[
  {
    "path": ".bumpversion.cfg",
    "content": "[bumpversion]\ncurrent_version = 0.9.0\ncommit = True\ntag = True\n\n[bumpversion:file:setup.cfg]\n\n[bumpversion:file:k_means_constrained/__init__.py]\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: \"[BUG]\"\nlabels: ''\nassignees: ''\n\n---\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**Minimum working example**\nCode and minimum data to reproduce the error. The example should be copy and pastable to reproduce the problem.\n\n**Versions:**\n- Python: \n- Operating system: [Windows/MacOS/Linux]\n- k-means-constrained: \n- numpy:\n- scipy:\n- ortools:\n- joblib:\n- cython (if installed):\n"
  },
  {
    "path": ".github/workflows/build_wheels.yml",
    "content": "name: Build & Test\n\non:\n    schedule:\n      - cron: '0 1 * * 4' # Runs every Thursday at 1 AM (UTC)\n    pull_request:\n    push:\n      branches:\n        - master\n    workflow_dispatch:\n\nconcurrency:\n    group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}\n    cancel-in-progress: true\n\njobs:\n  build_wheels:\n    name: ${{ matrix.os }}-${{ matrix.python }}\n    runs-on: ${{ matrix.os }}\n    strategy:\n      matrix:\n        # macos-15-intel is an intel runner, macos-latest is apple silicon\n        # windows-11-arm is currently not supported by the dependencies\n        os: [ubuntu-latest, ubuntu-24.04-arm, windows-latest, macos-15-intel, macos-latest]\n        python: [cp310, cp311, cp312, cp313, cp314]\n      fail-fast: false\n\n    steps:\n      - uses: actions/checkout@v4\n      - name: Build and test wheels\n        uses: pypa/cibuildwheel@v3.3.1\n        env:\n            # Build\n            # NOTE: build dependencies are defined in pyproject.toml (including numpy version)\n            CIBW_BUILD_FRONTEND: \"build\"\n            CIBW_ARCHS: native # Build only for the native architecture of the build machine\n            CIBW_BUILD: \"${{ matrix.python }}*\" # Build only for the specified Python version\n            CIBW_SKIP: \"*musllinux* cp3*t-*\" # Don't build musllinux (ortools) or free-threaded wheels\n\n            # Test\n            CIBW_BEFORE_TEST: \"python -m pip install --upgrade pip && python -m pip install -r requirements-dev.txt && python -m pip list\"\n            CIBW_TEST_COMMAND: \"pytest {project}/tests\"\n      - uses: actions/upload-artifact@v4\n        with:\n          path: ./wheelhouse/*.whl\n          name: ${{ matrix.os }}-${{ matrix.python }}\n  merge:\n    runs-on: ubuntu-latest\n    needs: build_wheels\n    steps:\n      - uses: actions/upload-artifact/merge@v4\n        with:\n            name: wheels\n            delete-merged: true\n"
  },
  {
    "path": ".gitignore",
    "content": "# Created by .ignore support plugin (hsz.mobi)\n### Python template\n# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\nwheels/\n*.egg-info/\n.installed.cfg\n*.egg\nMANIFEST\n\n# PyInstaller\n#  Usually these files are written by a python script from a template\n#  before PyInstaller builds the exe, so as to inject date/other infos into it.\n*.manifest\n*.spec\n\n# Installer logs\npip-log.txt\npip-delete-this-directory.txt\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.coverage\n.coverage.*\n.cache\nnosetests.xml\ncoverage.xml\n*.cover\n.hypothesis/\n.pytest_cache/\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\nlocal_settings.py\ndb.sqlite3\n\n# Flask stuff:\ninstance/\n.webassets-cache\n\n# Scrapy stuff:\n.scrapy\n\n# Sphinx documentation\nX_docs/_build/\n\n# PyBuilder\ntarget/\n\n# Jupyter Notebook\n.ipynb_checkpoints\n\n# pyenv\n.python-version\n\n# celery beat schedule file\ncelerybeat-schedule\n\n# SageMath parsed files\n*.sage.py\n\n# Environments\n.env\n.venv\nenv/\nvenv/\nENV/\nenv.bak/\nvenv.bak/\n\n# Spyder project settings\n.spyderproject\n.spyproject\n\n# Rope project settings\n.ropeproject\n\n# mkdocs documentation\n/site\n\n# mypy\n.mypy_cache/\n### JetBrains template\n# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm\n# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839\n\n# User-specific stuff\n.idea/**/workspace.xml\n.idea/**/tasks.xml\n.idea/**/dictionaries\n.idea/**/shelf\n\n# Sensitive or high-churn files\n.idea/**/dataSources/\n.idea/**/dataSources.ids\n.idea/**/dataSources.local.xml\n.idea/**/sqlDataSources.xml\n.idea/**/dynamic.xml\n.idea/**/uiDesigner.xml\n\n# Gradle\n.idea/**/gradle.xml\n.idea/**/libraries\n\n# CMake\ncmake-build-debug/\ncmake-build-release/\n\n# Mongo Explorer plugin\n.idea/**/mongoSettings.xml\n\n# File-based project format\n*.iws\n\n# IntelliJ\nout/\n\n# mpeltonen/sbt-idea plugin\n.idea_modules/\n\n# JIRA plugin\natlassian-ide-plugin.xml\n\n# Cursive Clojure plugin\n.idea/replstate.xml\n\n# Crashlytics plugin (for Android Studio and IntelliJ)\ncom_crashlytics_export_strings.xml\ncrashlytics.properties\ncrashlytics-build.properties\nfabric.properties\n\n# Editor-based Rest Client\n.idea/httpRequests\n### Example user template template\n### Example user template\n\n# IntelliJ project files\n.idea\n*.iml\nout\ngen\n/k_means_constrained/mincostflow_vectorized_.c\n/k_means_constrained/sklearn_import/cluster/_k_means.c\n/docs_source/_build/\n\nk-means-env/*\n/k_means_constrained/sklearn_import/metrics/pairwise_fast.c\n/k_means_constrained/sklearn_import/utils/sparsefuncs_fast.c\n\n.DS_Store\n.DS_Store/*\n\n*.code-workspace\nartifact/*"
  },
  {
    "path": "CITATION.cff",
    "content": "cff-version: 1.2.0\nmessage: \"If you use this software, please cite it as below.\"\nauthors:\n- family-names: \"Levy-Kramer\"\n  given-names: \"Josh\"\n  orcid: \"https://orcid.org/0000-0002-4350-6197\"\ntitle: \"k-means-constrained\"\ndate-released: 2018-04-23\nurl: \"https://github.com/joshlk/k-means-constrained\"\n"
  },
  {
    "path": "CLAUDE.md",
    "content": "# CLAUDE.md\n\nThis file provides guidance for AI assistants working with the k-means-constrained codebase.\n\n## Project Overview\n\n**k-means-constrained** is a Python library implementing K-means clustering with minimum and/or maximum cluster size constraints. It extends scikit-learn's KMeans API by formulating the constrained assignment step (E-step) as a Minimum Cost Flow (MCF) network optimization problem, solved using Google OR-Tools' `SimpleMinCostFlow`.\n\n- **Author:** Josh Levy-Kramer\n- **License:** BSD 3-Clause\n- **Version:** 0.9.0\n- **Python support:** 3.10, 3.11, 3.12, 3.13, 3.14\n\n## Repository Structure\n\n```\nk_means_constrained/                # Main package\n├── __init__.py                     # Exports KMeansConstrained, defines __version__\n├── k_means_constrained_.py         # Core algorithm implementation\n└── sklearn_import/                 # Vendored scikit-learn code (modified)\n    ├── base.py                     # BaseEstimator, ClusterMixin, TransformerMixin\n    ├── exceptions.py\n    ├── cluster/\n    │   ├── _k_means.pyx            # Cython: M-step center computation\n    │   └── k_means_.py             # KMeans base class, k-means++ init\n    ├── metrics/\n    │   ├── pairwise.py             # Distance computations\n    │   └── pairwise_fast.pyx       # Cython: optimized pairwise distances\n    ├── utils/\n    │   ├── extmath.py              # row_norms, squared_norm\n    │   ├── validation.py           # Input validation (check_array, etc.)\n    │   └── sparsefuncs_fast.pyx    # Cython: sparse matrix operations\n    └── preprocessing/\ntests/\n├── test_k_means_constrained_.py    # Core algorithm tests\n└── test_kmeans_constrained_from_sklearn.py  # Sklearn-adapted tests\netc/                                # Benchmarks and notebooks\ndocs_source/                        # Sphinx documentation source\ndocs/                               # Built HTML documentation\n.github/workflows/build_wheels.yml  # CI/CD pipeline\n```\n\n## Build & Development Commands\n\n### Prerequisites\n\nRequires Cython and numpy at build time. Install all dev dependencies:\n\n```sh\npip install -r requirements.txt\npip install -r requirements-dev.txt\n```\n\n### Key Commands\n\n| Command | Purpose |\n|---|---|\n| `make compile` | Build Cython extensions in-place (required before running tests locally) |\n| `pytest` | Run all tests |\n| `pytest tests/test_k_means_constrained_.py` | Run core tests only |\n| `make build` | Build the package |\n| `make dist` | Build wheel and sdist |\n| `make clean` | Remove build artifacts and caches |\n| `make docs` | Build Sphinx HTML documentation |\n\n### Typical Development Workflow\n\n1. `make compile` — build Cython extensions in-place\n2. Edit Python or Cython source files\n3. `make compile` again if `.pyx` files were changed\n4. `pytest` — run tests\n\n## Architecture & Key Concepts\n\n### Algorithm Flow\n\n1. **Initialization:** k-means++ or random center selection (in `sklearn_import/cluster/k_means_.py:_k_init`)\n2. **E-step (constrained):** `_labels_constrained()` builds an MCF graph from distance matrix and solves it via `ortools.SimpleMinCostFlow` to assign points to clusters respecting size_min/size_max\n3. **M-step (standard):** `_centers_dense()` / `_centers_sparse()` in `_k_means.pyx` recomputes cluster centers\n4. **Iterate** until convergence or max iterations\n\n### Key Functions in `k_means_constrained_.py`\n\n- `KMeansConstrained` — main API class, sklearn-compatible estimator\n- `k_means_constrained()` — top-level function handling multiple random inits\n- `kmeans_constrained_single()` — single run of the constrained E-M loop\n- `_labels_constrained()` — constrained E-step using min-cost flow\n- `minimum_cost_flow_problem_graph()` — builds MCF graph (nodes, arcs, costs, capacities)\n- `solve_min_cost_flow_graph()` — solves the MCF problem via OR-Tools\n\n### Vendored sklearn Code\n\nThe `sklearn_import/` directory contains code copied and adapted from scikit-learn. This is not a dependency on sklearn at runtime — it's vendored to avoid version coupling. Changes to these files should be minimal and well-documented.\n\n## Cython Extensions\n\nThree Cython `.pyx` files compile to C extensions:\n\n| Extension | Source | Purpose |\n|---|---|---|\n| `cluster._k_means` | `_k_means.pyx` | Compute cluster centers (M-step) |\n| `metrics.pairwise_fast` | `pairwise_fast.pyx` | Optimized sparse distance computation |\n| `utils.sparsefuncs_fast` | `sparsefuncs_fast.pyx` | Sparse CSR row norms and stats |\n\nCompilation is controlled by the `CYTHONIZE` environment variable (defaults to `1`). Set `CYTHONIZE=0` to skip Cythonization and use pre-compiled `.c`/`.cpp` files.\n\nCython compiler directives: `language_level=3`, `embedsignature=True`. Extensions use `boundscheck(False)`, `wraparound(False)`, `cdivision(True)` for performance.\n\n## Testing\n\n- **Framework:** pytest\n- **Test files:** `tests/test_k_means_constrained_.py` (core algorithm), `tests/test_kmeans_constrained_from_sklearn.py` (sklearn compatibility)\n- **CI matrix:** Ubuntu (x64+ARM), Windows, macOS (Intel+Apple Silicon) x Python 3.10-3.14\n- **CI tool:** `cibuildwheel` v3.0.0 — builds and tests wheels across platforms\n- **CI triggers:** push to master, PRs, weekly schedule (Thursday 1 AM UTC), manual dispatch\n- **Note:** musllinux is skipped (ortools compatibility)\n\n## Dependencies\n\n### Runtime (`requirements.txt`)\n\n- `ortools >= 9.15.6755` — Google OR-Tools for min-cost flow\n- `scipy >= 1.14.1` — sparse matrices, distance functions\n- `numpy >= 2.1.1` — array operations\n- `six` — Python 2/3 compatibility (legacy)\n- `joblib` — parallel execution of multiple inits\n\n### Build (`pyproject.toml`)\n\n- `setuptools`, `wheel`, `cython >= 3.0.11`, `numpy >= 2.0, < 3`\n\n### Dev (`requirements-dev.txt`)\n\n- `pytest`, `pandas`, `scikit-learn >= 1.5.2`, `sphinx`, `bump2version`, `twine`\n\n## Versioning & Release\n\n### Version locations\n\nThe version string appears in three files that must stay in sync:\n\n| File | Format |\n|---|---|\n| `setup.cfg` | `version = X.Y.Z` |\n| `k_means_constrained/__init__.py` | `__version__ = 'X.Y.Z'` |\n| `.bumpversion.cfg` | `current_version = X.Y.Z` |\n\n### Bumping the version\n\nUse `bump2version` (config in `.bumpversion.cfg`) which updates all three files and creates a git commit + tag automatically:\n\n```sh\nbump2version patch   # 0.9.0 → 0.9.1\nbump2version minor   # 0.9.0 → 0.10.0\nbump2version major   # 0.9.0 → 1.0.0\n```\n\nIf bumping manually (without `bump2version`), update all three files listed above.\n\n### Changelog\n\nThe changelog lives in `README.md` under the `# Change log` heading. When bumping the version, add a new entry at the top of the list following the existing format:\n\n```\n* vX.Y.Z (YYYY-MM-DD) Brief description of changes.\n```\n\n### Release workflow (from `README_dev.md`)\n\n1. Build and test locally (`make compile && pytest`)\n2. Push to GitHub (triggers CI wheel builds)\n3. Add changelog entry in `README.md`, bump version (`bump2version patch|minor|major`), push again\n4. Download CI artifacts (`make download-dists ID=$BUILD_ID`)\n5. Upload to test PyPI (`make test-pypi`), verify install\n6. Upload to real PyPI (`make pypi-upload`)\n\n## Code Conventions\n\n- **Naming:** PascalCase for classes, snake_case for functions, leading underscore for internal/private\n- **Docstrings:** NumPy style (Parameters, Returns, Notes, Examples sections)\n- **Imports:** `import numpy as np`, `import scipy.sparse as sp`\n- **Type hints:** Not heavily used; Cython files use `cdef`/`ctypedef` typed declarations\n- **Error handling:** `ValueError` for constraint violations, `NotImplementedError` for unsupported sparse operations\n- **Style checking:** flake8 (configured in `tox.ini`, excludes `.tox`, `*.egg`, `build`, `data`)\n\n## Important Caveats\n\n- Sparse matrix input is not fully supported — some code paths raise `NotImplementedError`\n- Performance: O(n^4 log n) when n ~ c (number of clusters), vs O(n^2) for standard k-means. Not suitable for very large datasets with few clusters.\n- The `tox.ini` is outdated (references Python 3.8/3.9). Use `pytest` directly or rely on CI.\n- Always run `make compile` after modifying `.pyx` files before testing.\n"
  },
  {
    "path": "LICENSE",
    "content": "BSD 3-Clause License\n\nCopyright (c) 2022, Josh Levy-Kramer & Outra Limited\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\n* Neither the name of the copyright holder nor the names of its\n  contributors may be used to endorse or promote products derived from\n  this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "MANIFEST.in",
    "content": "include README*.md\ninclude requirements*.txt\ninclude LICENSE\ninclude pyproject.toml\nglobal-include *.pyx\nglobal-include *.pyd"
  },
  {
    "path": "Makefile",
    "content": ".PHONY: build dist redist install dist-no-cython install-from-source clean venv-create venv-activate check-dist test-pypi pypi-upload\n\nbuild:\n\tpython setup.py build\n\ndist:\n\tpython setup.py build bdist_wheel sdist\n\ndist-no-cython:\n\tCYTHONIZE=0 python setup.py build bdist_wheel\n\ncompile:\n\tpython setup.py build build_ext --inplace\n\nredist: clean dist\n\ninstall:\n\tpip install .\n\ninstall-from-source: dist\n\tpip install dist/k-means-constrained-0.5.0.tar.gz\n\nclean:\n\t$(RM) -r build dist src/*.egg-info artifact\n\t$(RM) -r .pytest_cache\n\tfind . -name __pycache__ -exec rm -r {} +\n\t#git clean -fdX\n\nvenv-create:\n\tconda create -n k-means-constrained python=3.10\n\tconda activate k-means-constrained\n\tpip install -r requirements.txt\n\tpip install -r requirements-dev.txt\n\nvenv-activate:\n\t# Doesn't work. Need to execute manually\n\tconda activate k-means-constrained\n\nvenv-delete:\n\tconda env delete k-means-constrained\n\ndocs:\n\tsphinx-build -b html docs_source docs\n\nsource-dists:\n\trm -r dist\n\tpython setup.py sdist --formats=gztar\n\ndownload-dists:\n\t# e.g. `make download-dists ID=8`\n\t# ID is run id (get from url. Not Job ID)\n\t# Need gh installed. `brew install gh`\n\trm -r wheels || true\n\tgh run download $(ID)\n\ncheck-dist:\n\ttwine check wheels/*\n\ntest-pypi:\n\t# Get API key from password manager\n\ttwine upload --repository-url https://test.pypi.org/legacy/ wheels/*\n\npypi-upload:\n\t# Get API key from password manager\n\ttwine upload wheels/*"
  },
  {
    "path": "README.md",
    "content": "[![PyPI](https://img.shields.io/pypi/v/k-means-constrained)](https://pypi.org/project/k-means-constrained/)\n![Python](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-blue)\n[![Build](https://github.com/joshlk/k-means-constrained/actions/workflows/build_wheels.yml/badge.svg)](https://github.com/joshlk/k-means-constrained/actions/workflows/build_wheels.yml)\n[**Documentation**](https://joshlk.github.io/k-means-constrained/)\n\n# k-means-constrained\nK-means clustering implementation whereby a minimum and/or maximum size for each\ncluster can be specified.\n\nThis K-means implementation modifies the cluster assignment step (E in EM)\nby formulating it as a Minimum Cost Flow (MCF) linear network\noptimisation problem. This is then solved using a cost-scaling\npush-relabel algorithm and uses [Google's Operations Research tools's\n`SimpleMinCostFlow`](https://developers.google.com/optimization/flow/mincostflow)\nwhich is a fast C++ implementation.\n\nThis package is inspired by [Bradley et al.](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/tr-2000-65.pdf).\nThe original Minimum Cost Flow (MCF) network proposed by Bradley et al.\nhas been modified so maximum cluster sizes can also be specified along\nwith minimum cluster size. \n\nThe code is based on [scikit-lean's `KMeans`](https://scikit-learn.org/0.19/modules/generated/sklearn.cluster.KMeans.html)\nand implements the same [API with modifications](https://joshlk.github.io/k-means-constrained/).\n\nRef:\n1. [Bradley, P. S., K. P. Bennett, and Ayhan Demiriz. \"Constrained k-means clustering.\"\n    Microsoft Research, Redmond (2000): 1-8.](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/tr-2000-65.pdf)\n2. [Google's SimpleMinCostFlow C++ implementation](https://github.com/google/or-tools/blob/master/ortools/graph/min_cost_flow.h)\n\n# Installation\nYou can install the k-means-constrained from PyPI:\n\n```\npip install k-means-constrained\n```\n\nIt is supported on Python 3.10, 3.11, 3.12, 3.13 and 3.14. Previous versions of k-means-constrained support older versions of Python and Numpy.\n\n# Example\n\nMore details can be found in the [API documentation](https://joshlk.github.io/k-means-constrained/).\n\n```python\n>>> from k_means_constrained import KMeansConstrained\n>>> import numpy as np\n>>> X = np.array([[1, 2], [1, 4], [1, 0],\n...                [4, 2], [4, 4], [4, 0]])\n>>> clf = KMeansConstrained(\n...     n_clusters=2,\n...     size_min=2,\n...     size_max=5,\n...     random_state=0\n... )\n>>> clf.fit_predict(X)\narray([0, 0, 0, 1, 1, 1], dtype=int32)\n>>> clf.cluster_centers_\narray([[ 1.,  2.],\n       [ 4.,  2.]])\n>>> clf.labels_\narray([0, 0, 0, 1, 1, 1], dtype=int32)\n```\n\n<details>\n  <summary>Code only</summary>\n    \n```\nfrom k_means_constrained import KMeansConstrained\nimport numpy as np\nX = np.array([[1, 2], [1, 4], [1, 0],\n                [4, 2], [4, 4], [4, 0]])\nclf = KMeansConstrained(\n     n_clusters=2,\n     size_min=2,\n     size_max=5,\n     random_state=0\n )\nclf.fit_predict(X)\nclf.cluster_centers_\nclf.labels_\n```\n    \n</details>\n\n# Time complexity and runtime\n\nk-means-constrained is a more complex algorithm than vanilla k-means and therefore will take longer to execute and has worse scaling characteristics.\n\nGiven a number of data points $n$ and clusters $c$, the time complexity of:\n* k-means: $\\mathcal{O}(nc)$\n* k-means-constrained<sup>1</sup>: $\\mathcal{O}((n^3c+n^2c^2+nc^3)\\log(n+c)))$\n\nThis assumes a constant number of algorithm iterations and data-point features/dimensions.\n\nIf you consider the case where $n$ is the same order as $c$ ($n \\backsim c$) then:\n* k-means: $\\mathcal{O}(n^2)$\n* k-means-constrained<sup>1</sup>: $\\mathcal{O}(n^4\\log(n)))$\n\nBelow is a runtime comparison between k-means and k-means-constrained whereby the number of iterations, initializations, multi-process pool size and dimension size are fixed. The number of clusters is also always one-tenth the number of data points $n=10c$. It is shown above that the runtime is independent of the minimum or maximum cluster size, and so none is included below.\n\n<p align=\"center\">\n<img src=\"https://raw.githubusercontent.com/joshlk/k-means-constrained/master/etc/execution_time.png\" alt=\"Data-points vs execution time for k-means vs k-means-constrained. Data-points=10*clusters. No min/max constraints\" width=\"50%\" height=\"50%\">\n</p>\n\n<details>\n  <summary>System details</summary>\n    \n* OS: Linux-5.15.0-75-generic-x86_64-with-glibc2.35\n* CPU: AMD EPYC 7763 64-Core Processor\n* CPU cores: 120\n* k-means-constrained version: 0.7.3\n* numpy version: 1.24.2\n* scipy version: 1.11.1\n* ortools version: 9.6.2534\n* joblib version: 1.3.1\n* sklearn version: 1.3.0\n</details>\n---\n\n<sup>1</sup>: [Ortools states](https://developers.google.com/optimization/reference/graph/min_cost_flow) the time complexity of their cost-scaling push-relabel algorithm for the min-cost flow problem as $\\mathcal{O}(n^2m\\log(nC))$ where $n$ is the number of nodes, $m$ is the number of edges and $C$ is the maximum absolute edge cost.\n\n# Change log\n\n* v0.9.0 (2026-01-27) Added Python 3.14 support. Bumped ortools to >= 9.15.6755.\n* v0.8.0 (2025-11-26) Fixed IndexError due to imprecision in _k_init centroid selection. Ported fix from scikit-learn: [scikit-learn#11756](https://github.com/scikit-learn/scikit-learn/pull/11756)\n* v0.7.6 (2025-06-30) Add Python v3.13 and Linux ARM support.\n* v0.7.5 fix comment in README on Python version that is supported\n* v0.7.4 compatible with Numpy +v2.1.1. Added Python 3.12 support and dropped Python 3.8 and 3.9 support (due to Numpy). Linux ARM support has been dropped as we use GitHub runners to build the package and ARM machines was being emulated using QEMU. This however was producing numerical errors. GitHub should natively support Ubuntu ARM images soon and then we can start to re-build them.\n* v0.7.3 compatible with Numpy v1.23.0 to 1.26.4\n\n# Citations\n\nIf you use this software in your research, please use the following citation:\n\n```\n@software{Levy-Kramer_k-means-constrained_2018,\n  author = {Levy-Kramer, Josh},\n  month = apr,\n  title = {{k-means-constrained}},\n  url = {https://github.com/joshlk/k-means-constrained},\n  year = {2018}\n}\n```\n"
  },
  {
    "path": "README_dev.md",
    "content": "# Build and test\n\nNotes:\n* Numpy build version is in `pyproject.toml` while the runtime version is in `requirements.txt`\n* Check which Python versions a new version of Numpy is compatible with. Also check ortools as this is slower to update.\n* Change the Python versions in the GitHub action. Also change the badge in the README and the comment in the installation section.\n* You might need to increase the ciwheelbuild version in the GitHub action to be able to use new Python versions\n* Check ciwheelbuild example if you need to change runner image versions (e.g. MacOS, Windows or Ubuntu).\n    Change as little as possible so not to run into other errors:\n    https://github.com/pypa/cibuildwheel/blob/main/examples/github-with-qemu.yml\n* Add changes to the change log\n\nSteps:\n\n1. Build and test locally:\n\nTo build Cython extensions in source:\n```shell script\nmake compile\n```\n\nTo test:\n```shell script\npytest\n```\n\n2. Push changes to GitHub to build it for all platforms (if you get errors check notes above)\n\n3. Add changes to change log and bump version  (major, minor or patch). Push changes (so dist have new version):\n\n```shell script\nbump2version patch\ngit push # Must push as otherwise wheels have the wrong version\n```\n\n4. Download distributions (artifacts)\n\n```shell script\nmake download-dists ID=$BUILD_ID\n```\n\n5. Upload to test PyPi (you can get PyPI API token in password manager)\n\n```shell script\nmake check-dist\nmake test-pypi\n```\n\n6. Activate virtual env (might need to `make venv-create`)\n\n```shell script\nsource k-means-env/bin/activate\n```\n\n7. Test install (in virtual env. *****Remember to cd out of k-means-constrained folder*****):\n\n```shell script\npip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple k-means-constrained\n```\n\n8. Then push to real PyPI:\n\n```shell script\nmake pypi-upload\n```\n"
  },
  {
    "path": "docs/.buildinfo",
    "content": "# Sphinx build info version 1\n# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.\nconfig: 382d35e4d15790d94b7a36ad2e0a5f4f\ntags: 645f666f9bcd5a90fca523b33c5a78b7\n"
  },
  {
    "path": "docs/.nojekyll",
    "content": ""
  },
  {
    "path": "docs/_modules/index.html",
    "content": "\n\n<!DOCTYPE html>\n<html class=\"writer-html5\" lang=\"en\" >\n<head>\n  <meta charset=\"utf-8\" />\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n  \n  <title>Overview: module code &mdash; k-means-constrained 0.5.1 documentation</title>\n  \n\n  \n  <link rel=\"stylesheet\" href=\"../_static/css/theme.css\" type=\"text/css\" />\n  <link rel=\"stylesheet\" href=\"../_static/pygments.css\" type=\"text/css\" />\n  <link rel=\"stylesheet\" href=\"../_static/pygments.css\" type=\"text/css\" />\n  <link rel=\"stylesheet\" href=\"../_static/css/theme.css\" type=\"text/css\" />\n\n  \n  \n\n  \n  \n\n  \n\n  \n  <!--[if lt IE 9]>\n    <script src=\"../_static/js/html5shiv.min.js\"></script>\n  <![endif]-->\n  \n    \n      <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../\" src=\"../_static/documentation_options.js\"></script>\n        <script data-url_root=\"../\" id=\"documentation_options\" src=\"../_static/documentation_options.js\"></script>\n        <script src=\"../_static/jquery.js\"></script>\n        <script src=\"../_static/underscore.js\"></script>\n        <script src=\"../_static/doctools.js\"></script>\n    \n    <script type=\"text/javascript\" src=\"../_static/js/theme.js\"></script>\n\n    \n    <link rel=\"index\" title=\"Index\" href=\"../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../search.html\" /> \n</head>\n\n<body class=\"wy-body-for-nav\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\" >\n          \n\n          \n            <a href=\"../index.html\" class=\"icon icon-home\"> k-means-constrained\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"../search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        \n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n              \n            \n            \n              <!-- Local TOC -->\n              <div class=\"local-toc\"></div>\n            \n          \n        </div>\n        \n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"../index.html\">k-means-constrained</a>\n        \n      </nav>\n\n\n      <div class=\"wy-nav-content\">\n        \n        <div class=\"rst-content\">\n        \n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"../index.html\" class=\"icon icon-home\"></a> &raquo;</li>\n        \n      <li>Overview: module code</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n      </li>\n    \n  </ul>\n\n  \n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <h1>All modules for which code is available</h1>\n<ul><li><a href=\"k_means_constrained/k_means_constrained_.html\">k_means_constrained.k_means_constrained_</a></li>\n<li><a href=\"k_means_constrained/sklearn_import/base.html\">k_means_constrained.sklearn_import.base</a></li>\n<li><a href=\"k_means_constrained/sklearn_import/cluster/k_means_.html\">k_means_constrained.sklearn_import.cluster.k_means_</a></li>\n</ul>\n\n           </div>\n           \n          </div>\n          <footer>\n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &#169; Copyright 2020, Josh Levy-Kramer. Documentation derived from Scikit-Learn.\n\n    </p>\n  </div>\n    \n    \n    \n    Built with <a href=\"https://www.sphinx-doc.org/\">Sphinx</a> using a\n    \n    <a href=\"https://github.com/readthedocs/sphinx_rtd_theme\">theme</a>\n    \n    provided by <a href=\"https://readthedocs.org\">Read the Docs</a>. \n\n</footer>\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.Navigation.enable(true);\n      });\n  </script>\n\n  \n  \n    \n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/_modules/k_means_constrained/k_means_constrained_.html",
    "content": "\n\n<!DOCTYPE html>\n<html class=\"writer-html5\" lang=\"en\" >\n<head>\n  <meta charset=\"utf-8\" />\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n  \n  <title>k_means_constrained.k_means_constrained_ &mdash; k-means-constrained 0.5.1 documentation</title>\n  \n\n  \n  <link rel=\"stylesheet\" href=\"../../_static/css/theme.css\" type=\"text/css\" />\n  <link rel=\"stylesheet\" href=\"../../_static/pygments.css\" type=\"text/css\" />\n  <link rel=\"stylesheet\" href=\"../../_static/pygments.css\" type=\"text/css\" />\n  <link rel=\"stylesheet\" href=\"../../_static/css/theme.css\" type=\"text/css\" />\n\n  \n  \n\n  \n  \n\n  \n\n  \n  <!--[if lt IE 9]>\n    <script src=\"../../_static/js/html5shiv.min.js\"></script>\n  <![endif]-->\n  \n    \n      <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../\" src=\"../../_static/documentation_options.js\"></script>\n        <script data-url_root=\"../../\" id=\"documentation_options\" src=\"../../_static/documentation_options.js\"></script>\n        <script src=\"../../_static/jquery.js\"></script>\n        <script src=\"../../_static/underscore.js\"></script>\n        <script src=\"../../_static/doctools.js\"></script>\n    \n    <script type=\"text/javascript\" src=\"../../_static/js/theme.js\"></script>\n\n    \n    <link rel=\"index\" title=\"Index\" href=\"../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../search.html\" /> \n</head>\n\n<body class=\"wy-body-for-nav\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\" >\n          \n\n          \n            <a href=\"../../index.html\" class=\"icon icon-home\"> k-means-constrained\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"../../search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        \n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n              \n            \n            \n              <!-- Local TOC -->\n              <div class=\"local-toc\"></div>\n            \n          \n        </div>\n        \n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"../../index.html\">k-means-constrained</a>\n        \n      </nav>\n\n\n      <div class=\"wy-nav-content\">\n        \n        <div class=\"rst-content\">\n        \n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"../../index.html\" class=\"icon icon-home\"></a> &raquo;</li>\n        \n          <li><a href=\"../index.html\">Module code</a> &raquo;</li>\n        \n      <li>k_means_constrained.k_means_constrained_</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n      </li>\n    \n  </ul>\n\n  \n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <h1>Source code for k_means_constrained.k_means_constrained_</h1><div class=\"highlight\"><pre>\n<span></span><span class=\"sd\">&quot;&quot;&quot;k-means-constrained&quot;&quot;&quot;</span>\n\n<span class=\"c1\"># Authors: Josh Levy-Kramer &lt;josh@levykramer.co.uk&gt;</span>\n<span class=\"c1\">#          Gael Varoquaux &lt;gael.varoquaux@normalesup.org&gt;</span>\n<span class=\"c1\">#          Thomas Rueckstiess &lt;ruecksti@in.tum.de&gt;</span>\n<span class=\"c1\">#          James Bergstra &lt;james.bergstra@umontreal.ca&gt;</span>\n<span class=\"c1\">#          Jan Schlueter &lt;scikit-learn@jan-schlueter.de&gt;</span>\n<span class=\"c1\">#          Nelle Varoquaux</span>\n<span class=\"c1\">#          Peter Prettenhofer &lt;peter.prettenhofer@gmail.com&gt;</span>\n<span class=\"c1\">#          Olivier Grisel &lt;olivier.grisel@ensta.org&gt;</span>\n<span class=\"c1\">#          Mathieu Blondel &lt;mathieu@mblondel.org&gt;</span>\n<span class=\"c1\">#          Robert Layton &lt;robertlayton@gmail.com&gt;</span>\n<span class=\"c1\"># License: BSD 3 clause</span>\n\n<span class=\"kn\">import</span> <span class=\"nn\">warnings</span>\n<span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n<span class=\"kn\">import</span> <span class=\"nn\">scipy.sparse</span> <span class=\"k\">as</span> <span class=\"nn\">sp</span>\n<span class=\"kn\">from</span> <span class=\"nn\">.sklearn_import.metrics.pairwise</span> <span class=\"kn\">import</span> <span class=\"n\">euclidean_distances</span>\n<span class=\"kn\">from</span> <span class=\"nn\">.sklearn_import.utils.extmath</span> <span class=\"kn\">import</span> <span class=\"n\">row_norms</span><span class=\"p\">,</span> <span class=\"n\">squared_norm</span><span class=\"p\">,</span> <span class=\"n\">cartesian</span>\n<span class=\"kn\">from</span> <span class=\"nn\">.sklearn_import.utils.validation</span> <span class=\"kn\">import</span> <span class=\"n\">check_array</span><span class=\"p\">,</span> <span class=\"n\">check_random_state</span><span class=\"p\">,</span> <span class=\"n\">as_float_array</span><span class=\"p\">,</span> <span class=\"n\">check_is_fitted</span>\n<span class=\"kn\">from</span> <span class=\"nn\">joblib</span> <span class=\"kn\">import</span> <span class=\"n\">Parallel</span>\n<span class=\"kn\">from</span> <span class=\"nn\">joblib</span> <span class=\"kn\">import</span> <span class=\"n\">delayed</span>\n\n<span class=\"c1\"># Internal scikit learn methods imported into this project</span>\n<span class=\"kn\">from</span> <span class=\"nn\">k_means_constrained.sklearn_import.cluster._k_means</span> <span class=\"kn\">import</span> <span class=\"n\">_centers_dense</span><span class=\"p\">,</span> <span class=\"n\">_centers_sparse</span>\n<span class=\"kn\">from</span> <span class=\"nn\">k_means_constrained.sklearn_import.cluster.k_means_</span> <span class=\"kn\">import</span> <span class=\"n\">_validate_center_shape</span><span class=\"p\">,</span> <span class=\"n\">_tolerance</span><span class=\"p\">,</span> <span class=\"n\">KMeans</span><span class=\"p\">,</span> \\\n    <span class=\"n\">_init_centroids</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">k_means_constrained.mincostflow_vectorized</span> <span class=\"kn\">import</span> <span class=\"n\">SimpleMinCostFlowVectorized</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">k_means_constrained</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">n_clusters</span><span class=\"p\">,</span> <span class=\"n\">size_min</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">size_max</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">init</span><span class=\"o\">=</span><span class=\"s1\">&#39;k-means++&#39;</span><span class=\"p\">,</span>\n                        <span class=\"n\">n_init</span><span class=\"o\">=</span><span class=\"mi\">10</span><span class=\"p\">,</span> <span class=\"n\">max_iter</span><span class=\"o\">=</span><span class=\"mi\">300</span><span class=\"p\">,</span> <span class=\"n\">verbose</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span>\n                        <span class=\"n\">tol</span><span class=\"o\">=</span><span class=\"mf\">1e-4</span><span class=\"p\">,</span> <span class=\"n\">random_state</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">copy_x</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span> <span class=\"n\">n_jobs</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span>\n                        <span class=\"n\">return_n_iter</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;K-Means clustering with minimum and maximum cluster size constraints.</span>\n\n<span class=\"sd\">    Read more in the :ref:`User Guide &lt;k_means&gt;`.</span>\n\n<span class=\"sd\">    Parameters</span>\n<span class=\"sd\">    ----------</span>\n<span class=\"sd\">    X : array-like, shape (n_samples, n_features)</span>\n<span class=\"sd\">        The observations to cluster.</span>\n\n<span class=\"sd\">    size_min : int, optional, default: None</span>\n<span class=\"sd\">        Constrain the label assignment so that each cluster has a minimum</span>\n<span class=\"sd\">        size of size_min. If None, no constrains will be applied</span>\n\n<span class=\"sd\">    size_max : int, optional, default: None</span>\n<span class=\"sd\">        Constrain the label assignment so that each cluster has a maximum</span>\n<span class=\"sd\">        size of size_max. If None, no constrains will be applied</span>\n\n<span class=\"sd\">    n_clusters : int</span>\n<span class=\"sd\">        The number of clusters to form as well as the number of</span>\n<span class=\"sd\">        centroids to generate.</span>\n\n<span class=\"sd\">    init : {&#39;k-means++&#39;, &#39;random&#39;, or ndarray, or a callable}, optional</span>\n<span class=\"sd\">        Method for initialization, default to &#39;k-means++&#39;:</span>\n\n<span class=\"sd\">        &#39;k-means++&#39; : selects initial cluster centers for k-mean</span>\n<span class=\"sd\">        clustering in a smart way to speed up convergence. See section</span>\n<span class=\"sd\">        Notes in k_init for more details.</span>\n\n<span class=\"sd\">        &#39;random&#39;: generate k centroids from a Gaussian with mean and</span>\n<span class=\"sd\">        variance estimated from the data.</span>\n\n<span class=\"sd\">        If an ndarray is passed, it should be of shape (n_clusters, n_features)</span>\n<span class=\"sd\">        and gives the initial centers.</span>\n\n<span class=\"sd\">        If a callable is passed, it should take arguments X, k and</span>\n<span class=\"sd\">        and a random state and return an initialization.</span>\n\n<span class=\"sd\">    n_init : int, optional, default: 10</span>\n<span class=\"sd\">        Number of time the k-means algorithm will be run with different</span>\n<span class=\"sd\">        centroid seeds. The final results will be the best output of</span>\n<span class=\"sd\">        n_init consecutive runs in terms of inertia.</span>\n\n<span class=\"sd\">    max_iter : int, optional, default 300</span>\n<span class=\"sd\">        Maximum number of iterations of the k-means algorithm to run.</span>\n\n<span class=\"sd\">    verbose : boolean, optional</span>\n<span class=\"sd\">        Verbosity mode.</span>\n\n<span class=\"sd\">    tol : float, optional</span>\n<span class=\"sd\">        Relative tolerance with regards to Frobenius norm of the difference</span>\n<span class=\"sd\">        in the cluster centers of two consecutive iterations to declare</span>\n<span class=\"sd\">        convergence.</span>\n\n<span class=\"sd\">    random_state : int, RandomState instance or None, optional, default: None</span>\n<span class=\"sd\">        If int, random_state is the seed used by the random number generator;</span>\n<span class=\"sd\">        If RandomState instance, random_state is the random number generator;</span>\n<span class=\"sd\">        If None, the random number generator is the RandomState instance used</span>\n<span class=\"sd\">        by `np.random`.</span>\n\n<span class=\"sd\">    copy_x : boolean, optional</span>\n<span class=\"sd\">        When pre-computing distances it is more numerically accurate to center</span>\n<span class=\"sd\">        the data first.  If copy_x is True, then the original data is not</span>\n<span class=\"sd\">        modified.  If False, the original data is modified, and put back before</span>\n<span class=\"sd\">        the function returns, but small numerical differences may be introduced</span>\n<span class=\"sd\">        by subtracting and then adding the data mean.</span>\n\n<span class=\"sd\">    n_jobs : int</span>\n<span class=\"sd\">        The number of jobs to use for the computation. This works by computing</span>\n<span class=\"sd\">        each of the n_init runs in parallel.</span>\n\n<span class=\"sd\">        If -1 all CPUs are used. If 1 is given, no parallel computing code is</span>\n<span class=\"sd\">        used at all, which is useful for debugging. For n_jobs below -1,</span>\n<span class=\"sd\">        (n_cpus + 1 + n_jobs) are used. Thus for n_jobs = -2, all CPUs but one</span>\n<span class=\"sd\">        are used.</span>\n\n<span class=\"sd\">    return_n_iter : bool, optional</span>\n<span class=\"sd\">        Whether or not to return the number of iterations.</span>\n\n<span class=\"sd\">    Returns</span>\n<span class=\"sd\">    -------</span>\n<span class=\"sd\">    centroid : float ndarray with shape (k, n_features)</span>\n<span class=\"sd\">        Centroids found at the last iteration of k-means.</span>\n\n<span class=\"sd\">    label : integer ndarray with shape (n_samples,)</span>\n<span class=\"sd\">        label[i] is the code or index of the centroid the</span>\n<span class=\"sd\">        i&#39;th observation is closest to.</span>\n\n<span class=\"sd\">    inertia : float</span>\n<span class=\"sd\">        The final value of the inertia criterion (sum of squared distances to</span>\n<span class=\"sd\">        the closest centroid for all observations in the training set).</span>\n\n<span class=\"sd\">    best_n_iter : int</span>\n<span class=\"sd\">        Number of iterations corresponding to the best results.</span>\n<span class=\"sd\">        Returned only if `return_n_iter` is set to True.</span>\n\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"k\">if</span> <span class=\"n\">sp</span><span class=\"o\">.</span><span class=\"n\">issparse</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">):</span>\n        <span class=\"k\">raise</span> <span class=\"ne\">NotImplementedError</span><span class=\"p\">(</span><span class=\"s2\">&quot;Not implemented for sparse X&quot;</span><span class=\"p\">)</span>\n\n    <span class=\"k\">if</span> <span class=\"n\">n_init</span> <span class=\"o\">&lt;=</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n        <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s2\">&quot;Invalid number of initializations.&quot;</span>\n                         <span class=\"s2\">&quot; n_init=</span><span class=\"si\">%d</span><span class=\"s2\"> must be bigger than zero.&quot;</span> <span class=\"o\">%</span> <span class=\"n\">n_init</span><span class=\"p\">)</span>\n    <span class=\"n\">random_state</span> <span class=\"o\">=</span> <span class=\"n\">check_random_state</span><span class=\"p\">(</span><span class=\"n\">random_state</span><span class=\"p\">)</span>\n\n    <span class=\"k\">if</span> <span class=\"n\">max_iter</span> <span class=\"o\">&lt;=</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n        <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s1\">&#39;Number of iterations should be a positive number,&#39;</span>\n                         <span class=\"s1\">&#39; got </span><span class=\"si\">%d</span><span class=\"s1\"> instead&#39;</span> <span class=\"o\">%</span> <span class=\"n\">max_iter</span><span class=\"p\">)</span>\n\n    <span class=\"n\">X</span> <span class=\"o\">=</span> <span class=\"n\">as_float_array</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">copy</span><span class=\"o\">=</span><span class=\"n\">copy_x</span><span class=\"p\">)</span>\n    <span class=\"n\">tol</span> <span class=\"o\">=</span> <span class=\"n\">_tolerance</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">tol</span><span class=\"p\">)</span>\n\n    <span class=\"c1\"># Validate init array</span>\n    <span class=\"k\">if</span> <span class=\"nb\">hasattr</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"s1\">&#39;__array__&#39;</span><span class=\"p\">):</span>\n        <span class=\"n\">init</span> <span class=\"o\">=</span> <span class=\"n\">check_array</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">dtype</span><span class=\"o\">.</span><span class=\"n\">type</span><span class=\"p\">,</span> <span class=\"n\">copy</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n        <span class=\"n\">_validate_center_shape</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">n_clusters</span><span class=\"p\">,</span> <span class=\"n\">init</span><span class=\"p\">)</span>\n\n        <span class=\"k\">if</span> <span class=\"n\">n_init</span> <span class=\"o\">!=</span> <span class=\"mi\">1</span><span class=\"p\">:</span>\n            <span class=\"n\">warnings</span><span class=\"o\">.</span><span class=\"n\">warn</span><span class=\"p\">(</span>\n                <span class=\"s1\">&#39;Explicit initial center position passed: &#39;</span>\n                <span class=\"s1\">&#39;performing only one init in k-means instead of n_init=</span><span class=\"si\">%d</span><span class=\"s1\">&#39;</span>\n                <span class=\"o\">%</span> <span class=\"n\">n_init</span><span class=\"p\">,</span> <span class=\"ne\">RuntimeWarning</span><span class=\"p\">,</span> <span class=\"n\">stacklevel</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n            <span class=\"n\">n_init</span> <span class=\"o\">=</span> <span class=\"mi\">1</span>\n\n    <span class=\"c1\"># subtract of mean of x for more accurate distance computations</span>\n    <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"n\">sp</span><span class=\"o\">.</span><span class=\"n\">issparse</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">):</span>\n        <span class=\"n\">X_mean</span> <span class=\"o\">=</span> <span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">mean</span><span class=\"p\">(</span><span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">)</span>\n        <span class=\"c1\"># The copy was already done above</span>\n        <span class=\"n\">X</span> <span class=\"o\">-=</span> <span class=\"n\">X_mean</span>\n\n        <span class=\"k\">if</span> <span class=\"nb\">hasattr</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"s1\">&#39;__array__&#39;</span><span class=\"p\">):</span>\n            <span class=\"n\">init</span> <span class=\"o\">-=</span> <span class=\"n\">X_mean</span>\n\n    <span class=\"c1\"># precompute squared norms of data points</span>\n    <span class=\"n\">x_squared_norms</span> <span class=\"o\">=</span> <span class=\"n\">row_norms</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">squared</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n\n    <span class=\"n\">best_labels</span><span class=\"p\">,</span> <span class=\"n\">best_inertia</span><span class=\"p\">,</span> <span class=\"n\">best_centers</span> <span class=\"o\">=</span> <span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"kc\">None</span>\n\n    <span class=\"k\">if</span> <span class=\"n\">n_jobs</span> <span class=\"o\">==</span> <span class=\"mi\">1</span><span class=\"p\">:</span>\n        <span class=\"c1\"># For a single thread, less memory is needed if we just store one set</span>\n        <span class=\"c1\"># of the best results (as opposed to one set per run per thread).</span>\n        <span class=\"k\">for</span> <span class=\"n\">it</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">n_init</span><span class=\"p\">):</span>\n            <span class=\"c1\"># run a k-means once</span>\n            <span class=\"n\">labels</span><span class=\"p\">,</span> <span class=\"n\">inertia</span><span class=\"p\">,</span> <span class=\"n\">centers</span><span class=\"p\">,</span> <span class=\"n\">n_iter_</span> <span class=\"o\">=</span> <span class=\"n\">kmeans_constrained_single</span><span class=\"p\">(</span>\n                <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">n_clusters</span><span class=\"p\">,</span>\n                <span class=\"n\">size_min</span><span class=\"o\">=</span><span class=\"n\">size_min</span><span class=\"p\">,</span> <span class=\"n\">size_max</span><span class=\"o\">=</span><span class=\"n\">size_max</span><span class=\"p\">,</span>\n                <span class=\"n\">max_iter</span><span class=\"o\">=</span><span class=\"n\">max_iter</span><span class=\"p\">,</span> <span class=\"n\">init</span><span class=\"o\">=</span><span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"n\">verbose</span><span class=\"o\">=</span><span class=\"n\">verbose</span><span class=\"p\">,</span> <span class=\"n\">tol</span><span class=\"o\">=</span><span class=\"n\">tol</span><span class=\"p\">,</span>\n                <span class=\"n\">x_squared_norms</span><span class=\"o\">=</span><span class=\"n\">x_squared_norms</span><span class=\"p\">,</span> <span class=\"n\">random_state</span><span class=\"o\">=</span><span class=\"n\">random_state</span><span class=\"p\">)</span>\n            <span class=\"c1\"># determine if these results are the best so far</span>\n            <span class=\"k\">if</span> <span class=\"n\">best_inertia</span> <span class=\"ow\">is</span> <span class=\"kc\">None</span> <span class=\"ow\">or</span> <span class=\"n\">inertia</span> <span class=\"o\">&lt;</span> <span class=\"n\">best_inertia</span><span class=\"p\">:</span>\n                <span class=\"n\">best_labels</span> <span class=\"o\">=</span> <span class=\"n\">labels</span><span class=\"o\">.</span><span class=\"n\">copy</span><span class=\"p\">()</span>\n                <span class=\"n\">best_centers</span> <span class=\"o\">=</span> <span class=\"n\">centers</span><span class=\"o\">.</span><span class=\"n\">copy</span><span class=\"p\">()</span>\n                <span class=\"n\">best_inertia</span> <span class=\"o\">=</span> <span class=\"n\">inertia</span>\n                <span class=\"n\">best_n_iter</span> <span class=\"o\">=</span> <span class=\"n\">n_iter_</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"c1\"># parallelisation of k-means runs</span>\n        <span class=\"n\">seeds</span> <span class=\"o\">=</span> <span class=\"n\">random_state</span><span class=\"o\">.</span><span class=\"n\">randint</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">iinfo</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">int32</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">max</span><span class=\"p\">,</span> <span class=\"n\">size</span><span class=\"o\">=</span><span class=\"n\">n_init</span><span class=\"p\">)</span>\n        <span class=\"n\">results</span> <span class=\"o\">=</span> <span class=\"n\">Parallel</span><span class=\"p\">(</span><span class=\"n\">n_jobs</span><span class=\"o\">=</span><span class=\"n\">n_jobs</span><span class=\"p\">,</span> <span class=\"n\">verbose</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">)(</span>\n            <span class=\"n\">delayed</span><span class=\"p\">(</span><span class=\"n\">kmeans_constrained_single</span><span class=\"p\">)(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">n_clusters</span><span class=\"p\">,</span>\n                                               <span class=\"n\">size_min</span><span class=\"o\">=</span><span class=\"n\">size_min</span><span class=\"p\">,</span> <span class=\"n\">size_max</span><span class=\"o\">=</span><span class=\"n\">size_max</span><span class=\"p\">,</span>\n                                               <span class=\"n\">max_iter</span><span class=\"o\">=</span><span class=\"n\">max_iter</span><span class=\"p\">,</span> <span class=\"n\">init</span><span class=\"o\">=</span><span class=\"n\">init</span><span class=\"p\">,</span>\n                                               <span class=\"n\">verbose</span><span class=\"o\">=</span><span class=\"n\">verbose</span><span class=\"p\">,</span> <span class=\"n\">tol</span><span class=\"o\">=</span><span class=\"n\">tol</span><span class=\"p\">,</span>\n                                               <span class=\"n\">x_squared_norms</span><span class=\"o\">=</span><span class=\"n\">x_squared_norms</span><span class=\"p\">,</span>\n                                               <span class=\"c1\"># Change seed to ensure variety</span>\n                                               <span class=\"n\">random_state</span><span class=\"o\">=</span><span class=\"n\">seed</span><span class=\"p\">)</span>\n            <span class=\"k\">for</span> <span class=\"n\">seed</span> <span class=\"ow\">in</span> <span class=\"n\">seeds</span><span class=\"p\">)</span>\n        <span class=\"c1\"># Get results with the lowest inertia</span>\n        <span class=\"n\">labels</span><span class=\"p\">,</span> <span class=\"n\">inertia</span><span class=\"p\">,</span> <span class=\"n\">centers</span><span class=\"p\">,</span> <span class=\"n\">n_iters</span> <span class=\"o\">=</span> <span class=\"nb\">zip</span><span class=\"p\">(</span><span class=\"o\">*</span><span class=\"n\">results</span><span class=\"p\">)</span>\n        <span class=\"n\">best</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">argmin</span><span class=\"p\">(</span><span class=\"n\">inertia</span><span class=\"p\">)</span>\n        <span class=\"n\">best_labels</span> <span class=\"o\">=</span> <span class=\"n\">labels</span><span class=\"p\">[</span><span class=\"n\">best</span><span class=\"p\">]</span>\n        <span class=\"n\">best_inertia</span> <span class=\"o\">=</span> <span class=\"n\">inertia</span><span class=\"p\">[</span><span class=\"n\">best</span><span class=\"p\">]</span>\n        <span class=\"n\">best_centers</span> <span class=\"o\">=</span> <span class=\"n\">centers</span><span class=\"p\">[</span><span class=\"n\">best</span><span class=\"p\">]</span>\n        <span class=\"n\">best_n_iter</span> <span class=\"o\">=</span> <span class=\"n\">n_iters</span><span class=\"p\">[</span><span class=\"n\">best</span><span class=\"p\">]</span>\n\n    <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"n\">sp</span><span class=\"o\">.</span><span class=\"n\">issparse</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">):</span>\n        <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"n\">copy_x</span><span class=\"p\">:</span>\n            <span class=\"n\">X</span> <span class=\"o\">+=</span> <span class=\"n\">X_mean</span>\n        <span class=\"n\">best_centers</span> <span class=\"o\">+=</span> <span class=\"n\">X_mean</span>\n\n    <span class=\"k\">if</span> <span class=\"n\">return_n_iter</span><span class=\"p\">:</span>\n        <span class=\"k\">return</span> <span class=\"n\">best_centers</span><span class=\"p\">,</span> <span class=\"n\">best_labels</span><span class=\"p\">,</span> <span class=\"n\">best_inertia</span><span class=\"p\">,</span> <span class=\"n\">best_n_iter</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"k\">return</span> <span class=\"n\">best_centers</span><span class=\"p\">,</span> <span class=\"n\">best_labels</span><span class=\"p\">,</span> <span class=\"n\">best_inertia</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">kmeans_constrained_single</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">n_clusters</span><span class=\"p\">,</span> <span class=\"n\">size_min</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">size_max</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span>\n                              <span class=\"n\">max_iter</span><span class=\"o\">=</span><span class=\"mi\">300</span><span class=\"p\">,</span> <span class=\"n\">init</span><span class=\"o\">=</span><span class=\"s1\">&#39;k-means++&#39;</span><span class=\"p\">,</span>\n                              <span class=\"n\">verbose</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span> <span class=\"n\">x_squared_norms</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span>\n                              <span class=\"n\">random_state</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">tol</span><span class=\"o\">=</span><span class=\"mf\">1e-4</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;A single run of k-means constrained, assumes preparation completed prior.</span>\n\n<span class=\"sd\">    Parameters</span>\n<span class=\"sd\">    ----------</span>\n<span class=\"sd\">    X : array-like of floats, shape (n_samples, n_features)</span>\n<span class=\"sd\">        The observations to cluster.</span>\n\n<span class=\"sd\">    size_min : int, optional, default: None</span>\n<span class=\"sd\">        Constrain the label assignment so that each cluster has a minimum</span>\n<span class=\"sd\">        size of size_min. If None, no constrains will be applied</span>\n\n<span class=\"sd\">    size_max : int, optional, default: None</span>\n<span class=\"sd\">        Constrain the label assignment so that each cluster has a maximum</span>\n<span class=\"sd\">        size of size_max. If None, no constrains will be applied</span>\n\n<span class=\"sd\">    n_clusters : int</span>\n<span class=\"sd\">        The number of clusters to form as well as the number of</span>\n<span class=\"sd\">        centroids to generate.</span>\n\n<span class=\"sd\">    max_iter : int, optional, default 300</span>\n<span class=\"sd\">        Maximum number of iterations of the k-means algorithm to run.</span>\n\n<span class=\"sd\">    init : {&#39;k-means++&#39;, &#39;random&#39;, or ndarray, or a callable}, optional</span>\n<span class=\"sd\">        Method for initialization, default to &#39;k-means++&#39;:</span>\n\n<span class=\"sd\">        &#39;k-means++&#39; : selects initial cluster centers for k-mean</span>\n<span class=\"sd\">        clustering in a smart way to speed up convergence. See section</span>\n<span class=\"sd\">        Notes in k_init for more details.</span>\n\n<span class=\"sd\">        &#39;random&#39;: generate k centroids from a Gaussian with mean and</span>\n<span class=\"sd\">        variance estimated from the data.</span>\n\n<span class=\"sd\">        If an ndarray is passed, it should be of shape (k, p) and gives</span>\n<span class=\"sd\">        the initial centers.</span>\n\n<span class=\"sd\">        If a callable is passed, it should take arguments X, k and</span>\n<span class=\"sd\">        and a random state and return an initialization.</span>\n\n<span class=\"sd\">    tol : float, optional</span>\n<span class=\"sd\">        Relative tolerance with regards to Frobenius norm of the difference</span>\n<span class=\"sd\">        in the cluster centers of two consecutive iterations to declare</span>\n<span class=\"sd\">        convergence.</span>\n\n<span class=\"sd\">    verbose : boolean, optional</span>\n<span class=\"sd\">        Verbosity mode</span>\n\n<span class=\"sd\">    x_squared_norms : array</span>\n<span class=\"sd\">        Precomputed x_squared_norms.</span>\n\n<span class=\"sd\">    random_state : int, RandomState instance or None, optional, default: None</span>\n<span class=\"sd\">        If int, random_state is the seed used by the random number generator;</span>\n<span class=\"sd\">        If RandomState instance, random_state is the random number generator;</span>\n<span class=\"sd\">        If None, the random number generator is the RandomState instance used</span>\n<span class=\"sd\">        by `np.random`.</span>\n\n<span class=\"sd\">    Returns</span>\n<span class=\"sd\">    -------</span>\n<span class=\"sd\">    centroid : float ndarray with shape (k, n_features)</span>\n<span class=\"sd\">        Centroids found at the last iteration of k-means.</span>\n\n<span class=\"sd\">    label : integer ndarray with shape (n_samples,)</span>\n<span class=\"sd\">        label[i] is the code or index of the centroid the</span>\n<span class=\"sd\">        i&#39;th observation is closest to.</span>\n\n<span class=\"sd\">    inertia : float</span>\n<span class=\"sd\">        The final value of the inertia criterion (sum of squared distances to</span>\n<span class=\"sd\">        the closest centroid for all observations in the training set).</span>\n\n<span class=\"sd\">    n_iter : int</span>\n<span class=\"sd\">        Number of iterations run.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"k\">if</span> <span class=\"n\">sp</span><span class=\"o\">.</span><span class=\"n\">issparse</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">):</span>\n        <span class=\"k\">raise</span> <span class=\"ne\">NotImplementedError</span><span class=\"p\">(</span><span class=\"s2\">&quot;Not implemented for sparse X&quot;</span><span class=\"p\">)</span>\n\n    <span class=\"n\">random_state</span> <span class=\"o\">=</span> <span class=\"n\">check_random_state</span><span class=\"p\">(</span><span class=\"n\">random_state</span><span class=\"p\">)</span>\n    <span class=\"n\">n_samples</span> <span class=\"o\">=</span> <span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n\n    <span class=\"n\">best_labels</span><span class=\"p\">,</span> <span class=\"n\">best_inertia</span><span class=\"p\">,</span> <span class=\"n\">best_centers</span> <span class=\"o\">=</span> <span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"kc\">None</span>\n    <span class=\"c1\"># init</span>\n    <span class=\"n\">centers</span> <span class=\"o\">=</span> <span class=\"n\">_init_centroids</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">n_clusters</span><span class=\"p\">,</span> <span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"n\">random_state</span><span class=\"o\">=</span><span class=\"n\">random_state</span><span class=\"p\">,</span> <span class=\"n\">x_squared_norms</span><span class=\"o\">=</span><span class=\"n\">x_squared_norms</span><span class=\"p\">)</span>\n    <span class=\"k\">if</span> <span class=\"n\">verbose</span><span class=\"p\">:</span>\n        <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s2\">&quot;Initialization complete&quot;</span><span class=\"p\">)</span>\n\n    <span class=\"c1\"># Allocate memory to store the distances for each sample to its</span>\n    <span class=\"c1\"># closer center for reallocation in case of ties</span>\n    <span class=\"n\">distances</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">(</span><span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"n\">n_samples</span><span class=\"p\">,),</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">dtype</span><span class=\"p\">)</span>\n\n    <span class=\"c1\"># Determine min and max sizes if non given</span>\n    <span class=\"k\">if</span> <span class=\"n\">size_min</span> <span class=\"ow\">is</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n        <span class=\"n\">size_min</span> <span class=\"o\">=</span> <span class=\"mi\">0</span>\n    <span class=\"k\">if</span> <span class=\"n\">size_max</span> <span class=\"ow\">is</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n        <span class=\"n\">size_max</span> <span class=\"o\">=</span> <span class=\"n\">n_samples</span>  <span class=\"c1\"># Number of data points</span>\n\n    <span class=\"c1\"># Check size min and max</span>\n    <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"p\">((</span><span class=\"n\">size_min</span> <span class=\"o\">&gt;=</span> <span class=\"mi\">0</span><span class=\"p\">)</span> <span class=\"ow\">and</span> <span class=\"p\">(</span><span class=\"n\">size_min</span> <span class=\"o\">&lt;=</span> <span class=\"n\">n_samples</span><span class=\"p\">)</span>\n            <span class=\"ow\">and</span> <span class=\"p\">(</span><span class=\"n\">size_max</span> <span class=\"o\">&gt;=</span> <span class=\"mi\">0</span><span class=\"p\">)</span> <span class=\"ow\">and</span> <span class=\"p\">(</span><span class=\"n\">size_max</span> <span class=\"o\">&lt;=</span> <span class=\"n\">n_samples</span><span class=\"p\">)):</span>\n        <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s2\">&quot;size_min and size_max must be a positive number smaller &quot;</span>\n                         <span class=\"s2\">&quot;than the number of data points or `None`&quot;</span><span class=\"p\">)</span>\n    <span class=\"k\">if</span> <span class=\"n\">size_max</span> <span class=\"o\">&lt;</span> <span class=\"n\">size_min</span><span class=\"p\">:</span>\n        <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s2\">&quot;size_max must be larger than size_min&quot;</span><span class=\"p\">)</span>\n    <span class=\"k\">if</span> <span class=\"n\">size_min</span> <span class=\"o\">*</span> <span class=\"n\">n_clusters</span> <span class=\"o\">&gt;</span> <span class=\"n\">n_samples</span><span class=\"p\">:</span>\n        <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s2\">&quot;The product of size_min and n_clusters cannot exceed the number of samples (X)&quot;</span><span class=\"p\">)</span>\n    <span class=\"k\">if</span> <span class=\"n\">size_max</span> <span class=\"o\">*</span> <span class=\"n\">n_clusters</span> <span class=\"o\">&lt;</span> <span class=\"n\">n_samples</span><span class=\"p\">:</span>\n        <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s2\">&quot;The product of size_max and n_clusters must be larger than or equal the number of samples (X)&quot;</span><span class=\"p\">)</span>\n\n    <span class=\"c1\"># iterations</span>\n    <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">max_iter</span><span class=\"p\">):</span>\n        <span class=\"n\">centers_old</span> <span class=\"o\">=</span> <span class=\"n\">centers</span><span class=\"o\">.</span><span class=\"n\">copy</span><span class=\"p\">()</span>\n        <span class=\"c1\"># labels assignment is also called the E-step of EM</span>\n        <span class=\"n\">labels</span><span class=\"p\">,</span> <span class=\"n\">inertia</span> <span class=\"o\">=</span> \\\n            <span class=\"n\">_labels_constrained</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">centers</span><span class=\"p\">,</span> <span class=\"n\">size_min</span><span class=\"p\">,</span> <span class=\"n\">size_max</span><span class=\"p\">,</span> <span class=\"n\">distances</span><span class=\"o\">=</span><span class=\"n\">distances</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># computation of the means is also called the M-step of EM</span>\n        <span class=\"k\">if</span> <span class=\"n\">sp</span><span class=\"o\">.</span><span class=\"n\">issparse</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">):</span>\n            <span class=\"n\">centers</span> <span class=\"o\">=</span> <span class=\"n\">_centers_sparse</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">labels</span><span class=\"p\">,</span> <span class=\"n\">n_clusters</span><span class=\"p\">,</span> <span class=\"n\">distances</span><span class=\"p\">)</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"n\">centers</span> <span class=\"o\">=</span> <span class=\"n\">_centers_dense</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">labels</span><span class=\"p\">,</span> <span class=\"n\">n_clusters</span><span class=\"p\">,</span> <span class=\"n\">distances</span><span class=\"p\">)</span>\n\n        <span class=\"k\">if</span> <span class=\"n\">verbose</span><span class=\"p\">:</span>\n            <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s2\">&quot;Iteration </span><span class=\"si\">%2d</span><span class=\"s2\">, inertia </span><span class=\"si\">%.3f</span><span class=\"s2\">&quot;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">inertia</span><span class=\"p\">))</span>\n\n        <span class=\"k\">if</span> <span class=\"n\">best_inertia</span> <span class=\"ow\">is</span> <span class=\"kc\">None</span> <span class=\"ow\">or</span> <span class=\"n\">inertia</span> <span class=\"o\">&lt;</span> <span class=\"n\">best_inertia</span><span class=\"p\">:</span>\n            <span class=\"n\">best_labels</span> <span class=\"o\">=</span> <span class=\"n\">labels</span><span class=\"o\">.</span><span class=\"n\">copy</span><span class=\"p\">()</span>\n            <span class=\"n\">best_centers</span> <span class=\"o\">=</span> <span class=\"n\">centers</span><span class=\"o\">.</span><span class=\"n\">copy</span><span class=\"p\">()</span>\n            <span class=\"n\">best_inertia</span> <span class=\"o\">=</span> <span class=\"n\">inertia</span>\n\n        <span class=\"n\">center_shift_total</span> <span class=\"o\">=</span> <span class=\"n\">squared_norm</span><span class=\"p\">(</span><span class=\"n\">centers_old</span> <span class=\"o\">-</span> <span class=\"n\">centers</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"n\">center_shift_total</span> <span class=\"o\">&lt;=</span> <span class=\"n\">tol</span><span class=\"p\">:</span>\n            <span class=\"k\">if</span> <span class=\"n\">verbose</span><span class=\"p\">:</span>\n                <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s2\">&quot;Converged at iteration </span><span class=\"si\">%d</span><span class=\"s2\">: &quot;</span>\n                      <span class=\"s2\">&quot;center shift </span><span class=\"si\">%e</span><span class=\"s2\"> within tolerance </span><span class=\"si\">%e</span><span class=\"s2\">&quot;</span>\n                      <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">center_shift_total</span><span class=\"p\">,</span> <span class=\"n\">tol</span><span class=\"p\">))</span>\n            <span class=\"k\">break</span>\n\n    <span class=\"k\">if</span> <span class=\"n\">center_shift_total</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n        <span class=\"c1\"># rerun E-step in case of non-convergence so that predicted labels</span>\n        <span class=\"c1\"># match cluster centers</span>\n        <span class=\"n\">best_labels</span><span class=\"p\">,</span> <span class=\"n\">best_inertia</span> <span class=\"o\">=</span> \\\n            <span class=\"n\">_labels_constrained</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">centers</span><span class=\"p\">,</span> <span class=\"n\">size_min</span><span class=\"p\">,</span> <span class=\"n\">size_max</span><span class=\"p\">,</span> <span class=\"n\">distances</span><span class=\"o\">=</span><span class=\"n\">distances</span><span class=\"p\">)</span>\n\n    <span class=\"k\">return</span> <span class=\"n\">best_labels</span><span class=\"p\">,</span> <span class=\"n\">best_inertia</span><span class=\"p\">,</span> <span class=\"n\">best_centers</span><span class=\"p\">,</span> <span class=\"n\">i</span> <span class=\"o\">+</span> <span class=\"mi\">1</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">_labels_constrained</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">centers</span><span class=\"p\">,</span> <span class=\"n\">size_min</span><span class=\"p\">,</span> <span class=\"n\">size_max</span><span class=\"p\">,</span> <span class=\"n\">distances</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Compute labels using the min and max cluster size constraint</span>\n\n<span class=\"sd\">    This will overwrite the &#39;distances&#39; array in-place.</span>\n\n<span class=\"sd\">    Parameters</span>\n<span class=\"sd\">    ----------</span>\n<span class=\"sd\">    X : numpy array, shape (n_sample, n_features)</span>\n<span class=\"sd\">        Input data.</span>\n\n<span class=\"sd\">    size_min : int</span>\n<span class=\"sd\">        Minimum size for each cluster</span>\n\n<span class=\"sd\">    size_max : int</span>\n<span class=\"sd\">        Maximum size for each cluster</span>\n\n<span class=\"sd\">    centers : numpy array, shape (n_clusters, n_features)</span>\n<span class=\"sd\">        Cluster centers which data is assigned to.</span>\n\n<span class=\"sd\">    distances : numpy array, shape (n_samples,)</span>\n<span class=\"sd\">        Pre-allocated array in which distances are stored.</span>\n\n<span class=\"sd\">    Returns</span>\n<span class=\"sd\">    -------</span>\n<span class=\"sd\">    labels : numpy array, dtype=np.int, shape (n_samples,)</span>\n<span class=\"sd\">        Indices of clusters that samples are assigned to.</span>\n\n<span class=\"sd\">    inertia : float</span>\n<span class=\"sd\">        Sum of squared distances of samples to their closest cluster center.</span>\n\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"n\">C</span> <span class=\"o\">=</span> <span class=\"n\">centers</span>\n\n    <span class=\"c1\"># Distances to each centre C. (the `distances` parameter is the distance to the closest centre)</span>\n    <span class=\"c1\"># K-mean original uses squared distances but this equivalent for constrained k-means</span>\n    <span class=\"n\">D</span> <span class=\"o\">=</span> <span class=\"n\">euclidean_distances</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">C</span><span class=\"p\">,</span> <span class=\"n\">squared</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n\n    <span class=\"n\">edges</span><span class=\"p\">,</span> <span class=\"n\">costs</span><span class=\"p\">,</span> <span class=\"n\">capacities</span><span class=\"p\">,</span> <span class=\"n\">supplies</span><span class=\"p\">,</span> <span class=\"n\">n_C</span><span class=\"p\">,</span> <span class=\"n\">n_X</span> <span class=\"o\">=</span> <span class=\"n\">minimum_cost_flow_problem_graph</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">C</span><span class=\"p\">,</span> <span class=\"n\">D</span><span class=\"p\">,</span> <span class=\"n\">size_min</span><span class=\"p\">,</span> <span class=\"n\">size_max</span><span class=\"p\">)</span>\n    <span class=\"n\">labels</span> <span class=\"o\">=</span> <span class=\"n\">solve_min_cost_flow_graph</span><span class=\"p\">(</span><span class=\"n\">edges</span><span class=\"p\">,</span> <span class=\"n\">costs</span><span class=\"p\">,</span> <span class=\"n\">capacities</span><span class=\"p\">,</span> <span class=\"n\">supplies</span><span class=\"p\">,</span> <span class=\"n\">n_C</span><span class=\"p\">,</span> <span class=\"n\">n_X</span><span class=\"p\">)</span>\n\n    <span class=\"c1\"># cython k-means M step code assumes int32 inputs</span>\n    <span class=\"n\">labels</span> <span class=\"o\">=</span> <span class=\"n\">labels</span><span class=\"o\">.</span><span class=\"n\">astype</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">int32</span><span class=\"p\">)</span>\n\n    <span class=\"c1\"># Change distances in-place</span>\n    <span class=\"n\">distances</span><span class=\"p\">[:]</span> <span class=\"o\">=</span> <span class=\"n\">D</span><span class=\"p\">[</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">arange</span><span class=\"p\">(</span><span class=\"n\">D</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]),</span> <span class=\"n\">labels</span><span class=\"p\">]</span> <span class=\"o\">**</span> <span class=\"mi\">2</span>  <span class=\"c1\"># Square for M step of EM</span>\n    <span class=\"n\">inertia</span> <span class=\"o\">=</span> <span class=\"n\">distances</span><span class=\"o\">.</span><span class=\"n\">sum</span><span class=\"p\">()</span>\n\n    <span class=\"k\">return</span> <span class=\"n\">labels</span><span class=\"p\">,</span> <span class=\"n\">inertia</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">minimum_cost_flow_problem_graph</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">C</span><span class=\"p\">,</span> <span class=\"n\">D</span><span class=\"p\">,</span> <span class=\"n\">size_min</span><span class=\"p\">,</span> <span class=\"n\">size_max</span><span class=\"p\">):</span>\n    <span class=\"c1\"># Setup minimum cost flow formulation graph</span>\n    <span class=\"c1\"># Vertices indexes:</span>\n    <span class=\"c1\"># X-nodes: [0, n(x)-1], C-nodes: [n(X), n(X)+n(C)-1], C-dummy nodes:[n(X)+n(C), n(X)+2*n(C)-1],</span>\n    <span class=\"c1\"># Artificial node: [n(X)+2*n(C), n(X)+2*n(C)+1-1]</span>\n\n    <span class=\"c1\"># Create indices of nodes</span>\n    <span class=\"n\">n_X</span> <span class=\"o\">=</span> <span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n    <span class=\"n\">n_C</span> <span class=\"o\">=</span> <span class=\"n\">C</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n    <span class=\"n\">X_ix</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">arange</span><span class=\"p\">(</span><span class=\"n\">n_X</span><span class=\"p\">)</span>\n    <span class=\"n\">C_dummy_ix</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">arange</span><span class=\"p\">(</span><span class=\"n\">X_ix</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">X_ix</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"mi\">1</span> <span class=\"o\">+</span> <span class=\"n\">n_C</span><span class=\"p\">)</span>\n    <span class=\"n\">C_ix</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">arange</span><span class=\"p\">(</span><span class=\"n\">C_dummy_ix</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">C_dummy_ix</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"mi\">1</span> <span class=\"o\">+</span> <span class=\"n\">n_C</span><span class=\"p\">)</span>\n    <span class=\"n\">art_ix</span> <span class=\"o\">=</span> <span class=\"n\">C_ix</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"mi\">1</span>\n\n    <span class=\"c1\"># Edges</span>\n    <span class=\"n\">edges_X_C_dummy</span> <span class=\"o\">=</span> <span class=\"n\">cartesian</span><span class=\"p\">([</span><span class=\"n\">X_ix</span><span class=\"p\">,</span> <span class=\"n\">C_dummy_ix</span><span class=\"p\">])</span>  <span class=\"c1\"># All X&#39;s connect to all C dummy nodes (C&#39;)</span>\n    <span class=\"n\">edges_C_dummy_C</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">stack</span><span class=\"p\">([</span><span class=\"n\">C_dummy_ix</span><span class=\"p\">,</span> <span class=\"n\">C_ix</span><span class=\"p\">],</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>  <span class=\"c1\"># Each C&#39; connects to a corresponding C (centroid)</span>\n    <span class=\"n\">edges_C_art</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">stack</span><span class=\"p\">([</span><span class=\"n\">C_ix</span><span class=\"p\">,</span> <span class=\"n\">art_ix</span> <span class=\"o\">*</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">ones</span><span class=\"p\">(</span><span class=\"n\">n_C</span><span class=\"p\">)],</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>  <span class=\"c1\"># All C connect to artificial node</span>\n\n    <span class=\"n\">edges</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">([</span><span class=\"n\">edges_X_C_dummy</span><span class=\"p\">,</span> <span class=\"n\">edges_C_dummy_C</span><span class=\"p\">,</span> <span class=\"n\">edges_C_art</span><span class=\"p\">])</span>\n\n    <span class=\"c1\"># Costs</span>\n    <span class=\"n\">costs_X_C_dummy</span> <span class=\"o\">=</span> <span class=\"n\">D</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">D</span><span class=\"o\">.</span><span class=\"n\">size</span><span class=\"p\">)</span>\n    <span class=\"n\">costs</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">([</span><span class=\"n\">costs_X_C_dummy</span><span class=\"p\">,</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">(</span><span class=\"n\">edges</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">costs_X_C_dummy</span><span class=\"p\">))])</span>\n\n    <span class=\"c1\"># Capacities - can set for max-k</span>\n    <span class=\"n\">capacities_C_dummy_C</span> <span class=\"o\">=</span> <span class=\"n\">size_max</span> <span class=\"o\">*</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">ones</span><span class=\"p\">(</span><span class=\"n\">n_C</span><span class=\"p\">)</span>\n    <span class=\"n\">cap_non</span> <span class=\"o\">=</span> <span class=\"n\">n_X</span>  <span class=\"c1\"># The total supply and therefore wont restrict flow</span>\n    <span class=\"n\">capacities</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">([</span>\n        <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">ones</span><span class=\"p\">(</span><span class=\"n\">edges_X_C_dummy</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]),</span>\n        <span class=\"n\">capacities_C_dummy_C</span><span class=\"p\">,</span>\n        <span class=\"n\">cap_non</span> <span class=\"o\">*</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">ones</span><span class=\"p\">(</span><span class=\"n\">n_C</span><span class=\"p\">)</span>\n    <span class=\"p\">])</span>\n\n    <span class=\"c1\"># Sources and sinks</span>\n    <span class=\"n\">supplies_X</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">ones</span><span class=\"p\">(</span><span class=\"n\">n_X</span><span class=\"p\">)</span>\n    <span class=\"n\">supplies_C</span> <span class=\"o\">=</span> <span class=\"o\">-</span><span class=\"mi\">1</span> <span class=\"o\">*</span> <span class=\"n\">size_min</span> <span class=\"o\">*</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">ones</span><span class=\"p\">(</span><span class=\"n\">n_C</span><span class=\"p\">)</span>  <span class=\"c1\"># Demand node</span>\n    <span class=\"n\">supplies_art</span> <span class=\"o\">=</span> <span class=\"o\">-</span><span class=\"mi\">1</span> <span class=\"o\">*</span> <span class=\"p\">(</span><span class=\"n\">n_X</span> <span class=\"o\">-</span> <span class=\"n\">n_C</span> <span class=\"o\">*</span> <span class=\"n\">size_min</span><span class=\"p\">)</span>  <span class=\"c1\"># Demand node</span>\n    <span class=\"n\">supplies</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">([</span>\n        <span class=\"n\">supplies_X</span><span class=\"p\">,</span>\n        <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">(</span><span class=\"n\">n_C</span><span class=\"p\">),</span>  <span class=\"c1\"># C_dummies</span>\n        <span class=\"n\">supplies_C</span><span class=\"p\">,</span>\n        <span class=\"p\">[</span><span class=\"n\">supplies_art</span><span class=\"p\">]</span>\n    <span class=\"p\">])</span>\n\n    <span class=\"c1\"># All arrays must be of int dtype for `SimpleMinCostFlow`</span>\n    <span class=\"n\">edges</span> <span class=\"o\">=</span> <span class=\"n\">edges</span><span class=\"o\">.</span><span class=\"n\">astype</span><span class=\"p\">(</span><span class=\"s1\">&#39;int32&#39;</span><span class=\"p\">)</span>\n    <span class=\"n\">costs</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">around</span><span class=\"p\">(</span><span class=\"n\">costs</span> <span class=\"o\">*</span> <span class=\"mi\">1000</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">astype</span><span class=\"p\">(</span><span class=\"s1\">&#39;int32&#39;</span><span class=\"p\">)</span>  <span class=\"c1\"># Times by 1000 to give extra precision</span>\n    <span class=\"n\">capacities</span> <span class=\"o\">=</span> <span class=\"n\">capacities</span><span class=\"o\">.</span><span class=\"n\">astype</span><span class=\"p\">(</span><span class=\"s1\">&#39;int32&#39;</span><span class=\"p\">)</span>\n    <span class=\"n\">supplies</span> <span class=\"o\">=</span> <span class=\"n\">supplies</span><span class=\"o\">.</span><span class=\"n\">astype</span><span class=\"p\">(</span><span class=\"s1\">&#39;int32&#39;</span><span class=\"p\">)</span>\n\n    <span class=\"k\">return</span> <span class=\"n\">edges</span><span class=\"p\">,</span> <span class=\"n\">costs</span><span class=\"p\">,</span> <span class=\"n\">capacities</span><span class=\"p\">,</span> <span class=\"n\">supplies</span><span class=\"p\">,</span> <span class=\"n\">n_C</span><span class=\"p\">,</span> <span class=\"n\">n_X</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">solve_min_cost_flow_graph</span><span class=\"p\">(</span><span class=\"n\">edges</span><span class=\"p\">,</span> <span class=\"n\">costs</span><span class=\"p\">,</span> <span class=\"n\">capacities</span><span class=\"p\">,</span> <span class=\"n\">supplies</span><span class=\"p\">,</span> <span class=\"n\">n_C</span><span class=\"p\">,</span> <span class=\"n\">n_X</span><span class=\"p\">):</span>\n    <span class=\"c1\"># Instantiate a SimpleMinCostFlow solver.</span>\n    <span class=\"n\">min_cost_flow</span> <span class=\"o\">=</span> <span class=\"n\">SimpleMinCostFlowVectorized</span><span class=\"p\">()</span>\n\n    <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"n\">edges</span><span class=\"o\">.</span><span class=\"n\">dtype</span> <span class=\"o\">!=</span> <span class=\"s1\">&#39;int32&#39;</span><span class=\"p\">)</span> <span class=\"ow\">or</span> <span class=\"p\">(</span><span class=\"n\">costs</span><span class=\"o\">.</span><span class=\"n\">dtype</span> <span class=\"o\">!=</span> <span class=\"s1\">&#39;int32&#39;</span><span class=\"p\">)</span> \\\n            <span class=\"ow\">or</span> <span class=\"p\">(</span><span class=\"n\">capacities</span><span class=\"o\">.</span><span class=\"n\">dtype</span> <span class=\"o\">!=</span> <span class=\"s1\">&#39;int32&#39;</span><span class=\"p\">)</span> <span class=\"ow\">or</span> <span class=\"p\">(</span><span class=\"n\">supplies</span><span class=\"o\">.</span><span class=\"n\">dtype</span> <span class=\"o\">!=</span> <span class=\"s1\">&#39;int32&#39;</span><span class=\"p\">):</span>\n        <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s2\">&quot;`edges`, `costs`, `capacities`, `supplies` must all be int dtype&quot;</span><span class=\"p\">)</span>\n\n    <span class=\"n\">N_edges</span> <span class=\"o\">=</span> <span class=\"n\">edges</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n    <span class=\"n\">N_nodes</span> <span class=\"o\">=</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">supplies</span><span class=\"p\">)</span>\n\n    <span class=\"c1\"># Add each edge with associated capacities and cost</span>\n    <span class=\"n\">min_cost_flow</span><span class=\"o\">.</span><span class=\"n\">AddArcWithCapacityAndUnitCostVectorized</span><span class=\"p\">(</span><span class=\"n\">edges</span><span class=\"p\">[:,</span> <span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"n\">edges</span><span class=\"p\">[:,</span> <span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"n\">capacities</span><span class=\"p\">,</span> <span class=\"n\">costs</span><span class=\"p\">)</span>\n\n    <span class=\"c1\"># Add node supplies</span>\n    <span class=\"n\">min_cost_flow</span><span class=\"o\">.</span><span class=\"n\">SetNodeSupplyVectorized</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">arange</span><span class=\"p\">(</span><span class=\"n\">N_nodes</span><span class=\"p\">,</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"s1\">&#39;int32&#39;</span><span class=\"p\">),</span> <span class=\"n\">supplies</span><span class=\"p\">)</span>\n\n    <span class=\"c1\"># Find the minimum cost flow between node 0 and node 4.</span>\n    <span class=\"k\">if</span> <span class=\"n\">min_cost_flow</span><span class=\"o\">.</span><span class=\"n\">Solve</span><span class=\"p\">()</span> <span class=\"o\">!=</span> <span class=\"n\">min_cost_flow</span><span class=\"o\">.</span><span class=\"n\">OPTIMAL</span><span class=\"p\">:</span>\n        <span class=\"k\">raise</span> <span class=\"ne\">Exception</span><span class=\"p\">(</span><span class=\"s1\">&#39;There was an issue with the min cost flow input.&#39;</span><span class=\"p\">)</span>\n\n    <span class=\"c1\"># Assignment</span>\n    <span class=\"n\">labels_M</span> <span class=\"o\">=</span> <span class=\"n\">min_cost_flow</span><span class=\"o\">.</span><span class=\"n\">FlowVectorized</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">arange</span><span class=\"p\">(</span><span class=\"n\">n_X</span> <span class=\"o\">*</span> <span class=\"n\">n_C</span><span class=\"p\">,</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"s1\">&#39;int32&#39;</span><span class=\"p\">))</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"n\">n_X</span><span class=\"p\">,</span> <span class=\"n\">n_C</span><span class=\"p\">)</span>\n\n    <span class=\"n\">labels</span> <span class=\"o\">=</span> <span class=\"n\">labels_M</span><span class=\"o\">.</span><span class=\"n\">argmax</span><span class=\"p\">(</span><span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">labels</span>\n\n\n<div class=\"viewcode-block\" id=\"KMeansConstrained\"><a class=\"viewcode-back\" href=\"../../index.html#k_means_constrained.KMeansConstrained\">[docs]</a><span class=\"k\">class</span> <span class=\"nc\">KMeansConstrained</span><span class=\"p\">(</span><span class=\"n\">KMeans</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;K-Means clustering with minimum and maximum cluster size constraints</span>\n\n<span class=\"sd\">    Parameters</span>\n<span class=\"sd\">    ----------</span>\n\n<span class=\"sd\">    n_clusters : int, optional, default: 8</span>\n<span class=\"sd\">        The number of clusters to form as well as the number of</span>\n<span class=\"sd\">        centroids to generate.</span>\n\n<span class=\"sd\">    size_min : int, optional, default: None</span>\n<span class=\"sd\">        Constrain the label assignment so that each cluster has a minimum</span>\n<span class=\"sd\">        size of size_min. If None, no constrains will be applied</span>\n\n<span class=\"sd\">    size_max : int, optional, default: None</span>\n<span class=\"sd\">        Constrain the label assignment so that each cluster has a maximum</span>\n<span class=\"sd\">        size of size_max. If None, no constrains will be applied</span>\n\n<span class=\"sd\">    init : {&#39;k-means++&#39;, &#39;random&#39; or an ndarray}</span>\n<span class=\"sd\">        Method for initialization, defaults to &#39;k-means++&#39;:</span>\n\n<span class=\"sd\">        &#39;k-means++&#39; : selects initial cluster centers for k-mean</span>\n<span class=\"sd\">        clustering in a smart way to speed up convergence. See section</span>\n<span class=\"sd\">        Notes in k_init for more details.</span>\n\n<span class=\"sd\">        &#39;random&#39;: choose k observations (rows) at random from data for</span>\n<span class=\"sd\">        the initial centroids.</span>\n\n<span class=\"sd\">        If an ndarray is passed, it should be of shape (n_clusters, n_features)</span>\n<span class=\"sd\">        and gives the initial centers.</span>\n\n<span class=\"sd\">    n_init : int, default: 10</span>\n<span class=\"sd\">        Number of times the k-means algorithm will be run with different</span>\n<span class=\"sd\">        centroid seeds. The final results will be the best output of</span>\n<span class=\"sd\">        n_init consecutive runs in terms of inertia.</span>\n\n<span class=\"sd\">    max_iter : int, default: 300</span>\n<span class=\"sd\">        Maximum number of iterations of the k-means algorithm for a</span>\n<span class=\"sd\">        single run.</span>\n\n<span class=\"sd\">    tol : float, default: 1e-4</span>\n<span class=\"sd\">        Relative tolerance with regards to Frobenius norm of the difference</span>\n<span class=\"sd\">        in the cluster centers of two consecutive iterations to declare</span>\n<span class=\"sd\">        convergence.</span>\n\n<span class=\"sd\">    verbose : int, default 0</span>\n<span class=\"sd\">        Verbosity mode.</span>\n\n<span class=\"sd\">    random_state : int, RandomState instance or None, optional, default: None</span>\n<span class=\"sd\">        If int, random_state is the seed used by the random number generator;</span>\n<span class=\"sd\">        If RandomState instance, random_state is the random number generator;</span>\n<span class=\"sd\">        If None, the random number generator is the RandomState instance used</span>\n<span class=\"sd\">        by `np.random`.</span>\n\n<span class=\"sd\">    copy_x : boolean, default True</span>\n<span class=\"sd\">        When pre-computing distances it is more numerically accurate to center</span>\n<span class=\"sd\">        the data first.  If copy_x is True, then the original data is not</span>\n<span class=\"sd\">        modified.  If False, the original data is modified, and put back before</span>\n<span class=\"sd\">        the function returns, but small numerical differences may be introduced</span>\n<span class=\"sd\">        by subtracting and then adding the data mean.</span>\n\n<span class=\"sd\">    n_jobs : int</span>\n<span class=\"sd\">        The number of jobs to use for the computation. This works by computing</span>\n<span class=\"sd\">        each of the n_init runs in parallel.</span>\n\n<span class=\"sd\">        If -1 all CPUs are used. If 1 is given, no parallel computing code is</span>\n<span class=\"sd\">        used at all, which is useful for debugging. For n_jobs below -1,</span>\n<span class=\"sd\">        (n_cpus + 1 + n_jobs) are used. Thus for n_jobs = -2, all CPUs but one</span>\n<span class=\"sd\">        are used.</span>\n\n<span class=\"sd\">    Attributes</span>\n<span class=\"sd\">    ----------</span>\n<span class=\"sd\">    cluster_centers_ : array, [n_clusters, n_features]</span>\n<span class=\"sd\">        Coordinates of cluster centers</span>\n\n<span class=\"sd\">    labels_ :</span>\n<span class=\"sd\">        Labels of each point</span>\n\n<span class=\"sd\">    inertia_ : float</span>\n<span class=\"sd\">        Sum of squared distances of samples to their closest cluster center.</span>\n\n<span class=\"sd\">    Examples</span>\n<span class=\"sd\">    --------</span>\n\n<span class=\"sd\">    &gt;&gt;&gt; from k_means_constrained import KMeansConstrained</span>\n<span class=\"sd\">    &gt;&gt;&gt; import numpy as np</span>\n<span class=\"sd\">    &gt;&gt;&gt; X = np.array([[1, 2], [1, 4], [1, 0],</span>\n<span class=\"sd\">    ...                [4, 2], [4, 4], [4, 0]])</span>\n<span class=\"sd\">    &gt;&gt;&gt; clf = KMeansConstrained(</span>\n<span class=\"sd\">    ...     n_clusters=2,</span>\n<span class=\"sd\">    ...     size_min=2,</span>\n<span class=\"sd\">    ...     size_max=5,</span>\n<span class=\"sd\">    ...     random_state=0</span>\n<span class=\"sd\">    ... )</span>\n<span class=\"sd\">    &gt;&gt;&gt; clf.fit_predict(X)</span>\n<span class=\"sd\">    array([0, 0, 0, 1, 1, 1], dtype=int32)</span>\n<span class=\"sd\">    &gt;&gt;&gt; clf.cluster_centers_</span>\n<span class=\"sd\">    array([[ 1.,  2.],</span>\n<span class=\"sd\">           [ 4.,  2.]])</span>\n<span class=\"sd\">    &gt;&gt;&gt; clf.labels_</span>\n<span class=\"sd\">    array([0, 0, 0, 1, 1, 1], dtype=int32)</span>\n\n<span class=\"sd\">    Notes</span>\n<span class=\"sd\">    ------</span>\n<span class=\"sd\">    K-means problem constrained with a minimum and/or maximum size for each cluster.</span>\n\n<span class=\"sd\">    The constrained assignment is formulated as a Minimum Cost Flow (MCF) linear network optimisation</span>\n<span class=\"sd\">    problem. This is then solved using a cost-scaling push-relabel algorithm. The implementation used is</span>\n<span class=\"sd\">     Google&#39;s Operations Research tools&#39;s `SimpleMinCostFlow`.</span>\n\n<span class=\"sd\">    Ref:</span>\n<span class=\"sd\">    1. Bradley, P. S., K. P. Bennett, and Ayhan Demiriz. &quot;Constrained k-means clustering.&quot;</span>\n<span class=\"sd\">        Microsoft Research, Redmond (2000): 1-8.</span>\n<span class=\"sd\">    2. Google&#39;s SimpleMinCostFlow implementation:</span>\n<span class=\"sd\">        https://github.com/google/or-tools/blob/master/ortools/graph/min_cost_flow.h</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n\n    <span class=\"k\">def</span> <span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">n_clusters</span><span class=\"o\">=</span><span class=\"mi\">8</span><span class=\"p\">,</span> <span class=\"n\">size_min</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">size_max</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">init</span><span class=\"o\">=</span><span class=\"s1\">&#39;k-means++&#39;</span><span class=\"p\">,</span> <span class=\"n\">n_init</span><span class=\"o\">=</span><span class=\"mi\">10</span><span class=\"p\">,</span> <span class=\"n\">max_iter</span><span class=\"o\">=</span><span class=\"mi\">300</span><span class=\"p\">,</span> <span class=\"n\">tol</span><span class=\"o\">=</span><span class=\"mf\">1e-4</span><span class=\"p\">,</span>\n                 <span class=\"n\">verbose</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span> <span class=\"n\">random_state</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">copy_x</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span> <span class=\"n\">n_jobs</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">):</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">size_min</span> <span class=\"o\">=</span> <span class=\"n\">size_min</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">size_max</span> <span class=\"o\">=</span> <span class=\"n\">size_max</span>\n\n        <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"n\">n_clusters</span><span class=\"o\">=</span><span class=\"n\">n_clusters</span><span class=\"p\">,</span> <span class=\"n\">init</span><span class=\"o\">=</span><span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"n\">n_init</span><span class=\"o\">=</span><span class=\"n\">n_init</span><span class=\"p\">,</span> <span class=\"n\">max_iter</span><span class=\"o\">=</span><span class=\"n\">max_iter</span><span class=\"p\">,</span> <span class=\"n\">tol</span><span class=\"o\">=</span><span class=\"n\">tol</span><span class=\"p\">,</span>\n                         <span class=\"n\">verbose</span><span class=\"o\">=</span><span class=\"n\">verbose</span><span class=\"p\">,</span> <span class=\"n\">random_state</span><span class=\"o\">=</span><span class=\"n\">random_state</span><span class=\"p\">,</span> <span class=\"n\">copy_x</span><span class=\"o\">=</span><span class=\"n\">copy_x</span><span class=\"p\">,</span> <span class=\"n\">n_jobs</span><span class=\"o\">=</span><span class=\"n\">n_jobs</span><span class=\"p\">)</span>\n\n<div class=\"viewcode-block\" id=\"KMeansConstrained.fit\"><a class=\"viewcode-back\" href=\"../../index.html#k_means_constrained.KMeansConstrained.fit\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">fit</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Compute k-means clustering with given constants.</span>\n\n<span class=\"sd\">        Parameters</span>\n<span class=\"sd\">        ----------</span>\n<span class=\"sd\">        X : array-like, shape=(n_samples, n_features)</span>\n<span class=\"sd\">            Training instances to cluster.</span>\n\n<span class=\"sd\">        y : Ignored</span>\n\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"k\">if</span> <span class=\"n\">sp</span><span class=\"o\">.</span><span class=\"n\">issparse</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">):</span>\n            <span class=\"k\">raise</span> <span class=\"ne\">NotImplementedError</span><span class=\"p\">(</span><span class=\"s2\">&quot;Not implemented for sparse X&quot;</span><span class=\"p\">)</span>\n\n        <span class=\"n\">random_state</span> <span class=\"o\">=</span> <span class=\"n\">check_random_state</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">random_state</span><span class=\"p\">)</span>\n        <span class=\"n\">X</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_check_fit_data</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">cluster_centers_</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">labels_</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">inertia_</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">n_iter_</span> <span class=\"o\">=</span> \\\n            <span class=\"n\">k_means_constrained</span><span class=\"p\">(</span>\n                <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">n_clusters</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">n_clusters</span><span class=\"p\">,</span>\n                <span class=\"n\">size_min</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">size_min</span><span class=\"p\">,</span> <span class=\"n\">size_max</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">size_max</span><span class=\"p\">,</span>\n                <span class=\"n\">init</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">init</span><span class=\"p\">,</span>\n                <span class=\"n\">n_init</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">n_init</span><span class=\"p\">,</span> <span class=\"n\">max_iter</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">max_iter</span><span class=\"p\">,</span> <span class=\"n\">verbose</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">verbose</span><span class=\"p\">,</span>\n                <span class=\"n\">tol</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">tol</span><span class=\"p\">,</span> <span class=\"n\">random_state</span><span class=\"o\">=</span><span class=\"n\">random_state</span><span class=\"p\">,</span> <span class=\"n\">copy_x</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">copy_x</span><span class=\"p\">,</span>\n                <span class=\"n\">n_jobs</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">n_jobs</span><span class=\"p\">,</span>\n                <span class=\"n\">return_n_iter</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span></div>\n\n<div class=\"viewcode-block\" id=\"KMeansConstrained.predict\"><a class=\"viewcode-back\" href=\"../../index.html#k_means_constrained.KMeansConstrained.predict\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">predict</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">size_min</span><span class=\"o\">=</span><span class=\"s1\">&#39;init&#39;</span><span class=\"p\">,</span> <span class=\"n\">size_max</span><span class=\"o\">=</span><span class=\"s1\">&#39;init&#39;</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        Predict the closest cluster each sample in X belongs to given the provided constraints.</span>\n<span class=\"sd\">        The constraints can be temporally overridden when determining which cluster each datapoint is assigned to.</span>\n\n<span class=\"sd\">        Only computes the assignment step. It does not re-fit the cluster positions.</span>\n\n<span class=\"sd\">        Parameters</span>\n<span class=\"sd\">        ----------</span>\n<span class=\"sd\">        X : array-like, shape = [n_samples, n_features]</span>\n<span class=\"sd\">            New data to predict.</span>\n\n<span class=\"sd\">        size_min : int, optional, default: size_min provided with initialisation</span>\n<span class=\"sd\">            Constrain the label assignment so that each cluster has a minimum</span>\n<span class=\"sd\">            size of size_min. If None, no constrains will be applied.</span>\n<span class=\"sd\">            If &#39;init&#39; the value provided during initialisation of the</span>\n<span class=\"sd\">            class will be used.</span>\n\n<span class=\"sd\">        size_max : int, optional, default: size_max provided with initialisation</span>\n<span class=\"sd\">            Constrain the label assignment so that each cluster has a maximum</span>\n<span class=\"sd\">            size of size_max. If None, no constrains will be applied.</span>\n<span class=\"sd\">            If &#39;init&#39; the value provided during initialisation of the</span>\n<span class=\"sd\">            class will be used.</span>\n\n<span class=\"sd\">        Returns</span>\n<span class=\"sd\">        -------</span>\n<span class=\"sd\">        labels : array, shape [n_samples,]</span>\n<span class=\"sd\">            Index of the cluster each sample belongs to.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n\n        <span class=\"k\">if</span> <span class=\"n\">sp</span><span class=\"o\">.</span><span class=\"n\">issparse</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">):</span>\n            <span class=\"k\">raise</span> <span class=\"ne\">NotImplementedError</span><span class=\"p\">(</span><span class=\"s2\">&quot;Not implemented for sparse X&quot;</span><span class=\"p\">)</span>\n\n        <span class=\"k\">if</span> <span class=\"n\">size_min</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;init&#39;</span><span class=\"p\">:</span>\n            <span class=\"n\">size_min</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">size_min</span>\n        <span class=\"k\">if</span> <span class=\"n\">size_max</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;init&#39;</span><span class=\"p\">:</span>\n            <span class=\"n\">size_max</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">size_max</span>\n\n        <span class=\"n\">n_clusters</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">n_clusters</span>\n        <span class=\"n\">n_samples</span> <span class=\"o\">=</span> <span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n\n        <span class=\"n\">check_is_fitted</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"s1\">&#39;cluster_centers_&#39;</span><span class=\"p\">)</span>\n\n        <span class=\"n\">X</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_check_test_data</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># Allocate memory to store the distances for each sample to its</span>\n        <span class=\"c1\"># closer center for reallocation in case of ties</span>\n        <span class=\"n\">distances</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">(</span><span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"n\">n_samples</span><span class=\"p\">,),</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">dtype</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># Determine min and max sizes if non given</span>\n        <span class=\"k\">if</span> <span class=\"n\">size_min</span> <span class=\"ow\">is</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n            <span class=\"n\">size_min</span> <span class=\"o\">=</span> <span class=\"mi\">0</span>\n        <span class=\"k\">if</span> <span class=\"n\">size_max</span> <span class=\"ow\">is</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n            <span class=\"n\">size_max</span> <span class=\"o\">=</span> <span class=\"n\">n_samples</span>  <span class=\"c1\"># Number of data points</span>\n\n        <span class=\"c1\"># Check size min and max</span>\n        <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"p\">((</span><span class=\"n\">size_min</span> <span class=\"o\">&gt;=</span> <span class=\"mi\">0</span><span class=\"p\">)</span> <span class=\"ow\">and</span> <span class=\"p\">(</span><span class=\"n\">size_min</span> <span class=\"o\">&lt;=</span> <span class=\"n\">n_samples</span><span class=\"p\">)</span>\n                <span class=\"ow\">and</span> <span class=\"p\">(</span><span class=\"n\">size_max</span> <span class=\"o\">&gt;=</span> <span class=\"mi\">0</span><span class=\"p\">)</span> <span class=\"ow\">and</span> <span class=\"p\">(</span><span class=\"n\">size_max</span> <span class=\"o\">&lt;=</span> <span class=\"n\">n_samples</span><span class=\"p\">)):</span>\n            <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s2\">&quot;size_min and size_max must be a positive number smaller &quot;</span>\n                             <span class=\"s2\">&quot;than the number of data points or `None`&quot;</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"n\">size_max</span> <span class=\"o\">&lt;</span> <span class=\"n\">size_min</span><span class=\"p\">:</span>\n            <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s2\">&quot;size_max must be larger than size_min&quot;</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"n\">size_min</span> <span class=\"o\">*</span> <span class=\"n\">n_clusters</span> <span class=\"o\">&gt;</span> <span class=\"n\">n_samples</span><span class=\"p\">:</span>\n            <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s2\">&quot;The product of size_min and n_clusters cannot exceed the number of samples (X)&quot;</span><span class=\"p\">)</span>\n\n        <span class=\"n\">labels</span><span class=\"p\">,</span> <span class=\"n\">inertia</span> <span class=\"o\">=</span> \\\n            <span class=\"n\">_labels_constrained</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">cluster_centers_</span><span class=\"p\">,</span> <span class=\"n\">size_min</span><span class=\"p\">,</span> <span class=\"n\">size_max</span><span class=\"p\">,</span> <span class=\"n\">distances</span><span class=\"o\">=</span><span class=\"n\">distances</span><span class=\"p\">)</span>\n\n        <span class=\"k\">return</span> <span class=\"n\">labels</span></div>\n\n<div class=\"viewcode-block\" id=\"KMeansConstrained.fit_predict\"><a class=\"viewcode-back\" href=\"../../index.html#k_means_constrained.KMeansConstrained.fit_predict\">[docs]</a>    <span class=\"k\">def</span> <span class=\"nf\">fit_predict</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Compute cluster centers and predict cluster index for each sample.</span>\n\n<span class=\"sd\">        Equivalent to calling fit(X) followed by predict(X) but also more efficient.</span>\n\n<span class=\"sd\">        Parameters</span>\n<span class=\"sd\">        ----------</span>\n<span class=\"sd\">        X : {array-like, sparse matrix}, shape = [n_samples, n_features]</span>\n<span class=\"sd\">            New data to transform.</span>\n\n<span class=\"sd\">        Returns</span>\n<span class=\"sd\">        -------</span>\n<span class=\"sd\">        labels : array, shape [n_samples,]</span>\n<span class=\"sd\">            Index of the cluster each sample belongs to.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">fit</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">labels_</span></div></div>\n</pre></div>\n\n           </div>\n           \n          </div>\n          <footer>\n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &#169; Copyright 2020, Josh Levy-Kramer. Documentation derived from Scikit-Learn.\n\n    </p>\n  </div>\n    \n    \n    \n    Built with <a href=\"https://www.sphinx-doc.org/\">Sphinx</a> using a\n    \n    <a href=\"https://github.com/readthedocs/sphinx_rtd_theme\">theme</a>\n    \n    provided by <a href=\"https://readthedocs.org\">Read the Docs</a>. \n\n</footer>\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.Navigation.enable(true);\n      });\n  </script>\n\n  \n  \n    \n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/_modules/k_means_constrained/sklearn_cluster/k_means_.html",
    "content": "\n<!DOCTYPE html>\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>k_means_constrained.sklearn_cluster.k_means_ &#8212; k-means-constrained 0.0.2 documentation</title>\n    <link rel=\"stylesheet\" href=\"../../../_static/alabaster.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../../_static/pygments.css\" type=\"text/css\" />\n    <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../../\" src=\"../../../_static/documentation_options.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/jquery.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/underscore.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/doctools.js\"></script>\n    <script type=\"text/javascript\" src=\"../../../_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"../../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../../search.html\" />\n   \n  <link rel=\"stylesheet\" href=\"../../../_static/custom.css\" type=\"text/css\" />\n  \n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=0.9, maximum-scale=0.9\" />\n\n  </head><body>\n  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          \n\n          <div class=\"body\" role=\"main\">\n            \n  <h1>Source code for k_means_constrained.sklearn_cluster.k_means_</h1><div class=\"highlight\"><pre>\n<span></span><span class=\"sd\">&quot;&quot;&quot;K-means clustering&quot;&quot;&quot;</span>\n\n<span class=\"c1\"># Authors: Gael Varoquaux &lt;gael.varoquaux@normalesup.org&gt;</span>\n<span class=\"c1\">#          Thomas Rueckstiess &lt;ruecksti@in.tum.de&gt;</span>\n<span class=\"c1\">#          James Bergstra &lt;james.bergstra@umontreal.ca&gt;</span>\n<span class=\"c1\">#          Jan Schlueter &lt;scikit-learn@jan-schlueter.de&gt;</span>\n<span class=\"c1\">#          Nelle Varoquaux</span>\n<span class=\"c1\">#          Peter Prettenhofer &lt;peter.prettenhofer@gmail.com&gt;</span>\n<span class=\"c1\">#          Olivier Grisel &lt;olivier.grisel@ensta.org&gt;</span>\n<span class=\"c1\">#          Mathieu Blondel &lt;mathieu@mblondel.org&gt;</span>\n<span class=\"c1\">#          Robert Layton &lt;robertlayton@gmail.com&gt;</span>\n<span class=\"c1\"># License: BSD 3 clause</span>\n\n<span class=\"kn\">import</span> <span class=\"nn\">warnings</span>\n\n<span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n<span class=\"kn\">import</span> <span class=\"nn\">scipy.sparse</span> <span class=\"k\">as</span> <span class=\"nn\">sp</span>\n<span class=\"kn\">from</span> <span class=\"nn\">sklearn.base</span> <span class=\"k\">import</span> <span class=\"n\">BaseEstimator</span><span class=\"p\">,</span> <span class=\"n\">ClusterMixin</span><span class=\"p\">,</span> <span class=\"n\">TransformerMixin</span>\n<span class=\"kn\">from</span> <span class=\"nn\">sklearn.externals.six</span> <span class=\"k\">import</span> <span class=\"n\">string_types</span>\n<span class=\"kn\">from</span> <span class=\"nn\">sklearn.metrics.pairwise</span> <span class=\"k\">import</span> <span class=\"n\">euclidean_distances</span>\n<span class=\"kn\">from</span> <span class=\"nn\">sklearn.metrics.pairwise</span> <span class=\"k\">import</span> <span class=\"n\">pairwise_distances_argmin_min</span>\n<span class=\"kn\">from</span> <span class=\"nn\">sklearn.utils</span> <span class=\"k\">import</span> <span class=\"n\">check_array</span>\n<span class=\"kn\">from</span> <span class=\"nn\">sklearn.utils</span> <span class=\"k\">import</span> <span class=\"n\">check_random_state</span>\n<span class=\"kn\">from</span> <span class=\"nn\">sklearn.utils.extmath</span> <span class=\"k\">import</span> <span class=\"n\">row_norms</span><span class=\"p\">,</span> <span class=\"n\">stable_cumsum</span>\n<span class=\"kn\">from</span> <span class=\"nn\">sklearn.utils.sparsefuncs</span> <span class=\"k\">import</span> <span class=\"n\">mean_variance_axis</span>\n<span class=\"kn\">from</span> <span class=\"nn\">sklearn.utils.validation</span> <span class=\"k\">import</span> <span class=\"n\">FLOAT_DTYPES</span>\n<span class=\"kn\">from</span> <span class=\"nn\">sklearn.utils.validation</span> <span class=\"k\">import</span> <span class=\"n\">check_is_fitted</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">.</span> <span class=\"k\">import</span> <span class=\"n\">_k_means</span>\n\n\n<span class=\"c1\">###############################################################################</span>\n<span class=\"c1\"># Initialization heuristic</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">_k_init</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">n_clusters</span><span class=\"p\">,</span> <span class=\"n\">x_squared_norms</span><span class=\"p\">,</span> <span class=\"n\">random_state</span><span class=\"p\">,</span> <span class=\"n\">n_local_trials</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Init n_clusters seeds according to k-means++</span>\n\n<span class=\"sd\">    Parameters</span>\n<span class=\"sd\">    -----------</span>\n<span class=\"sd\">    X : array or sparse matrix, shape (n_samples, n_features)</span>\n<span class=\"sd\">        The data to pick seeds for. To avoid memory copy, the input data</span>\n<span class=\"sd\">        should be double precision (dtype=np.float64).</span>\n\n<span class=\"sd\">    n_clusters : integer</span>\n<span class=\"sd\">        The number of seeds to choose</span>\n\n<span class=\"sd\">    x_squared_norms : array, shape (n_samples,)</span>\n<span class=\"sd\">        Squared Euclidean norm of each data point.</span>\n\n<span class=\"sd\">    random_state : numpy.RandomState</span>\n<span class=\"sd\">        The generator used to initialize the centers.</span>\n\n<span class=\"sd\">    n_local_trials : integer, optional</span>\n<span class=\"sd\">        The number of seeding trials for each center (except the first),</span>\n<span class=\"sd\">        of which the one reducing inertia the most is greedily chosen.</span>\n<span class=\"sd\">        Set to None to make the number of trials depend logarithmically</span>\n<span class=\"sd\">        on the number of seeds (2+log(k)); this is the default.</span>\n\n<span class=\"sd\">    Notes</span>\n<span class=\"sd\">    -----</span>\n<span class=\"sd\">    Selects initial cluster centers for k-mean clustering in a smart way</span>\n<span class=\"sd\">    to speed up convergence. see: Arthur, D. and Vassilvitskii, S.</span>\n<span class=\"sd\">    &quot;k-means++: the advantages of careful seeding&quot;. ACM-SIAM symposium</span>\n<span class=\"sd\">    on Discrete algorithms. 2007</span>\n\n<span class=\"sd\">    Version ported from http://www.stanford.edu/~darthur/kMeansppTest.zip,</span>\n<span class=\"sd\">    which is the implementation used in the aforementioned paper.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"n\">n_samples</span><span class=\"p\">,</span> <span class=\"n\">n_features</span> <span class=\"o\">=</span> <span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">shape</span>\n\n    <span class=\"n\">centers</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">empty</span><span class=\"p\">((</span><span class=\"n\">n_clusters</span><span class=\"p\">,</span> <span class=\"n\">n_features</span><span class=\"p\">),</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">dtype</span><span class=\"p\">)</span>\n\n    <span class=\"k\">assert</span> <span class=\"n\">x_squared_norms</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"s1\">&#39;x_squared_norms None in _k_init&#39;</span>\n\n    <span class=\"c1\"># Set the number of local seeding trials if none is given</span>\n    <span class=\"k\">if</span> <span class=\"n\">n_local_trials</span> <span class=\"ow\">is</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n        <span class=\"c1\"># This is what Arthur/Vassilvitskii tried, but did not report</span>\n        <span class=\"c1\"># specific results for other than mentioning in the conclusion</span>\n        <span class=\"c1\"># that it helped.</span>\n        <span class=\"n\">n_local_trials</span> <span class=\"o\">=</span> <span class=\"mi\">2</span> <span class=\"o\">+</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">log</span><span class=\"p\">(</span><span class=\"n\">n_clusters</span><span class=\"p\">))</span>\n\n    <span class=\"c1\"># Pick first center randomly</span>\n    <span class=\"n\">center_id</span> <span class=\"o\">=</span> <span class=\"n\">random_state</span><span class=\"o\">.</span><span class=\"n\">randint</span><span class=\"p\">(</span><span class=\"n\">n_samples</span><span class=\"p\">)</span>\n    <span class=\"k\">if</span> <span class=\"n\">sp</span><span class=\"o\">.</span><span class=\"n\">issparse</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">):</span>\n        <span class=\"n\">centers</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">X</span><span class=\"p\">[</span><span class=\"n\">center_id</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">toarray</span><span class=\"p\">()</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"n\">centers</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">X</span><span class=\"p\">[</span><span class=\"n\">center_id</span><span class=\"p\">]</span>\n\n    <span class=\"c1\"># Initialize list of closest distances and calculate current potential</span>\n    <span class=\"n\">closest_dist_sq</span> <span class=\"o\">=</span> <span class=\"n\">euclidean_distances</span><span class=\"p\">(</span>\n        <span class=\"n\">centers</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">newaxis</span><span class=\"p\">],</span> <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">Y_norm_squared</span><span class=\"o\">=</span><span class=\"n\">x_squared_norms</span><span class=\"p\">,</span>\n        <span class=\"n\">squared</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n    <span class=\"n\">current_pot</span> <span class=\"o\">=</span> <span class=\"n\">closest_dist_sq</span><span class=\"o\">.</span><span class=\"n\">sum</span><span class=\"p\">()</span>\n\n    <span class=\"c1\"># Pick the remaining n_clusters-1 points</span>\n    <span class=\"k\">for</span> <span class=\"n\">c</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">n_clusters</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Choose center candidates by sampling with probability proportional</span>\n        <span class=\"c1\"># to the squared distance to the closest existing center</span>\n        <span class=\"n\">rand_vals</span> <span class=\"o\">=</span> <span class=\"n\">random_state</span><span class=\"o\">.</span><span class=\"n\">random_sample</span><span class=\"p\">(</span><span class=\"n\">n_local_trials</span><span class=\"p\">)</span> <span class=\"o\">*</span> <span class=\"n\">current_pot</span>\n        <span class=\"n\">candidate_ids</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">searchsorted</span><span class=\"p\">(</span><span class=\"n\">stable_cumsum</span><span class=\"p\">(</span><span class=\"n\">closest_dist_sq</span><span class=\"p\">),</span>\n                                        <span class=\"n\">rand_vals</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># Compute distances to center candidates</span>\n        <span class=\"n\">distance_to_candidates</span> <span class=\"o\">=</span> <span class=\"n\">euclidean_distances</span><span class=\"p\">(</span>\n            <span class=\"n\">X</span><span class=\"p\">[</span><span class=\"n\">candidate_ids</span><span class=\"p\">],</span> <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">Y_norm_squared</span><span class=\"o\">=</span><span class=\"n\">x_squared_norms</span><span class=\"p\">,</span> <span class=\"n\">squared</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># Decide which candidate is the best</span>\n        <span class=\"n\">best_candidate</span> <span class=\"o\">=</span> <span class=\"kc\">None</span>\n        <span class=\"n\">best_pot</span> <span class=\"o\">=</span> <span class=\"kc\">None</span>\n        <span class=\"n\">best_dist_sq</span> <span class=\"o\">=</span> <span class=\"kc\">None</span>\n        <span class=\"k\">for</span> <span class=\"n\">trial</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">n_local_trials</span><span class=\"p\">):</span>\n            <span class=\"c1\"># Compute potential when including center candidate</span>\n            <span class=\"n\">new_dist_sq</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">minimum</span><span class=\"p\">(</span><span class=\"n\">closest_dist_sq</span><span class=\"p\">,</span>\n                                     <span class=\"n\">distance_to_candidates</span><span class=\"p\">[</span><span class=\"n\">trial</span><span class=\"p\">])</span>\n            <span class=\"n\">new_pot</span> <span class=\"o\">=</span> <span class=\"n\">new_dist_sq</span><span class=\"o\">.</span><span class=\"n\">sum</span><span class=\"p\">()</span>\n\n            <span class=\"c1\"># Store result if it is the best local trial so far</span>\n            <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"n\">best_candidate</span> <span class=\"ow\">is</span> <span class=\"kc\">None</span><span class=\"p\">)</span> <span class=\"ow\">or</span> <span class=\"p\">(</span><span class=\"n\">new_pot</span> <span class=\"o\">&lt;</span> <span class=\"n\">best_pot</span><span class=\"p\">):</span>\n                <span class=\"n\">best_candidate</span> <span class=\"o\">=</span> <span class=\"n\">candidate_ids</span><span class=\"p\">[</span><span class=\"n\">trial</span><span class=\"p\">]</span>\n                <span class=\"n\">best_pot</span> <span class=\"o\">=</span> <span class=\"n\">new_pot</span>\n                <span class=\"n\">best_dist_sq</span> <span class=\"o\">=</span> <span class=\"n\">new_dist_sq</span>\n\n        <span class=\"c1\"># Permanently add best center candidate found in local tries</span>\n        <span class=\"k\">if</span> <span class=\"n\">sp</span><span class=\"o\">.</span><span class=\"n\">issparse</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">):</span>\n            <span class=\"n\">centers</span><span class=\"p\">[</span><span class=\"n\">c</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">X</span><span class=\"p\">[</span><span class=\"n\">best_candidate</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">toarray</span><span class=\"p\">()</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"n\">centers</span><span class=\"p\">[</span><span class=\"n\">c</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">X</span><span class=\"p\">[</span><span class=\"n\">best_candidate</span><span class=\"p\">]</span>\n        <span class=\"n\">current_pot</span> <span class=\"o\">=</span> <span class=\"n\">best_pot</span>\n        <span class=\"n\">closest_dist_sq</span> <span class=\"o\">=</span> <span class=\"n\">best_dist_sq</span>\n\n    <span class=\"k\">return</span> <span class=\"n\">centers</span>\n\n\n<span class=\"c1\">###############################################################################</span>\n<span class=\"c1\"># K-means batch estimation by EM (expectation maximization)</span>\n\n<span class=\"k\">def</span> <span class=\"nf\">_validate_center_shape</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">n_centers</span><span class=\"p\">,</span> <span class=\"n\">centers</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Check if centers is compatible with X and n_centers&quot;&quot;&quot;</span>\n    <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">centers</span><span class=\"p\">)</span> <span class=\"o\">!=</span> <span class=\"n\">n_centers</span><span class=\"p\">:</span>\n        <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s1\">&#39;The shape of the initial centers (</span><span class=\"si\">%s</span><span class=\"s1\">) &#39;</span>\n                         <span class=\"s1\">&#39;does not match the number of clusters </span><span class=\"si\">%i</span><span class=\"s1\">&#39;</span>\n                         <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">centers</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">,</span> <span class=\"n\">n_centers</span><span class=\"p\">))</span>\n    <span class=\"k\">if</span> <span class=\"n\">centers</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"o\">!=</span> <span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]:</span>\n        <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span>\n            <span class=\"s2\">&quot;The number of features of the initial centers </span><span class=\"si\">%s</span><span class=\"s2\"> &quot;</span>\n            <span class=\"s2\">&quot;does not match the number of features of the data </span><span class=\"si\">%s</span><span class=\"s2\">.&quot;</span>\n            <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">centers</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]))</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">_tolerance</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">tol</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Return a tolerance which is independent of the dataset&quot;&quot;&quot;</span>\n    <span class=\"k\">if</span> <span class=\"n\">sp</span><span class=\"o\">.</span><span class=\"n\">issparse</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">):</span>\n        <span class=\"n\">variances</span> <span class=\"o\">=</span> <span class=\"n\">mean_variance_axis</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">)[</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"n\">variances</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">var</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">mean</span><span class=\"p\">(</span><span class=\"n\">variances</span><span class=\"p\">)</span> <span class=\"o\">*</span> <span class=\"n\">tol</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">_labels_inertia_precompute_dense</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">x_squared_norms</span><span class=\"p\">,</span> <span class=\"n\">centers</span><span class=\"p\">,</span> <span class=\"n\">distances</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Compute labels and inertia using a full distance matrix.</span>\n\n<span class=\"sd\">    This will overwrite the &#39;distances&#39; array in-place.</span>\n\n<span class=\"sd\">    Parameters</span>\n<span class=\"sd\">    ----------</span>\n<span class=\"sd\">    X : numpy array, shape (n_sample, n_features)</span>\n<span class=\"sd\">        Input data.</span>\n\n<span class=\"sd\">    x_squared_norms : numpy array, shape (n_samples,)</span>\n<span class=\"sd\">        Precomputed squared norms of X.</span>\n\n<span class=\"sd\">    centers : numpy array, shape (n_clusters, n_features)</span>\n<span class=\"sd\">        Cluster centers which data is assigned to.</span>\n\n<span class=\"sd\">    distances : numpy array, shape (n_samples,)</span>\n<span class=\"sd\">        Pre-allocated array in which distances are stored.</span>\n\n<span class=\"sd\">    Returns</span>\n<span class=\"sd\">    -------</span>\n<span class=\"sd\">    labels : numpy array, dtype=np.int, shape (n_samples,)</span>\n<span class=\"sd\">        Indices of clusters that samples are assigned to.</span>\n\n<span class=\"sd\">    inertia : float</span>\n<span class=\"sd\">        Sum of distances of samples to their closest cluster center.</span>\n\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"n\">n_samples</span> <span class=\"o\">=</span> <span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n\n    <span class=\"c1\"># Breakup nearest neighbor distance computation into batches to prevent</span>\n    <span class=\"c1\"># memory blowup in the case of a large number of samples and clusters.</span>\n    <span class=\"c1\"># TODO: Once PR #7383 is merged use check_inputs=False in metric_kwargs.</span>\n    <span class=\"n\">labels</span><span class=\"p\">,</span> <span class=\"n\">mindist</span> <span class=\"o\">=</span> <span class=\"n\">pairwise_distances_argmin_min</span><span class=\"p\">(</span>\n        <span class=\"n\">X</span><span class=\"o\">=</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">Y</span><span class=\"o\">=</span><span class=\"n\">centers</span><span class=\"p\">,</span> <span class=\"n\">metric</span><span class=\"o\">=</span><span class=\"s1\">&#39;euclidean&#39;</span><span class=\"p\">,</span> <span class=\"n\">metric_kwargs</span><span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s1\">&#39;squared&#39;</span><span class=\"p\">:</span> <span class=\"kc\">True</span><span class=\"p\">})</span>\n    <span class=\"c1\"># cython k-means code assumes int32 inputs</span>\n    <span class=\"n\">labels</span> <span class=\"o\">=</span> <span class=\"n\">labels</span><span class=\"o\">.</span><span class=\"n\">astype</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">int32</span><span class=\"p\">)</span>\n    <span class=\"k\">if</span> <span class=\"n\">n_samples</span> <span class=\"o\">==</span> <span class=\"n\">distances</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]:</span>\n        <span class=\"c1\"># distances will be changed in-place</span>\n        <span class=\"n\">distances</span><span class=\"p\">[:]</span> <span class=\"o\">=</span> <span class=\"n\">mindist</span>\n    <span class=\"n\">inertia</span> <span class=\"o\">=</span> <span class=\"n\">mindist</span><span class=\"o\">.</span><span class=\"n\">sum</span><span class=\"p\">()</span>\n    <span class=\"k\">return</span> <span class=\"n\">labels</span><span class=\"p\">,</span> <span class=\"n\">inertia</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">_labels_inertia</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">x_squared_norms</span><span class=\"p\">,</span> <span class=\"n\">centers</span><span class=\"p\">,</span>\n                    <span class=\"n\">precompute_distances</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span> <span class=\"n\">distances</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;E step of the K-means EM algorithm.</span>\n\n<span class=\"sd\">    Compute the labels and the inertia of the given samples and centers.</span>\n<span class=\"sd\">    This will compute the distances in-place.</span>\n\n<span class=\"sd\">    Parameters</span>\n<span class=\"sd\">    ----------</span>\n<span class=\"sd\">    X : float64 array-like or CSR sparse matrix, shape (n_samples, n_features)</span>\n<span class=\"sd\">        The input samples to assign to the labels.</span>\n\n<span class=\"sd\">    x_squared_norms : array, shape (n_samples,)</span>\n<span class=\"sd\">        Precomputed squared euclidean norm of each data point, to speed up</span>\n<span class=\"sd\">        computations.</span>\n\n<span class=\"sd\">    centers : float array, shape (k, n_features)</span>\n<span class=\"sd\">        The cluster centers.</span>\n\n<span class=\"sd\">    precompute_distances : boolean, default: True</span>\n<span class=\"sd\">        Precompute distances (faster but takes more memory).</span>\n\n<span class=\"sd\">    distances : float array, shape (n_samples,)</span>\n<span class=\"sd\">        Pre-allocated array to be filled in with each sample&#39;s distance</span>\n<span class=\"sd\">        to the closest center.</span>\n\n<span class=\"sd\">    Returns</span>\n<span class=\"sd\">    -------</span>\n<span class=\"sd\">    labels : int array of shape(n)</span>\n<span class=\"sd\">        The resulting assignment</span>\n\n<span class=\"sd\">    inertia : float</span>\n<span class=\"sd\">        Sum of distances of samples to their closest cluster center.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"n\">n_samples</span> <span class=\"o\">=</span> <span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n    <span class=\"c1\"># set the default value of centers to -1 to be able to detect any anomaly</span>\n    <span class=\"c1\"># easily</span>\n    <span class=\"n\">labels</span> <span class=\"o\">=</span> <span class=\"o\">-</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">ones</span><span class=\"p\">(</span><span class=\"n\">n_samples</span><span class=\"p\">,</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">int32</span><span class=\"p\">)</span>\n    <span class=\"k\">if</span> <span class=\"n\">distances</span> <span class=\"ow\">is</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n        <span class=\"n\">distances</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">(</span><span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"p\">,),</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">dtype</span><span class=\"p\">)</span>\n    <span class=\"c1\"># distances will be changed in-place</span>\n    <span class=\"k\">if</span> <span class=\"n\">sp</span><span class=\"o\">.</span><span class=\"n\">issparse</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">):</span>\n        <span class=\"n\">inertia</span> <span class=\"o\">=</span> <span class=\"n\">_k_means</span><span class=\"o\">.</span><span class=\"n\">_assign_labels_csr</span><span class=\"p\">(</span>\n            <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">x_squared_norms</span><span class=\"p\">,</span> <span class=\"n\">centers</span><span class=\"p\">,</span> <span class=\"n\">labels</span><span class=\"p\">,</span> <span class=\"n\">distances</span><span class=\"o\">=</span><span class=\"n\">distances</span><span class=\"p\">)</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"k\">if</span> <span class=\"n\">precompute_distances</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"n\">_labels_inertia_precompute_dense</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">x_squared_norms</span><span class=\"p\">,</span>\n                                                    <span class=\"n\">centers</span><span class=\"p\">,</span> <span class=\"n\">distances</span><span class=\"p\">)</span>\n        <span class=\"n\">inertia</span> <span class=\"o\">=</span> <span class=\"n\">_k_means</span><span class=\"o\">.</span><span class=\"n\">_assign_labels_array</span><span class=\"p\">(</span>\n            <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">x_squared_norms</span><span class=\"p\">,</span> <span class=\"n\">centers</span><span class=\"p\">,</span> <span class=\"n\">labels</span><span class=\"p\">,</span> <span class=\"n\">distances</span><span class=\"o\">=</span><span class=\"n\">distances</span><span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">labels</span><span class=\"p\">,</span> <span class=\"n\">inertia</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">_init_centroids</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">k</span><span class=\"p\">,</span> <span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"n\">random_state</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">x_squared_norms</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span>\n                    <span class=\"n\">init_size</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Compute the initial centroids</span>\n\n<span class=\"sd\">    Parameters</span>\n<span class=\"sd\">    ----------</span>\n\n<span class=\"sd\">    X : array, shape (n_samples, n_features)</span>\n\n<span class=\"sd\">    k : int</span>\n<span class=\"sd\">        number of centroids</span>\n\n<span class=\"sd\">    init : {&#39;k-means++&#39;, &#39;random&#39; or ndarray or callable} optional</span>\n<span class=\"sd\">        Method for initialization</span>\n\n<span class=\"sd\">    random_state : int, RandomState instance or None, optional, default: None</span>\n<span class=\"sd\">        If int, random_state is the seed used by the random number generator;</span>\n<span class=\"sd\">        If RandomState instance, random_state is the random number generator;</span>\n<span class=\"sd\">        If None, the random number generator is the RandomState instance used</span>\n<span class=\"sd\">        by `np.random`.</span>\n\n<span class=\"sd\">    x_squared_norms :  array, shape (n_samples,), optional</span>\n<span class=\"sd\">        Squared euclidean norm of each data point. Pass it if you have it at</span>\n<span class=\"sd\">        hands already to avoid it being recomputed here. Default: None</span>\n\n<span class=\"sd\">    init_size : int, optional</span>\n<span class=\"sd\">        Number of samples to randomly sample for speeding up the</span>\n<span class=\"sd\">        initialization (sometimes at the expense of accuracy): the</span>\n<span class=\"sd\">        only algorithm is initialized by running a batch KMeans on a</span>\n<span class=\"sd\">        random subset of the data. This needs to be larger than k.</span>\n\n<span class=\"sd\">    Returns</span>\n<span class=\"sd\">    -------</span>\n<span class=\"sd\">    centers : array, shape(k, n_features)</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"n\">random_state</span> <span class=\"o\">=</span> <span class=\"n\">check_random_state</span><span class=\"p\">(</span><span class=\"n\">random_state</span><span class=\"p\">)</span>\n    <span class=\"n\">n_samples</span> <span class=\"o\">=</span> <span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n\n    <span class=\"k\">if</span> <span class=\"n\">x_squared_norms</span> <span class=\"ow\">is</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n        <span class=\"n\">x_squared_norms</span> <span class=\"o\">=</span> <span class=\"n\">row_norms</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">squared</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n\n    <span class=\"k\">if</span> <span class=\"n\">init_size</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span> <span class=\"ow\">and</span> <span class=\"n\">init_size</span> <span class=\"o\">&lt;</span> <span class=\"n\">n_samples</span><span class=\"p\">:</span>\n        <span class=\"k\">if</span> <span class=\"n\">init_size</span> <span class=\"o\">&lt;</span> <span class=\"n\">k</span><span class=\"p\">:</span>\n            <span class=\"n\">warnings</span><span class=\"o\">.</span><span class=\"n\">warn</span><span class=\"p\">(</span>\n                <span class=\"s2\">&quot;init_size=</span><span class=\"si\">%d</span><span class=\"s2\"> should be larger than k=</span><span class=\"si\">%d</span><span class=\"s2\">. &quot;</span>\n                <span class=\"s2\">&quot;Setting it to 3*k&quot;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">init_size</span><span class=\"p\">,</span> <span class=\"n\">k</span><span class=\"p\">),</span>\n                <span class=\"ne\">RuntimeWarning</span><span class=\"p\">,</span> <span class=\"n\">stacklevel</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n            <span class=\"n\">init_size</span> <span class=\"o\">=</span> <span class=\"mi\">3</span> <span class=\"o\">*</span> <span class=\"n\">k</span>\n        <span class=\"n\">init_indices</span> <span class=\"o\">=</span> <span class=\"n\">random_state</span><span class=\"o\">.</span><span class=\"n\">randint</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">n_samples</span><span class=\"p\">,</span> <span class=\"n\">init_size</span><span class=\"p\">)</span>\n        <span class=\"n\">X</span> <span class=\"o\">=</span> <span class=\"n\">X</span><span class=\"p\">[</span><span class=\"n\">init_indices</span><span class=\"p\">]</span>\n        <span class=\"n\">x_squared_norms</span> <span class=\"o\">=</span> <span class=\"n\">x_squared_norms</span><span class=\"p\">[</span><span class=\"n\">init_indices</span><span class=\"p\">]</span>\n        <span class=\"n\">n_samples</span> <span class=\"o\">=</span> <span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n    <span class=\"k\">elif</span> <span class=\"n\">n_samples</span> <span class=\"o\">&lt;</span> <span class=\"n\">k</span><span class=\"p\">:</span>\n        <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span>\n            <span class=\"s2\">&quot;n_samples=</span><span class=\"si\">%d</span><span class=\"s2\"> should be larger than k=</span><span class=\"si\">%d</span><span class=\"s2\">&quot;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">n_samples</span><span class=\"p\">,</span> <span class=\"n\">k</span><span class=\"p\">))</span>\n\n    <span class=\"k\">if</span> <span class=\"nb\">isinstance</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"n\">string_types</span><span class=\"p\">)</span> <span class=\"ow\">and</span> <span class=\"n\">init</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;k-means++&#39;</span><span class=\"p\">:</span>\n        <span class=\"n\">centers</span> <span class=\"o\">=</span> <span class=\"n\">_k_init</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">k</span><span class=\"p\">,</span> <span class=\"n\">random_state</span><span class=\"o\">=</span><span class=\"n\">random_state</span><span class=\"p\">,</span>\n                          <span class=\"n\">x_squared_norms</span><span class=\"o\">=</span><span class=\"n\">x_squared_norms</span><span class=\"p\">)</span>\n    <span class=\"k\">elif</span> <span class=\"nb\">isinstance</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"n\">string_types</span><span class=\"p\">)</span> <span class=\"ow\">and</span> <span class=\"n\">init</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;random&#39;</span><span class=\"p\">:</span>\n        <span class=\"n\">seeds</span> <span class=\"o\">=</span> <span class=\"n\">random_state</span><span class=\"o\">.</span><span class=\"n\">permutation</span><span class=\"p\">(</span><span class=\"n\">n_samples</span><span class=\"p\">)[:</span><span class=\"n\">k</span><span class=\"p\">]</span>\n        <span class=\"n\">centers</span> <span class=\"o\">=</span> <span class=\"n\">X</span><span class=\"p\">[</span><span class=\"n\">seeds</span><span class=\"p\">]</span>\n    <span class=\"k\">elif</span> <span class=\"nb\">hasattr</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"s1\">&#39;__array__&#39;</span><span class=\"p\">):</span>\n        <span class=\"c1\"># ensure that the centers have the same dtype as X</span>\n        <span class=\"c1\"># this is a requirement of fused types of cython</span>\n        <span class=\"n\">centers</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">dtype</span><span class=\"p\">)</span>\n    <span class=\"k\">elif</span> <span class=\"n\">callable</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"p\">):</span>\n        <span class=\"n\">centers</span> <span class=\"o\">=</span> <span class=\"n\">init</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">k</span><span class=\"p\">,</span> <span class=\"n\">random_state</span><span class=\"o\">=</span><span class=\"n\">random_state</span><span class=\"p\">)</span>\n        <span class=\"n\">centers</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">asarray</span><span class=\"p\">(</span><span class=\"n\">centers</span><span class=\"p\">,</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">dtype</span><span class=\"p\">)</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s2\">&quot;the init parameter for the k-means should &quot;</span>\n                         <span class=\"s2\">&quot;be &#39;k-means++&#39; or &#39;random&#39; or an ndarray, &quot;</span>\n                         <span class=\"s2\">&quot;&#39;</span><span class=\"si\">%s</span><span class=\"s2\">&#39; (type &#39;</span><span class=\"si\">%s</span><span class=\"s2\">&#39;) was passed.&quot;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"nb\">type</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"p\">)))</span>\n\n    <span class=\"k\">if</span> <span class=\"n\">sp</span><span class=\"o\">.</span><span class=\"n\">issparse</span><span class=\"p\">(</span><span class=\"n\">centers</span><span class=\"p\">):</span>\n        <span class=\"n\">centers</span> <span class=\"o\">=</span> <span class=\"n\">centers</span><span class=\"o\">.</span><span class=\"n\">toarray</span><span class=\"p\">()</span>\n\n    <span class=\"n\">_validate_center_shape</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">k</span><span class=\"p\">,</span> <span class=\"n\">centers</span><span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">centers</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">KMeans</span><span class=\"p\">(</span><span class=\"n\">BaseEstimator</span><span class=\"p\">,</span> <span class=\"n\">ClusterMixin</span><span class=\"p\">,</span> <span class=\"n\">TransformerMixin</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;K-Means clustering</span>\n\n<span class=\"sd\">    Read more in the :ref:`User Guide &lt;k_means&gt;`.</span>\n\n<span class=\"sd\">    Parameters</span>\n<span class=\"sd\">    ----------</span>\n\n<span class=\"sd\">    n_clusters : int, optional, default: 8</span>\n<span class=\"sd\">        The number of clusters to form as well as the number of</span>\n<span class=\"sd\">        centroids to generate.</span>\n\n<span class=\"sd\">    init : {&#39;k-means++&#39;, &#39;random&#39; or an ndarray}</span>\n<span class=\"sd\">        Method for initialization, defaults to &#39;k-means++&#39;:</span>\n\n<span class=\"sd\">        &#39;k-means++&#39; : selects initial cluster centers for k-mean</span>\n<span class=\"sd\">        clustering in a smart way to speed up convergence. See section</span>\n<span class=\"sd\">        Notes in k_init for more details.</span>\n\n<span class=\"sd\">        &#39;random&#39;: choose k observations (rows) at random from data for</span>\n<span class=\"sd\">        the initial centroids.</span>\n\n<span class=\"sd\">        If an ndarray is passed, it should be of shape (n_clusters, n_features)</span>\n<span class=\"sd\">        and gives the initial centers.</span>\n\n<span class=\"sd\">    n_init : int, default: 10</span>\n<span class=\"sd\">        Number of time the k-means algorithm will be run with different</span>\n<span class=\"sd\">        centroid seeds. The final results will be the best output of</span>\n<span class=\"sd\">        n_init consecutive runs in terms of inertia.</span>\n\n<span class=\"sd\">    max_iter : int, default: 300</span>\n<span class=\"sd\">        Maximum number of iterations of the k-means algorithm for a</span>\n<span class=\"sd\">        single run.</span>\n\n<span class=\"sd\">    tol : float, default: 1e-4</span>\n<span class=\"sd\">        Relative tolerance with regards to inertia to declare convergence</span>\n\n<span class=\"sd\">    precompute_distances : {&#39;auto&#39;, True, False}</span>\n<span class=\"sd\">        Precompute distances (faster but takes more memory).</span>\n\n<span class=\"sd\">        &#39;auto&#39; : do not precompute distances if n_samples * n_clusters &gt; 12</span>\n<span class=\"sd\">        million. This corresponds to about 100MB overhead per job using</span>\n<span class=\"sd\">        double precision.</span>\n\n<span class=\"sd\">        True : always precompute distances</span>\n\n<span class=\"sd\">        False : never precompute distances</span>\n\n<span class=\"sd\">    verbose : int, default 0</span>\n<span class=\"sd\">        Verbosity mode.</span>\n\n<span class=\"sd\">    random_state : int, RandomState instance or None, optional, default: None</span>\n<span class=\"sd\">        If int, random_state is the seed used by the random number generator;</span>\n<span class=\"sd\">        If RandomState instance, random_state is the random number generator;</span>\n<span class=\"sd\">        If None, the random number generator is the RandomState instance used</span>\n<span class=\"sd\">        by `np.random`.</span>\n\n<span class=\"sd\">    copy_x : boolean, default True</span>\n<span class=\"sd\">        When pre-computing distances it is more numerically accurate to center</span>\n<span class=\"sd\">        the data first.  If copy_x is True, then the original data is not</span>\n<span class=\"sd\">        modified.  If False, the original data is modified, and put back before</span>\n<span class=\"sd\">        the function returns, but small numerical differences may be introduced</span>\n<span class=\"sd\">        by subtracting and then adding the data mean.</span>\n\n<span class=\"sd\">    n_jobs : int</span>\n<span class=\"sd\">        The number of jobs to use for the computation. This works by computing</span>\n<span class=\"sd\">        each of the n_init runs in parallel.</span>\n\n<span class=\"sd\">        If -1 all CPUs are used. If 1 is given, no parallel computing code is</span>\n<span class=\"sd\">        used at all, which is useful for debugging. For n_jobs below -1,</span>\n<span class=\"sd\">        (n_cpus + 1 + n_jobs) are used. Thus for n_jobs = -2, all CPUs but one</span>\n<span class=\"sd\">        are used.</span>\n\n<span class=\"sd\">    algorithm : &quot;auto&quot;, &quot;full&quot; or &quot;elkan&quot;, default=&quot;auto&quot;</span>\n<span class=\"sd\">        K-means algorithm to use. The classical EM-style algorithm is &quot;full&quot;.</span>\n<span class=\"sd\">        The &quot;elkan&quot; variation is more efficient by using the triangle</span>\n<span class=\"sd\">        inequality, but currently doesn&#39;t support sparse data. &quot;auto&quot; chooses</span>\n<span class=\"sd\">        &quot;elkan&quot; for dense data and &quot;full&quot; for sparse data.</span>\n\n<span class=\"sd\">    Attributes</span>\n<span class=\"sd\">    ----------</span>\n<span class=\"sd\">    cluster_centers_ : array, [n_clusters, n_features]</span>\n<span class=\"sd\">        Coordinates of cluster centers</span>\n\n<span class=\"sd\">    labels_ :</span>\n<span class=\"sd\">        Labels of each point</span>\n\n<span class=\"sd\">    inertia_ : float</span>\n<span class=\"sd\">        Sum of distances of samples to their closest cluster center.</span>\n\n<span class=\"sd\">    Examples</span>\n<span class=\"sd\">    --------</span>\n\n<span class=\"sd\">    &gt;&gt;&gt; from sklearn.cluster import KMeans</span>\n<span class=\"sd\">    &gt;&gt;&gt; import numpy as np</span>\n<span class=\"sd\">    &gt;&gt;&gt; X = np.array([[1, 2], [1, 4], [1, 0],</span>\n<span class=\"sd\">    ...               [4, 2], [4, 4], [4, 0]])</span>\n<span class=\"sd\">    &gt;&gt;&gt; kmeans = KMeans(n_clusters=2, random_state=0).fit(X)</span>\n<span class=\"sd\">    &gt;&gt;&gt; kmeans.labels_</span>\n<span class=\"sd\">    array([0, 0, 0, 1, 1, 1], dtype=int32)</span>\n<span class=\"sd\">    &gt;&gt;&gt; kmeans.predict([[0, 0], [4, 4]])</span>\n<span class=\"sd\">    array([0, 1], dtype=int32)</span>\n<span class=\"sd\">    &gt;&gt;&gt; kmeans.cluster_centers_</span>\n<span class=\"sd\">    array([[ 1.,  2.],</span>\n<span class=\"sd\">           [ 4.,  2.]])</span>\n\n<span class=\"sd\">    See also</span>\n<span class=\"sd\">    --------</span>\n\n<span class=\"sd\">    MiniBatchKMeans</span>\n<span class=\"sd\">        Alternative online implementation that does incremental updates</span>\n<span class=\"sd\">        of the centers positions using mini-batches.</span>\n<span class=\"sd\">        For large scale learning (say n_samples &gt; 10k) MiniBatchKMeans is</span>\n<span class=\"sd\">        probably much faster than the default batch implementation.</span>\n\n<span class=\"sd\">    Notes</span>\n<span class=\"sd\">    ------</span>\n<span class=\"sd\">    The k-means problem is solved using Lloyd&#39;s algorithm.</span>\n\n<span class=\"sd\">    The average complexity is given by O(k n T), were n is the number of</span>\n<span class=\"sd\">    samples and T is the number of iteration.</span>\n\n<span class=\"sd\">    The worst case complexity is given by O(n^(k+2/p)) with</span>\n<span class=\"sd\">    n = n_samples, p = n_features. (D. Arthur and S. Vassilvitskii,</span>\n<span class=\"sd\">    &#39;How slow is the k-means method?&#39; SoCG2006)</span>\n\n<span class=\"sd\">    In practice, the k-means algorithm is very fast (one of the fastest</span>\n<span class=\"sd\">    clustering algorithms available), but it falls in local minima. That&#39;s why</span>\n<span class=\"sd\">    it can be useful to restart it several times.</span>\n\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">n_clusters</span><span class=\"o\">=</span><span class=\"mi\">8</span><span class=\"p\">,</span> <span class=\"n\">init</span><span class=\"o\">=</span><span class=\"s1\">&#39;k-means++&#39;</span><span class=\"p\">,</span> <span class=\"n\">n_init</span><span class=\"o\">=</span><span class=\"mi\">10</span><span class=\"p\">,</span>\n                 <span class=\"n\">max_iter</span><span class=\"o\">=</span><span class=\"mi\">300</span><span class=\"p\">,</span> <span class=\"n\">tol</span><span class=\"o\">=</span><span class=\"mf\">1e-4</span><span class=\"p\">,</span> <span class=\"n\">precompute_distances</span><span class=\"o\">=</span><span class=\"s1\">&#39;auto&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">verbose</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">random_state</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">copy_x</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span>\n                 <span class=\"n\">n_jobs</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">algorithm</span><span class=\"o\">=</span><span class=\"s1\">&#39;auto&#39;</span><span class=\"p\">):</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">n_clusters</span> <span class=\"o\">=</span> <span class=\"n\">n_clusters</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">init</span> <span class=\"o\">=</span> <span class=\"n\">init</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">max_iter</span> <span class=\"o\">=</span> <span class=\"n\">max_iter</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">tol</span> <span class=\"o\">=</span> <span class=\"n\">tol</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">precompute_distances</span> <span class=\"o\">=</span> <span class=\"n\">precompute_distances</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">n_init</span> <span class=\"o\">=</span> <span class=\"n\">n_init</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">verbose</span> <span class=\"o\">=</span> <span class=\"n\">verbose</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">random_state</span> <span class=\"o\">=</span> <span class=\"n\">random_state</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">copy_x</span> <span class=\"o\">=</span> <span class=\"n\">copy_x</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">n_jobs</span> <span class=\"o\">=</span> <span class=\"n\">n_jobs</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">algorithm</span> <span class=\"o\">=</span> <span class=\"n\">algorithm</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">_check_fit_data</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Verify that the number of samples given is larger than k&quot;&quot;&quot;</span>\n        <span class=\"n\">X</span> <span class=\"o\">=</span> <span class=\"n\">check_array</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">accept_sparse</span><span class=\"o\">=</span><span class=\"s1\">&#39;csr&#39;</span><span class=\"p\">,</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float64</span><span class=\"p\">,</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">])</span>\n        <span class=\"k\">if</span> <span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">&lt;</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">n_clusters</span><span class=\"p\">:</span>\n            <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s2\">&quot;n_samples=</span><span class=\"si\">%d</span><span class=\"s2\"> should be &gt;= n_clusters=</span><span class=\"si\">%d</span><span class=\"s2\">&quot;</span> <span class=\"o\">%</span> <span class=\"p\">(</span>\n                <span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">n_clusters</span><span class=\"p\">))</span>\n        <span class=\"k\">return</span> <span class=\"n\">X</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">_check_test_data</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">):</span>\n        <span class=\"n\">X</span> <span class=\"o\">=</span> <span class=\"n\">check_array</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">accept_sparse</span><span class=\"o\">=</span><span class=\"s1\">&#39;csr&#39;</span><span class=\"p\">,</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">FLOAT_DTYPES</span><span class=\"p\">)</span>\n        <span class=\"n\">n_samples</span><span class=\"p\">,</span> <span class=\"n\">n_features</span> <span class=\"o\">=</span> <span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">shape</span>\n        <span class=\"n\">expected_n_features</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">cluster_centers_</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n        <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"n\">n_features</span> <span class=\"o\">==</span> <span class=\"n\">expected_n_features</span><span class=\"p\">:</span>\n            <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s2\">&quot;Incorrect number of features. &quot;</span>\n                             <span class=\"s2\">&quot;Got </span><span class=\"si\">%d</span><span class=\"s2\"> features, expected </span><span class=\"si\">%d</span><span class=\"s2\">&quot;</span> <span class=\"o\">%</span> <span class=\"p\">(</span>\n                                 <span class=\"n\">n_features</span><span class=\"p\">,</span> <span class=\"n\">expected_n_features</span><span class=\"p\">))</span>\n\n        <span class=\"k\">return</span> <span class=\"n\">X</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">fit</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Compute k-means clustering.</span>\n\n<span class=\"sd\">        Parameters</span>\n<span class=\"sd\">        ----------</span>\n<span class=\"sd\">        X : array-like or sparse matrix, shape=(n_samples, n_features)</span>\n<span class=\"sd\">            Training instances to cluster.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"c1\"># Added to remove scikit-learn internal dependenceies</span>\n        <span class=\"k\">raise</span> <span class=\"bp\">NotImplemented</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">fit_predict</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Compute cluster centers and predict cluster index for each sample.</span>\n\n<span class=\"sd\">        Convenience method; equivalent to calling fit(X) followed by</span>\n<span class=\"sd\">        predict(X).</span>\n\n<span class=\"sd\">        Parameters</span>\n<span class=\"sd\">        ----------</span>\n<span class=\"sd\">        X : {array-like, sparse matrix}, shape = [n_samples, n_features]</span>\n<span class=\"sd\">            New data to transform.</span>\n\n<span class=\"sd\">        Returns</span>\n<span class=\"sd\">        -------</span>\n<span class=\"sd\">        labels : array, shape [n_samples,]</span>\n<span class=\"sd\">            Index of the cluster each sample belongs to.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">fit</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">labels_</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">fit_transform</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Compute clustering and transform X to cluster-distance space.</span>\n\n<span class=\"sd\">        Equivalent to fit(X).transform(X), but more efficiently implemented.</span>\n\n<span class=\"sd\">        Parameters</span>\n<span class=\"sd\">        ----------</span>\n<span class=\"sd\">        X : {array-like, sparse matrix}, shape = [n_samples, n_features]</span>\n<span class=\"sd\">            New data to transform.</span>\n\n<span class=\"sd\">        Returns</span>\n<span class=\"sd\">        -------</span>\n<span class=\"sd\">        X_new : array, shape [n_samples, k]</span>\n<span class=\"sd\">            X transformed in the new space.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"c1\"># Currently, this just skips a copy of the data if it is not in</span>\n        <span class=\"c1\"># np.array or CSR format already.</span>\n        <span class=\"c1\"># XXX This skips _check_test_data, which may change the dtype;</span>\n        <span class=\"c1\"># we should refactor the input validation.</span>\n        <span class=\"n\">X</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_check_fit_data</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">fit</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">_transform</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">transform</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Transform X to a cluster-distance space.</span>\n\n<span class=\"sd\">        In the new space, each dimension is the distance to the cluster</span>\n<span class=\"sd\">        centers.  Note that even if X is sparse, the array returned by</span>\n<span class=\"sd\">        `transform` will typically be dense.</span>\n\n<span class=\"sd\">        Parameters</span>\n<span class=\"sd\">        ----------</span>\n<span class=\"sd\">        X : {array-like, sparse matrix}, shape = [n_samples, n_features]</span>\n<span class=\"sd\">            New data to transform.</span>\n\n<span class=\"sd\">        Returns</span>\n<span class=\"sd\">        -------</span>\n<span class=\"sd\">        X_new : array, shape [n_samples, k]</span>\n<span class=\"sd\">            X transformed in the new space.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"n\">check_is_fitted</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"s1\">&#39;cluster_centers_&#39;</span><span class=\"p\">)</span>\n\n        <span class=\"n\">X</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_check_test_data</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_transform</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">_transform</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;guts of transform method; no input validation&quot;&quot;&quot;</span>\n        <span class=\"k\">return</span> <span class=\"n\">euclidean_distances</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">cluster_centers_</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">predict</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Predict the closest cluster each sample in X belongs to.</span>\n\n<span class=\"sd\">        In the vector quantization literature, `cluster_centers_` is called</span>\n<span class=\"sd\">        the code book and each value returned by `predict` is the index of</span>\n<span class=\"sd\">        the closest code in the code book.</span>\n\n<span class=\"sd\">        Parameters</span>\n<span class=\"sd\">        ----------</span>\n<span class=\"sd\">        X : {array-like, sparse matrix}, shape = [n_samples, n_features]</span>\n<span class=\"sd\">            New data to predict.</span>\n\n<span class=\"sd\">        Returns</span>\n<span class=\"sd\">        -------</span>\n<span class=\"sd\">        labels : array, shape [n_samples,]</span>\n<span class=\"sd\">            Index of the cluster each sample belongs to.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"n\">check_is_fitted</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"s1\">&#39;cluster_centers_&#39;</span><span class=\"p\">)</span>\n\n        <span class=\"n\">X</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_check_test_data</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span>\n        <span class=\"n\">x_squared_norms</span> <span class=\"o\">=</span> <span class=\"n\">row_norms</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">squared</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"n\">_labels_inertia</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">x_squared_norms</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">cluster_centers_</span><span class=\"p\">)[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">score</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Opposite of the value of X on the K-means objective.</span>\n\n<span class=\"sd\">        Parameters</span>\n<span class=\"sd\">        ----------</span>\n<span class=\"sd\">        X : {array-like, sparse matrix}, shape = [n_samples, n_features]</span>\n<span class=\"sd\">            New data.</span>\n\n<span class=\"sd\">        Returns</span>\n<span class=\"sd\">        -------</span>\n<span class=\"sd\">        score : float</span>\n<span class=\"sd\">            Opposite of the value of X on the K-means objective.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"n\">check_is_fitted</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"s1\">&#39;cluster_centers_&#39;</span><span class=\"p\">)</span>\n\n        <span class=\"n\">X</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_check_test_data</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span>\n        <span class=\"n\">x_squared_norms</span> <span class=\"o\">=</span> <span class=\"n\">row_norms</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">squared</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"o\">-</span><span class=\"n\">_labels_inertia</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">x_squared_norms</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">cluster_centers_</span><span class=\"p\">)[</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n\n\n</pre></div>\n\n          </div>\n          \n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<h1 class=\"logo\"><a href=\"../../../index.html\">k-means-constrained</a></h1>\n\n\n\n\n\n\n\n\n<h3>Navigation</h3>\n\n<div class=\"relations\">\n<h3>Related Topics</h3>\n<ul>\n  <li><a href=\"../../../index.html\">Documentation overview</a><ul>\n  <li><a href=\"../../index.html\">Module code</a><ul>\n  </ul></li>\n  </ul></li>\n</ul>\n</div>\n<div id=\"searchbox\" style=\"display: none\" role=\"search\">\n  <h3 id=\"searchlabel\">Quick search</h3>\n    <div class=\"searchformwrapper\">\n    <form class=\"search\" action=\"../../../search.html\" method=\"get\">\n      <input type=\"text\" name=\"q\" aria-labelledby=\"searchlabel\" />\n      <input type=\"submit\" value=\"Go\" />\n    </form>\n    </div>\n</div>\n<script type=\"text/javascript\">$('#searchbox').show(0);</script>\n\n\n\n\n\n\n\n\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"footer\">\n      &copy;2020, Josh Levy-Kramer.\n      \n      |\n      Powered by <a href=\"http://sphinx-doc.org/\">Sphinx 2.2.0</a>\n      &amp; <a href=\"https://github.com/bitprophet/alabaster\">Alabaster 0.7.12</a>\n      \n    </div>\n\n    \n\n    \n  </body>\n</html>"
  },
  {
    "path": "docs/_modules/k_means_constrained/sklearn_import/base.html",
    "content": "\n\n<!DOCTYPE html>\n<html class=\"writer-html5\" lang=\"en\" >\n<head>\n  <meta charset=\"utf-8\" />\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n  \n  <title>k_means_constrained.sklearn_import.base &mdash; k-means-constrained 0.5.1 documentation</title>\n  \n\n  \n  <link rel=\"stylesheet\" href=\"../../../_static/css/theme.css\" type=\"text/css\" />\n  <link rel=\"stylesheet\" href=\"../../../_static/pygments.css\" type=\"text/css\" />\n  <link rel=\"stylesheet\" href=\"../../../_static/pygments.css\" type=\"text/css\" />\n  <link rel=\"stylesheet\" href=\"../../../_static/css/theme.css\" type=\"text/css\" />\n\n  \n  \n\n  \n  \n\n  \n\n  \n  <!--[if lt IE 9]>\n    <script src=\"../../../_static/js/html5shiv.min.js\"></script>\n  <![endif]-->\n  \n    \n      <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../../\" src=\"../../../_static/documentation_options.js\"></script>\n        <script data-url_root=\"../../../\" id=\"documentation_options\" src=\"../../../_static/documentation_options.js\"></script>\n        <script src=\"../../../_static/jquery.js\"></script>\n        <script src=\"../../../_static/underscore.js\"></script>\n        <script src=\"../../../_static/doctools.js\"></script>\n    \n    <script type=\"text/javascript\" src=\"../../../_static/js/theme.js\"></script>\n\n    \n    <link rel=\"index\" title=\"Index\" href=\"../../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../../search.html\" /> \n</head>\n\n<body class=\"wy-body-for-nav\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\" >\n          \n\n          \n            <a href=\"../../../index.html\" class=\"icon icon-home\"> k-means-constrained\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"../../../search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        \n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n              \n            \n            \n              <!-- Local TOC -->\n              <div class=\"local-toc\"></div>\n            \n          \n        </div>\n        \n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"../../../index.html\">k-means-constrained</a>\n        \n      </nav>\n\n\n      <div class=\"wy-nav-content\">\n        \n        <div class=\"rst-content\">\n        \n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"../../../index.html\" class=\"icon icon-home\"></a> &raquo;</li>\n        \n          <li><a href=\"../../index.html\">Module code</a> &raquo;</li>\n        \n      <li>k_means_constrained.sklearn_import.base</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n      </li>\n    \n  </ul>\n\n  \n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <h1>Source code for k_means_constrained.sklearn_import.base</h1><div class=\"highlight\"><pre>\n<span></span><span class=\"kn\">import</span> <span class=\"nn\">warnings</span>\n<span class=\"kn\">from</span> <span class=\"nn\">collections</span> <span class=\"kn\">import</span> <span class=\"n\">defaultdict</span>\n\n<span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n<span class=\"kn\">import</span> <span class=\"nn\">six</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">k_means_constrained.sklearn_import</span> <span class=\"kn\">import</span> <span class=\"n\">__version__</span>\n<span class=\"kn\">from</span> <span class=\"nn\">k_means_constrained.sklearn_import.funcsigs</span> <span class=\"kn\">import</span> <span class=\"n\">signature</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">BaseEstimator</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Base class for all estimators in scikit-learn</span>\n\n<span class=\"sd\">    Notes</span>\n<span class=\"sd\">    -----</span>\n<span class=\"sd\">    All estimators should specify all the parameters that can be set</span>\n<span class=\"sd\">    at the class level in their ``__init__`` as explicit keyword</span>\n<span class=\"sd\">    arguments (no ``*args`` or ``**kwargs``).</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n\n    <span class=\"nd\">@classmethod</span>\n    <span class=\"k\">def</span> <span class=\"nf\">_get_param_names</span><span class=\"p\">(</span><span class=\"bp\">cls</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Get parameter names for the estimator&quot;&quot;&quot;</span>\n        <span class=\"c1\"># fetch the constructor or the original constructor before</span>\n        <span class=\"c1\"># deprecation wrapping if any</span>\n        <span class=\"n\">init</span> <span class=\"o\">=</span> <span class=\"nb\">getattr</span><span class=\"p\">(</span><span class=\"bp\">cls</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">,</span> <span class=\"s1\">&#39;deprecated_original&#39;</span><span class=\"p\">,</span> <span class=\"bp\">cls</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"n\">init</span> <span class=\"ow\">is</span> <span class=\"nb\">object</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">:</span>\n            <span class=\"c1\"># No explicit constructor to introspect</span>\n            <span class=\"k\">return</span> <span class=\"p\">[]</span>\n\n        <span class=\"c1\"># introspect the constructor arguments to find the model parameters</span>\n        <span class=\"c1\"># to represent</span>\n        <span class=\"n\">init_signature</span> <span class=\"o\">=</span> <span class=\"n\">signature</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"p\">)</span>\n        <span class=\"c1\"># Consider the constructor parameters excluding &#39;self&#39;</span>\n        <span class=\"n\">parameters</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">p</span> <span class=\"k\">for</span> <span class=\"n\">p</span> <span class=\"ow\">in</span> <span class=\"n\">init_signature</span><span class=\"o\">.</span><span class=\"n\">parameters</span><span class=\"o\">.</span><span class=\"n\">values</span><span class=\"p\">()</span>\n                      <span class=\"k\">if</span> <span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">name</span> <span class=\"o\">!=</span> <span class=\"s1\">&#39;self&#39;</span> <span class=\"ow\">and</span> <span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">kind</span> <span class=\"o\">!=</span> <span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">VAR_KEYWORD</span><span class=\"p\">]</span>\n        <span class=\"k\">for</span> <span class=\"n\">p</span> <span class=\"ow\">in</span> <span class=\"n\">parameters</span><span class=\"p\">:</span>\n            <span class=\"k\">if</span> <span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">kind</span> <span class=\"o\">==</span> <span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">VAR_POSITIONAL</span><span class=\"p\">:</span>\n                <span class=\"k\">raise</span> <span class=\"ne\">RuntimeError</span><span class=\"p\">(</span><span class=\"s2\">&quot;scikit-learn estimators should always &quot;</span>\n                                   <span class=\"s2\">&quot;specify their parameters in the signature&quot;</span>\n                                   <span class=\"s2\">&quot; of their __init__ (no varargs).&quot;</span>\n                                   <span class=\"s2\">&quot; </span><span class=\"si\">%s</span><span class=\"s2\"> with constructor </span><span class=\"si\">%s</span><span class=\"s2\"> doesn&#39;t &quot;</span>\n                                   <span class=\"s2\">&quot; follow this convention.&quot;</span>\n                                   <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"bp\">cls</span><span class=\"p\">,</span> <span class=\"n\">init_signature</span><span class=\"p\">))</span>\n        <span class=\"c1\"># Extract and sort argument names excluding &#39;self&#39;</span>\n        <span class=\"k\">return</span> <span class=\"nb\">sorted</span><span class=\"p\">([</span><span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">name</span> <span class=\"k\">for</span> <span class=\"n\">p</span> <span class=\"ow\">in</span> <span class=\"n\">parameters</span><span class=\"p\">])</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">get_params</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">deep</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Get parameters for this estimator.</span>\n\n<span class=\"sd\">        Parameters</span>\n<span class=\"sd\">        ----------</span>\n<span class=\"sd\">        deep : boolean, optional</span>\n<span class=\"sd\">            If True, will return the parameters for this estimator and</span>\n<span class=\"sd\">            contained subobjects that are estimators.</span>\n\n<span class=\"sd\">        Returns</span>\n<span class=\"sd\">        -------</span>\n<span class=\"sd\">        params : mapping of string to any</span>\n<span class=\"sd\">            Parameter names mapped to their values.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"n\">out</span> <span class=\"o\">=</span> <span class=\"nb\">dict</span><span class=\"p\">()</span>\n        <span class=\"k\">for</span> <span class=\"n\">key</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_get_param_names</span><span class=\"p\">():</span>\n            <span class=\"c1\"># We need deprecation warnings to always be on in order to</span>\n            <span class=\"c1\"># catch deprecated param values.</span>\n            <span class=\"c1\"># This is set in utils/__init__.py but it gets overwritten</span>\n            <span class=\"c1\"># when running under python3 somehow.</span>\n            <span class=\"n\">warnings</span><span class=\"o\">.</span><span class=\"n\">simplefilter</span><span class=\"p\">(</span><span class=\"s2\">&quot;always&quot;</span><span class=\"p\">,</span> <span class=\"ne\">DeprecationWarning</span><span class=\"p\">)</span>\n            <span class=\"k\">try</span><span class=\"p\">:</span>\n                <span class=\"k\">with</span> <span class=\"n\">warnings</span><span class=\"o\">.</span><span class=\"n\">catch_warnings</span><span class=\"p\">(</span><span class=\"n\">record</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span> <span class=\"k\">as</span> <span class=\"n\">w</span><span class=\"p\">:</span>\n                    <span class=\"n\">value</span> <span class=\"o\">=</span> <span class=\"nb\">getattr</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">key</span><span class=\"p\">,</span> <span class=\"kc\">None</span><span class=\"p\">)</span>\n                <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">w</span><span class=\"p\">)</span> <span class=\"ow\">and</span> <span class=\"n\">w</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">category</span> <span class=\"o\">==</span> <span class=\"ne\">DeprecationWarning</span><span class=\"p\">:</span>\n                    <span class=\"c1\"># if the parameter is deprecated, don&#39;t show it</span>\n                    <span class=\"k\">continue</span>\n            <span class=\"k\">finally</span><span class=\"p\">:</span>\n                <span class=\"n\">warnings</span><span class=\"o\">.</span><span class=\"n\">filters</span><span class=\"o\">.</span><span class=\"n\">pop</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"p\">)</span>\n\n            <span class=\"c1\"># XXX: should we rather test if instance of estimator?</span>\n            <span class=\"k\">if</span> <span class=\"n\">deep</span> <span class=\"ow\">and</span> <span class=\"nb\">hasattr</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">,</span> <span class=\"s1\">&#39;get_params&#39;</span><span class=\"p\">):</span>\n                <span class=\"n\">deep_items</span> <span class=\"o\">=</span> <span class=\"n\">value</span><span class=\"o\">.</span><span class=\"n\">get_params</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">items</span><span class=\"p\">()</span>\n                <span class=\"n\">out</span><span class=\"o\">.</span><span class=\"n\">update</span><span class=\"p\">((</span><span class=\"n\">key</span> <span class=\"o\">+</span> <span class=\"s1\">&#39;__&#39;</span> <span class=\"o\">+</span> <span class=\"n\">k</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"p\">)</span> <span class=\"k\">for</span> <span class=\"n\">k</span><span class=\"p\">,</span> <span class=\"n\">val</span> <span class=\"ow\">in</span> <span class=\"n\">deep_items</span><span class=\"p\">)</span>\n            <span class=\"n\">out</span><span class=\"p\">[</span><span class=\"n\">key</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">value</span>\n        <span class=\"k\">return</span> <span class=\"n\">out</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">set_params</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">params</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Set the parameters of this estimator.</span>\n\n<span class=\"sd\">        The method works on simple estimators as well as on nested objects</span>\n<span class=\"sd\">        (such as pipelines). The latter have parameters of the form</span>\n<span class=\"sd\">        ``&lt;component&gt;__&lt;parameter&gt;`` so that it&#39;s possible to update each</span>\n<span class=\"sd\">        component of a nested object.</span>\n\n<span class=\"sd\">        Returns</span>\n<span class=\"sd\">        -------</span>\n<span class=\"sd\">        self</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"n\">params</span><span class=\"p\">:</span>\n            <span class=\"c1\"># Simple optimization to gain speed (inspect is slow)</span>\n            <span class=\"k\">return</span> <span class=\"bp\">self</span>\n        <span class=\"n\">valid_params</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">get_params</span><span class=\"p\">(</span><span class=\"n\">deep</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n\n        <span class=\"n\">nested_params</span> <span class=\"o\">=</span> <span class=\"n\">defaultdict</span><span class=\"p\">(</span><span class=\"nb\">dict</span><span class=\"p\">)</span>  <span class=\"c1\"># grouped by prefix</span>\n        <span class=\"k\">for</span> <span class=\"n\">key</span><span class=\"p\">,</span> <span class=\"n\">value</span> <span class=\"ow\">in</span> <span class=\"n\">params</span><span class=\"o\">.</span><span class=\"n\">items</span><span class=\"p\">():</span>\n            <span class=\"n\">key</span><span class=\"p\">,</span> <span class=\"n\">delim</span><span class=\"p\">,</span> <span class=\"n\">sub_key</span> <span class=\"o\">=</span> <span class=\"n\">key</span><span class=\"o\">.</span><span class=\"n\">partition</span><span class=\"p\">(</span><span class=\"s1\">&#39;__&#39;</span><span class=\"p\">)</span>\n            <span class=\"k\">if</span> <span class=\"n\">key</span> <span class=\"ow\">not</span> <span class=\"ow\">in</span> <span class=\"n\">valid_params</span><span class=\"p\">:</span>\n                <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s1\">&#39;Invalid parameter </span><span class=\"si\">%s</span><span class=\"s1\"> for estimator </span><span class=\"si\">%s</span><span class=\"s1\">. &#39;</span>\n                                 <span class=\"s1\">&#39;Check the list of available parameters &#39;</span>\n                                 <span class=\"s1\">&#39;with `estimator.get_params().keys()`.&#39;</span> <span class=\"o\">%</span>\n                                 <span class=\"p\">(</span><span class=\"n\">key</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">))</span>\n\n            <span class=\"k\">if</span> <span class=\"n\">delim</span><span class=\"p\">:</span>\n                <span class=\"n\">nested_params</span><span class=\"p\">[</span><span class=\"n\">key</span><span class=\"p\">][</span><span class=\"n\">sub_key</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">value</span>\n            <span class=\"k\">else</span><span class=\"p\">:</span>\n                <span class=\"nb\">setattr</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">key</span><span class=\"p\">,</span> <span class=\"n\">value</span><span class=\"p\">)</span>\n\n        <span class=\"k\">for</span> <span class=\"n\">key</span><span class=\"p\">,</span> <span class=\"n\">sub_params</span> <span class=\"ow\">in</span> <span class=\"n\">nested_params</span><span class=\"o\">.</span><span class=\"n\">items</span><span class=\"p\">():</span>\n            <span class=\"n\">valid_params</span><span class=\"p\">[</span><span class=\"n\">key</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">set_params</span><span class=\"p\">(</span><span class=\"o\">**</span><span class=\"n\">sub_params</span><span class=\"p\">)</span>\n\n        <span class=\"k\">return</span> <span class=\"bp\">self</span>\n\n    <span class=\"k\">def</span> <span class=\"fm\">__repr__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"n\">class_name</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"vm\">__class__</span><span class=\"o\">.</span><span class=\"vm\">__name__</span>\n        <span class=\"k\">return</span> <span class=\"s1\">&#39;</span><span class=\"si\">%s</span><span class=\"s1\">(</span><span class=\"si\">%s</span><span class=\"s1\">)&#39;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">class_name</span><span class=\"p\">,</span> <span class=\"n\">_pprint</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">get_params</span><span class=\"p\">(</span><span class=\"n\">deep</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">),</span>\n                                               <span class=\"n\">offset</span><span class=\"o\">=</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">class_name</span><span class=\"p\">),),)</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">__getstate__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">try</span><span class=\"p\">:</span>\n            <span class=\"n\">state</span> <span class=\"o\">=</span> <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">BaseEstimator</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">__getstate__</span><span class=\"p\">()</span>\n        <span class=\"k\">except</span> <span class=\"ne\">AttributeError</span><span class=\"p\">:</span>\n            <span class=\"n\">state</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"vm\">__dict__</span><span class=\"o\">.</span><span class=\"n\">copy</span><span class=\"p\">()</span>\n\n        <span class=\"k\">if</span> <span class=\"nb\">type</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"vm\">__module__</span><span class=\"o\">.</span><span class=\"n\">startswith</span><span class=\"p\">(</span><span class=\"s1\">&#39;sklearn.&#39;</span><span class=\"p\">):</span>\n            <span class=\"k\">return</span> <span class=\"nb\">dict</span><span class=\"p\">(</span><span class=\"n\">state</span><span class=\"o\">.</span><span class=\"n\">items</span><span class=\"p\">(),</span> <span class=\"n\">_sklearn_version</span><span class=\"o\">=</span><span class=\"n\">__version__</span><span class=\"p\">)</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"n\">state</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">__setstate__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">state</span><span class=\"p\">):</span>\n        <span class=\"k\">if</span> <span class=\"nb\">type</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"vm\">__module__</span><span class=\"o\">.</span><span class=\"n\">startswith</span><span class=\"p\">(</span><span class=\"s1\">&#39;sklearn.&#39;</span><span class=\"p\">):</span>\n            <span class=\"n\">pickle_version</span> <span class=\"o\">=</span> <span class=\"n\">state</span><span class=\"o\">.</span><span class=\"n\">pop</span><span class=\"p\">(</span><span class=\"s2\">&quot;_sklearn_version&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;pre-0.18&quot;</span><span class=\"p\">)</span>\n            <span class=\"k\">if</span> <span class=\"n\">pickle_version</span> <span class=\"o\">!=</span> <span class=\"n\">__version__</span><span class=\"p\">:</span>\n                <span class=\"n\">warnings</span><span class=\"o\">.</span><span class=\"n\">warn</span><span class=\"p\">(</span>\n                    <span class=\"s2\">&quot;Trying to unpickle estimator </span><span class=\"si\">{0}</span><span class=\"s2\"> from version </span><span class=\"si\">{1}</span><span class=\"s2\"> when &quot;</span>\n                    <span class=\"s2\">&quot;using version </span><span class=\"si\">{2}</span><span class=\"s2\">. This might lead to breaking code or &quot;</span>\n                    <span class=\"s2\">&quot;invalid results. Use at your own risk.&quot;</span><span class=\"o\">.</span><span class=\"n\">format</span><span class=\"p\">(</span>\n                        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"vm\">__class__</span><span class=\"o\">.</span><span class=\"vm\">__name__</span><span class=\"p\">,</span> <span class=\"n\">pickle_version</span><span class=\"p\">,</span> <span class=\"n\">__version__</span><span class=\"p\">),</span>\n                    <span class=\"ne\">UserWarning</span><span class=\"p\">)</span>\n        <span class=\"k\">try</span><span class=\"p\">:</span>\n            <span class=\"nb\">super</span><span class=\"p\">(</span><span class=\"n\">BaseEstimator</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">__setstate__</span><span class=\"p\">(</span><span class=\"n\">state</span><span class=\"p\">)</span>\n        <span class=\"k\">except</span> <span class=\"ne\">AttributeError</span><span class=\"p\">:</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"vm\">__dict__</span><span class=\"o\">.</span><span class=\"n\">update</span><span class=\"p\">(</span><span class=\"n\">state</span><span class=\"p\">)</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">ClusterMixin</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Mixin class for all cluster estimators in scikit-learn.&quot;&quot;&quot;</span>\n    <span class=\"n\">_estimator_type</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;clusterer&quot;</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">fit_predict</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Performs clustering on X and returns cluster labels.</span>\n\n<span class=\"sd\">        Parameters</span>\n<span class=\"sd\">        ----------</span>\n<span class=\"sd\">        X : ndarray, shape (n_samples, n_features)</span>\n<span class=\"sd\">            Input data.</span>\n\n<span class=\"sd\">        Returns</span>\n<span class=\"sd\">        -------</span>\n<span class=\"sd\">        y : ndarray, shape (n_samples,)</span>\n<span class=\"sd\">            cluster labels</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"c1\"># non-optimized default implementation; override when a better</span>\n        <span class=\"c1\"># method is possible for a given clustering algorithm</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">fit</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">labels_</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">TransformerMixin</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Mixin class for all transformers in scikit-learn.&quot;&quot;&quot;</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">fit_transform</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">fit_params</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Fit to data, then transform it.</span>\n\n<span class=\"sd\">        Fits transformer to X and y with optional parameters fit_params</span>\n<span class=\"sd\">        and returns a transformed version of X.</span>\n\n<span class=\"sd\">        Parameters</span>\n<span class=\"sd\">        ----------</span>\n<span class=\"sd\">        X : numpy array of shape [n_samples, n_features]</span>\n<span class=\"sd\">            Training set.</span>\n\n<span class=\"sd\">        y : numpy array of shape [n_samples]</span>\n<span class=\"sd\">            Target values.</span>\n\n<span class=\"sd\">        Returns</span>\n<span class=\"sd\">        -------</span>\n<span class=\"sd\">        X_new : numpy array of shape [n_samples, n_features_new]</span>\n<span class=\"sd\">            Transformed array.</span>\n\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"c1\"># non-optimized default implementation; override when a better</span>\n        <span class=\"c1\"># method is possible for a given clustering algorithm</span>\n        <span class=\"k\">if</span> <span class=\"n\">y</span> <span class=\"ow\">is</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n            <span class=\"c1\"># fit method of arity 1 (unsupervised transformation)</span>\n            <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">fit</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">fit_params</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">transform</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"c1\"># fit method of arity 2 (supervised transformation)</span>\n            <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">fit</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">fit_params</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">transform</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">_pprint</span><span class=\"p\">(</span><span class=\"n\">params</span><span class=\"p\">,</span> <span class=\"n\">offset</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">printer</span><span class=\"o\">=</span><span class=\"nb\">repr</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Pretty print the dictionary &#39;params&#39;</span>\n\n<span class=\"sd\">    Parameters</span>\n<span class=\"sd\">    ----------</span>\n<span class=\"sd\">    params : dict</span>\n<span class=\"sd\">        The dictionary to pretty print</span>\n\n<span class=\"sd\">    offset : int</span>\n<span class=\"sd\">        The offset in characters to add at the begin of each line.</span>\n\n<span class=\"sd\">    printer : callable</span>\n<span class=\"sd\">        The function to convert entries to strings, typically</span>\n<span class=\"sd\">        the builtin str or repr</span>\n\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"c1\"># Do a multi-line justified repr:</span>\n    <span class=\"n\">options</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">get_printoptions</span><span class=\"p\">()</span>\n    <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">set_printoptions</span><span class=\"p\">(</span><span class=\"n\">precision</span><span class=\"o\">=</span><span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"n\">threshold</span><span class=\"o\">=</span><span class=\"mi\">64</span><span class=\"p\">,</span> <span class=\"n\">edgeitems</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n    <span class=\"n\">params_list</span> <span class=\"o\">=</span> <span class=\"nb\">list</span><span class=\"p\">()</span>\n    <span class=\"n\">this_line_length</span> <span class=\"o\">=</span> <span class=\"n\">offset</span>\n    <span class=\"n\">line_sep</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;,</span><span class=\"se\">\\n</span><span class=\"s1\">&#39;</span> <span class=\"o\">+</span> <span class=\"p\">(</span><span class=\"mi\">1</span> <span class=\"o\">+</span> <span class=\"n\">offset</span> <span class=\"o\">//</span> <span class=\"mi\">2</span><span class=\"p\">)</span> <span class=\"o\">*</span> <span class=\"s1\">&#39; &#39;</span>\n    <span class=\"k\">for</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"n\">k</span><span class=\"p\">,</span> <span class=\"n\">v</span><span class=\"p\">)</span> <span class=\"ow\">in</span> <span class=\"nb\">enumerate</span><span class=\"p\">(</span><span class=\"nb\">sorted</span><span class=\"p\">(</span><span class=\"n\">six</span><span class=\"o\">.</span><span class=\"n\">iteritems</span><span class=\"p\">(</span><span class=\"n\">params</span><span class=\"p\">))):</span>\n        <span class=\"k\">if</span> <span class=\"nb\">type</span><span class=\"p\">(</span><span class=\"n\">v</span><span class=\"p\">)</span> <span class=\"ow\">is</span> <span class=\"nb\">float</span><span class=\"p\">:</span>\n            <span class=\"c1\"># use str for representing floating point numbers</span>\n            <span class=\"c1\"># this way we get consistent representation across</span>\n            <span class=\"c1\"># architectures and versions.</span>\n            <span class=\"n\">this_repr</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;</span><span class=\"si\">%s</span><span class=\"s1\">=</span><span class=\"si\">%s</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">k</span><span class=\"p\">,</span> <span class=\"nb\">str</span><span class=\"p\">(</span><span class=\"n\">v</span><span class=\"p\">))</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"c1\"># use repr of the rest</span>\n            <span class=\"n\">this_repr</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;</span><span class=\"si\">%s</span><span class=\"s1\">=</span><span class=\"si\">%s</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">k</span><span class=\"p\">,</span> <span class=\"n\">printer</span><span class=\"p\">(</span><span class=\"n\">v</span><span class=\"p\">))</span>\n        <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">this_repr</span><span class=\"p\">)</span> <span class=\"o\">&gt;</span> <span class=\"mi\">500</span><span class=\"p\">:</span>\n            <span class=\"n\">this_repr</span> <span class=\"o\">=</span> <span class=\"n\">this_repr</span><span class=\"p\">[:</span><span class=\"mi\">300</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"s1\">&#39;...&#39;</span> <span class=\"o\">+</span> <span class=\"n\">this_repr</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">100</span><span class=\"p\">:]</span>\n        <span class=\"k\">if</span> <span class=\"n\">i</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n            <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"n\">this_line_length</span> <span class=\"o\">+</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">this_repr</span><span class=\"p\">)</span> <span class=\"o\">&gt;=</span> <span class=\"mi\">75</span> <span class=\"ow\">or</span> <span class=\"s1\">&#39;</span><span class=\"se\">\\n</span><span class=\"s1\">&#39;</span> <span class=\"ow\">in</span> <span class=\"n\">this_repr</span><span class=\"p\">):</span>\n                <span class=\"n\">params_list</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">line_sep</span><span class=\"p\">)</span>\n                <span class=\"n\">this_line_length</span> <span class=\"o\">=</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">line_sep</span><span class=\"p\">)</span>\n            <span class=\"k\">else</span><span class=\"p\">:</span>\n                <span class=\"n\">params_list</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"s1\">&#39;, &#39;</span><span class=\"p\">)</span>\n                <span class=\"n\">this_line_length</span> <span class=\"o\">+=</span> <span class=\"mi\">2</span>\n        <span class=\"n\">params_list</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">this_repr</span><span class=\"p\">)</span>\n        <span class=\"n\">this_line_length</span> <span class=\"o\">+=</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">this_repr</span><span class=\"p\">)</span>\n\n    <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">set_printoptions</span><span class=\"p\">(</span><span class=\"o\">**</span><span class=\"n\">options</span><span class=\"p\">)</span>\n    <span class=\"n\">lines</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;&#39;</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">(</span><span class=\"n\">params_list</span><span class=\"p\">)</span>\n    <span class=\"c1\"># Strip trailing space to avoid nightmare in doctests</span>\n    <span class=\"n\">lines</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;</span><span class=\"se\">\\n</span><span class=\"s1\">&#39;</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">(</span><span class=\"n\">l</span><span class=\"o\">.</span><span class=\"n\">rstrip</span><span class=\"p\">(</span><span class=\"s1\">&#39; &#39;</span><span class=\"p\">)</span> <span class=\"k\">for</span> <span class=\"n\">l</span> <span class=\"ow\">in</span> <span class=\"n\">lines</span><span class=\"o\">.</span><span class=\"n\">split</span><span class=\"p\">(</span><span class=\"s1\">&#39;</span><span class=\"se\">\\n</span><span class=\"s1\">&#39;</span><span class=\"p\">))</span>\n    <span class=\"k\">return</span> <span class=\"n\">lines</span>\n</pre></div>\n\n           </div>\n           \n          </div>\n          <footer>\n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &#169; Copyright 2020, Josh Levy-Kramer. Documentation derived from Scikit-Learn.\n\n    </p>\n  </div>\n    \n    \n    \n    Built with <a href=\"https://www.sphinx-doc.org/\">Sphinx</a> using a\n    \n    <a href=\"https://github.com/readthedocs/sphinx_rtd_theme\">theme</a>\n    \n    provided by <a href=\"https://readthedocs.org\">Read the Docs</a>. \n\n</footer>\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.Navigation.enable(true);\n      });\n  </script>\n\n  \n  \n    \n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/_modules/k_means_constrained/sklearn_import/cluster/k_means_.html",
    "content": "\n\n<!DOCTYPE html>\n<html class=\"writer-html5\" lang=\"en\" >\n<head>\n  <meta charset=\"utf-8\" />\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n  \n  <title>k_means_constrained.sklearn_import.cluster.k_means_ &mdash; k-means-constrained 0.5.1 documentation</title>\n  \n\n  \n  <link rel=\"stylesheet\" href=\"../../../../_static/css/theme.css\" type=\"text/css\" />\n  <link rel=\"stylesheet\" href=\"../../../../_static/pygments.css\" type=\"text/css\" />\n  <link rel=\"stylesheet\" href=\"../../../../_static/pygments.css\" type=\"text/css\" />\n  <link rel=\"stylesheet\" href=\"../../../../_static/css/theme.css\" type=\"text/css\" />\n\n  \n  \n\n  \n  \n\n  \n\n  \n  <!--[if lt IE 9]>\n    <script src=\"../../../../_static/js/html5shiv.min.js\"></script>\n  <![endif]-->\n  \n    \n      <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../../../\" src=\"../../../../_static/documentation_options.js\"></script>\n        <script data-url_root=\"../../../../\" id=\"documentation_options\" src=\"../../../../_static/documentation_options.js\"></script>\n        <script src=\"../../../../_static/jquery.js\"></script>\n        <script src=\"../../../../_static/underscore.js\"></script>\n        <script src=\"../../../../_static/doctools.js\"></script>\n    \n    <script type=\"text/javascript\" src=\"../../../../_static/js/theme.js\"></script>\n\n    \n    <link rel=\"index\" title=\"Index\" href=\"../../../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../../../search.html\" /> \n</head>\n\n<body class=\"wy-body-for-nav\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\" >\n          \n\n          \n            <a href=\"../../../../index.html\" class=\"icon icon-home\"> k-means-constrained\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"../../../../search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        \n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n              \n            \n            \n              <!-- Local TOC -->\n              <div class=\"local-toc\"></div>\n            \n          \n        </div>\n        \n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"../../../../index.html\">k-means-constrained</a>\n        \n      </nav>\n\n\n      <div class=\"wy-nav-content\">\n        \n        <div class=\"rst-content\">\n        \n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"../../../../index.html\" class=\"icon icon-home\"></a> &raquo;</li>\n        \n          <li><a href=\"../../../index.html\">Module code</a> &raquo;</li>\n        \n      <li>k_means_constrained.sklearn_import.cluster.k_means_</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n      </li>\n    \n  </ul>\n\n  \n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <h1>Source code for k_means_constrained.sklearn_import.cluster.k_means_</h1><div class=\"highlight\"><pre>\n<span></span><span class=\"sd\">&quot;&quot;&quot;K-means clustering&quot;&quot;&quot;</span>\n\n<span class=\"c1\"># Authors: Gael Varoquaux &lt;gael.varoquaux@normalesup.org&gt;</span>\n<span class=\"c1\">#          Thomas Rueckstiess &lt;ruecksti@in.tum.de&gt;</span>\n<span class=\"c1\">#          James Bergstra &lt;james.bergstra@umontreal.ca&gt;</span>\n<span class=\"c1\">#          Jan Schlueter &lt;scikit-learn@jan-schlueter.de&gt;</span>\n<span class=\"c1\">#          Nelle Varoquaux</span>\n<span class=\"c1\">#          Peter Prettenhofer &lt;peter.prettenhofer@gmail.com&gt;</span>\n<span class=\"c1\">#          Olivier Grisel &lt;olivier.grisel@ensta.org&gt;</span>\n<span class=\"c1\">#          Mathieu Blondel &lt;mathieu@mblondel.org&gt;</span>\n<span class=\"c1\">#          Robert Layton &lt;robertlayton@gmail.com&gt;</span>\n<span class=\"c1\"># License: BSD 3 clause</span>\n\n<span class=\"kn\">import</span> <span class=\"nn\">warnings</span>\n\n<span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n<span class=\"kn\">import</span> <span class=\"nn\">scipy.sparse</span> <span class=\"k\">as</span> <span class=\"nn\">sp</span>\n<span class=\"kn\">from</span> <span class=\"nn\">k_means_constrained.sklearn_import.base</span> <span class=\"kn\">import</span> <span class=\"n\">BaseEstimator</span><span class=\"p\">,</span> <span class=\"n\">ClusterMixin</span><span class=\"p\">,</span> <span class=\"n\">TransformerMixin</span>\n<span class=\"kn\">from</span> <span class=\"nn\">six</span> <span class=\"kn\">import</span> <span class=\"n\">string_types</span>\n<span class=\"kn\">from</span> <span class=\"nn\">k_means_constrained.sklearn_import.metrics.pairwise</span> <span class=\"kn\">import</span> <span class=\"n\">euclidean_distances</span><span class=\"p\">,</span> <span class=\"n\">pairwise_distances_argmin_min</span>\n<span class=\"kn\">from</span> <span class=\"nn\">k_means_constrained.sklearn_import.utils.validation</span> <span class=\"kn\">import</span> <span class=\"n\">check_array</span><span class=\"p\">,</span> <span class=\"n\">check_random_state</span><span class=\"p\">,</span> <span class=\"n\">FLOAT_DTYPES</span><span class=\"p\">,</span> \\\n    <span class=\"n\">check_is_fitted</span>\n<span class=\"kn\">from</span> <span class=\"nn\">k_means_constrained.sklearn_import.utils.extmath</span> <span class=\"kn\">import</span> <span class=\"n\">row_norms</span><span class=\"p\">,</span> <span class=\"n\">stable_cumsum</span>\n<span class=\"kn\">from</span> <span class=\"nn\">k_means_constrained.sklearn_import.utils.sparsefuncs</span> <span class=\"kn\">import</span> <span class=\"n\">mean_variance_axis</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">k_means_constrained.sklearn_import.cluster</span> <span class=\"kn\">import</span> <span class=\"n\">_k_means</span>\n\n\n<span class=\"c1\">###############################################################################</span>\n<span class=\"c1\"># Initialization heuristic</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">_k_init</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">n_clusters</span><span class=\"p\">,</span> <span class=\"n\">x_squared_norms</span><span class=\"p\">,</span> <span class=\"n\">random_state</span><span class=\"p\">,</span> <span class=\"n\">n_local_trials</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Init n_clusters seeds according to k-means++</span>\n\n<span class=\"sd\">    Parameters</span>\n<span class=\"sd\">    -----------</span>\n<span class=\"sd\">    X : array or sparse matrix, shape (n_samples, n_features)</span>\n<span class=\"sd\">        The data to pick seeds for. To avoid memory copy, the input data</span>\n<span class=\"sd\">        should be double precision (dtype=np.float64).</span>\n\n<span class=\"sd\">    n_clusters : integer</span>\n<span class=\"sd\">        The number of seeds to choose</span>\n\n<span class=\"sd\">    x_squared_norms : array, shape (n_samples,)</span>\n<span class=\"sd\">        Squared Euclidean norm of each data point.</span>\n\n<span class=\"sd\">    random_state : numpy.RandomState</span>\n<span class=\"sd\">        The generator used to initialize the centers.</span>\n\n<span class=\"sd\">    n_local_trials : integer, optional</span>\n<span class=\"sd\">        The number of seeding trials for each center (except the first),</span>\n<span class=\"sd\">        of which the one reducing inertia the most is greedily chosen.</span>\n<span class=\"sd\">        Set to None to make the number of trials depend logarithmically</span>\n<span class=\"sd\">        on the number of seeds (2+log(k)); this is the default.</span>\n\n<span class=\"sd\">    Notes</span>\n<span class=\"sd\">    -----</span>\n<span class=\"sd\">    Selects initial cluster centers for k-mean clustering in a smart way</span>\n<span class=\"sd\">    to speed up convergence. see: Arthur, D. and Vassilvitskii, S.</span>\n<span class=\"sd\">    &quot;k-means++: the advantages of careful seeding&quot;. ACM-SIAM symposium</span>\n<span class=\"sd\">    on Discrete algorithms. 2007</span>\n\n<span class=\"sd\">    Version ported from http://www.stanford.edu/~darthur/kMeansppTest.zip,</span>\n<span class=\"sd\">    which is the implementation used in the aforementioned paper.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"n\">n_samples</span><span class=\"p\">,</span> <span class=\"n\">n_features</span> <span class=\"o\">=</span> <span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">shape</span>\n\n    <span class=\"n\">centers</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">empty</span><span class=\"p\">((</span><span class=\"n\">n_clusters</span><span class=\"p\">,</span> <span class=\"n\">n_features</span><span class=\"p\">),</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">dtype</span><span class=\"p\">)</span>\n\n    <span class=\"k\">assert</span> <span class=\"n\">x_squared_norms</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"s1\">&#39;x_squared_norms None in _k_init&#39;</span>\n\n    <span class=\"c1\"># Set the number of local seeding trials if none is given</span>\n    <span class=\"k\">if</span> <span class=\"n\">n_local_trials</span> <span class=\"ow\">is</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n        <span class=\"c1\"># This is what Arthur/Vassilvitskii tried, but did not report</span>\n        <span class=\"c1\"># specific results for other than mentioning in the conclusion</span>\n        <span class=\"c1\"># that it helped.</span>\n        <span class=\"n\">n_local_trials</span> <span class=\"o\">=</span> <span class=\"mi\">2</span> <span class=\"o\">+</span> <span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">log</span><span class=\"p\">(</span><span class=\"n\">n_clusters</span><span class=\"p\">))</span>\n\n    <span class=\"c1\"># Pick first center randomly</span>\n    <span class=\"n\">center_id</span> <span class=\"o\">=</span> <span class=\"n\">random_state</span><span class=\"o\">.</span><span class=\"n\">randint</span><span class=\"p\">(</span><span class=\"n\">n_samples</span><span class=\"p\">)</span>\n    <span class=\"k\">if</span> <span class=\"n\">sp</span><span class=\"o\">.</span><span class=\"n\">issparse</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">):</span>\n        <span class=\"n\">centers</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">X</span><span class=\"p\">[</span><span class=\"n\">center_id</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">toarray</span><span class=\"p\">()</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"n\">centers</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">X</span><span class=\"p\">[</span><span class=\"n\">center_id</span><span class=\"p\">]</span>\n\n    <span class=\"c1\"># Initialize list of closest distances and calculate current potential</span>\n    <span class=\"n\">closest_dist_sq</span> <span class=\"o\">=</span> <span class=\"n\">euclidean_distances</span><span class=\"p\">(</span>\n        <span class=\"n\">centers</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">newaxis</span><span class=\"p\">],</span> <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">Y_norm_squared</span><span class=\"o\">=</span><span class=\"n\">x_squared_norms</span><span class=\"p\">,</span>\n        <span class=\"n\">squared</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n    <span class=\"n\">current_pot</span> <span class=\"o\">=</span> <span class=\"n\">closest_dist_sq</span><span class=\"o\">.</span><span class=\"n\">sum</span><span class=\"p\">()</span>\n\n    <span class=\"c1\"># Pick the remaining n_clusters-1 points</span>\n    <span class=\"k\">for</span> <span class=\"n\">c</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">n_clusters</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Choose center candidates by sampling with probability proportional</span>\n        <span class=\"c1\"># to the squared distance to the closest existing center</span>\n        <span class=\"n\">rand_vals</span> <span class=\"o\">=</span> <span class=\"n\">random_state</span><span class=\"o\">.</span><span class=\"n\">random_sample</span><span class=\"p\">(</span><span class=\"n\">n_local_trials</span><span class=\"p\">)</span> <span class=\"o\">*</span> <span class=\"n\">current_pot</span>\n        <span class=\"n\">candidate_ids</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">searchsorted</span><span class=\"p\">(</span><span class=\"n\">stable_cumsum</span><span class=\"p\">(</span><span class=\"n\">closest_dist_sq</span><span class=\"p\">),</span>\n                                        <span class=\"n\">rand_vals</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># Compute distances to center candidates</span>\n        <span class=\"n\">distance_to_candidates</span> <span class=\"o\">=</span> <span class=\"n\">euclidean_distances</span><span class=\"p\">(</span>\n            <span class=\"n\">X</span><span class=\"p\">[</span><span class=\"n\">candidate_ids</span><span class=\"p\">],</span> <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">Y_norm_squared</span><span class=\"o\">=</span><span class=\"n\">x_squared_norms</span><span class=\"p\">,</span> <span class=\"n\">squared</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># Decide which candidate is the best</span>\n        <span class=\"n\">best_candidate</span> <span class=\"o\">=</span> <span class=\"kc\">None</span>\n        <span class=\"n\">best_pot</span> <span class=\"o\">=</span> <span class=\"kc\">None</span>\n        <span class=\"n\">best_dist_sq</span> <span class=\"o\">=</span> <span class=\"kc\">None</span>\n        <span class=\"k\">for</span> <span class=\"n\">trial</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">n_local_trials</span><span class=\"p\">):</span>\n            <span class=\"c1\"># Compute potential when including center candidate</span>\n            <span class=\"n\">new_dist_sq</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">minimum</span><span class=\"p\">(</span><span class=\"n\">closest_dist_sq</span><span class=\"p\">,</span>\n                                     <span class=\"n\">distance_to_candidates</span><span class=\"p\">[</span><span class=\"n\">trial</span><span class=\"p\">])</span>\n            <span class=\"n\">new_pot</span> <span class=\"o\">=</span> <span class=\"n\">new_dist_sq</span><span class=\"o\">.</span><span class=\"n\">sum</span><span class=\"p\">()</span>\n\n            <span class=\"c1\"># Store result if it is the best local trial so far</span>\n            <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"n\">best_candidate</span> <span class=\"ow\">is</span> <span class=\"kc\">None</span><span class=\"p\">)</span> <span class=\"ow\">or</span> <span class=\"p\">(</span><span class=\"n\">new_pot</span> <span class=\"o\">&lt;</span> <span class=\"n\">best_pot</span><span class=\"p\">):</span>\n                <span class=\"n\">best_candidate</span> <span class=\"o\">=</span> <span class=\"n\">candidate_ids</span><span class=\"p\">[</span><span class=\"n\">trial</span><span class=\"p\">]</span>\n                <span class=\"n\">best_pot</span> <span class=\"o\">=</span> <span class=\"n\">new_pot</span>\n                <span class=\"n\">best_dist_sq</span> <span class=\"o\">=</span> <span class=\"n\">new_dist_sq</span>\n\n        <span class=\"c1\"># Permanently add best center candidate found in local tries</span>\n        <span class=\"k\">if</span> <span class=\"n\">sp</span><span class=\"o\">.</span><span class=\"n\">issparse</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">):</span>\n            <span class=\"n\">centers</span><span class=\"p\">[</span><span class=\"n\">c</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">X</span><span class=\"p\">[</span><span class=\"n\">best_candidate</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">toarray</span><span class=\"p\">()</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"n\">centers</span><span class=\"p\">[</span><span class=\"n\">c</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">X</span><span class=\"p\">[</span><span class=\"n\">best_candidate</span><span class=\"p\">]</span>\n        <span class=\"n\">current_pot</span> <span class=\"o\">=</span> <span class=\"n\">best_pot</span>\n        <span class=\"n\">closest_dist_sq</span> <span class=\"o\">=</span> <span class=\"n\">best_dist_sq</span>\n\n    <span class=\"k\">return</span> <span class=\"n\">centers</span>\n\n\n<span class=\"c1\">###############################################################################</span>\n<span class=\"c1\"># K-means batch estimation by EM (expectation maximization)</span>\n\n<span class=\"k\">def</span> <span class=\"nf\">_validate_center_shape</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">n_centers</span><span class=\"p\">,</span> <span class=\"n\">centers</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Check if centers is compatible with X and n_centers&quot;&quot;&quot;</span>\n    <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">centers</span><span class=\"p\">)</span> <span class=\"o\">!=</span> <span class=\"n\">n_centers</span><span class=\"p\">:</span>\n        <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s1\">&#39;The shape of the initial centers (</span><span class=\"si\">%s</span><span class=\"s1\">) &#39;</span>\n                         <span class=\"s1\">&#39;does not match the number of clusters </span><span class=\"si\">%i</span><span class=\"s1\">&#39;</span>\n                         <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">centers</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">,</span> <span class=\"n\">n_centers</span><span class=\"p\">))</span>\n    <span class=\"k\">if</span> <span class=\"n\">centers</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"o\">!=</span> <span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]:</span>\n        <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span>\n            <span class=\"s2\">&quot;The number of features of the initial centers </span><span class=\"si\">%s</span><span class=\"s2\"> &quot;</span>\n            <span class=\"s2\">&quot;does not match the number of features of the data </span><span class=\"si\">%s</span><span class=\"s2\">.&quot;</span>\n            <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">centers</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]))</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">_tolerance</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">tol</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Return a tolerance which is independent of the dataset&quot;&quot;&quot;</span>\n    <span class=\"k\">if</span> <span class=\"n\">sp</span><span class=\"o\">.</span><span class=\"n\">issparse</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">):</span>\n        <span class=\"n\">variances</span> <span class=\"o\">=</span> <span class=\"n\">mean_variance_axis</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">)[</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"n\">variances</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">var</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">axis</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">mean</span><span class=\"p\">(</span><span class=\"n\">variances</span><span class=\"p\">)</span> <span class=\"o\">*</span> <span class=\"n\">tol</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">_labels_inertia_precompute_dense</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">x_squared_norms</span><span class=\"p\">,</span> <span class=\"n\">centers</span><span class=\"p\">,</span> <span class=\"n\">distances</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Compute labels and inertia using a full distance matrix.</span>\n\n<span class=\"sd\">    This will overwrite the &#39;distances&#39; array in-place.</span>\n\n<span class=\"sd\">    Parameters</span>\n<span class=\"sd\">    ----------</span>\n<span class=\"sd\">    X : numpy array, shape (n_sample, n_features)</span>\n<span class=\"sd\">        Input data.</span>\n\n<span class=\"sd\">    x_squared_norms : numpy array, shape (n_samples,)</span>\n<span class=\"sd\">        Precomputed squared norms of X.</span>\n\n<span class=\"sd\">    centers : numpy array, shape (n_clusters, n_features)</span>\n<span class=\"sd\">        Cluster centers which data is assigned to.</span>\n\n<span class=\"sd\">    distances : numpy array, shape (n_samples,)</span>\n<span class=\"sd\">        Pre-allocated array in which distances are stored.</span>\n\n<span class=\"sd\">    Returns</span>\n<span class=\"sd\">    -------</span>\n<span class=\"sd\">    labels : numpy array, dtype=np.int, shape (n_samples,)</span>\n<span class=\"sd\">        Indices of clusters that samples are assigned to.</span>\n\n<span class=\"sd\">    inertia : float</span>\n<span class=\"sd\">        Sum of distances of samples to their closest cluster center.</span>\n\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"n\">n_samples</span> <span class=\"o\">=</span> <span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n\n    <span class=\"c1\"># Breakup nearest neighbor distance computation into batches to prevent</span>\n    <span class=\"c1\"># memory blowup in the case of a large number of samples and clusters.</span>\n    <span class=\"c1\"># TODO: Once PR #7383 is merged use check_inputs=False in metric_kwargs.</span>\n    <span class=\"n\">labels</span><span class=\"p\">,</span> <span class=\"n\">mindist</span> <span class=\"o\">=</span> <span class=\"n\">pairwise_distances_argmin_min</span><span class=\"p\">(</span>\n        <span class=\"n\">X</span><span class=\"o\">=</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">Y</span><span class=\"o\">=</span><span class=\"n\">centers</span><span class=\"p\">,</span> <span class=\"n\">metric</span><span class=\"o\">=</span><span class=\"s1\">&#39;euclidean&#39;</span><span class=\"p\">,</span> <span class=\"n\">metric_kwargs</span><span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s1\">&#39;squared&#39;</span><span class=\"p\">:</span> <span class=\"kc\">True</span><span class=\"p\">})</span>\n    <span class=\"c1\"># cython k-means code assumes int32 inputs</span>\n    <span class=\"n\">labels</span> <span class=\"o\">=</span> <span class=\"n\">labels</span><span class=\"o\">.</span><span class=\"n\">astype</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">int32</span><span class=\"p\">)</span>\n    <span class=\"k\">if</span> <span class=\"n\">n_samples</span> <span class=\"o\">==</span> <span class=\"n\">distances</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]:</span>\n        <span class=\"c1\"># distances will be changed in-place</span>\n        <span class=\"n\">distances</span><span class=\"p\">[:]</span> <span class=\"o\">=</span> <span class=\"n\">mindist</span>\n    <span class=\"n\">inertia</span> <span class=\"o\">=</span> <span class=\"n\">mindist</span><span class=\"o\">.</span><span class=\"n\">sum</span><span class=\"p\">()</span>\n    <span class=\"k\">return</span> <span class=\"n\">labels</span><span class=\"p\">,</span> <span class=\"n\">inertia</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">_labels_inertia</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">x_squared_norms</span><span class=\"p\">,</span> <span class=\"n\">centers</span><span class=\"p\">,</span>\n                    <span class=\"n\">precompute_distances</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span> <span class=\"n\">distances</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;E step of the K-means EM algorithm.</span>\n\n<span class=\"sd\">    Compute the labels and the inertia of the given samples and centers.</span>\n<span class=\"sd\">    This will compute the distances in-place.</span>\n\n<span class=\"sd\">    Parameters</span>\n<span class=\"sd\">    ----------</span>\n<span class=\"sd\">    X : float64 array-like or CSR sparse matrix, shape (n_samples, n_features)</span>\n<span class=\"sd\">        The input samples to assign to the labels.</span>\n\n<span class=\"sd\">    x_squared_norms : array, shape (n_samples,)</span>\n<span class=\"sd\">        Precomputed squared euclidean norm of each data point, to speed up</span>\n<span class=\"sd\">        computations.</span>\n\n<span class=\"sd\">    centers : float array, shape (k, n_features)</span>\n<span class=\"sd\">        The cluster centers.</span>\n\n<span class=\"sd\">    precompute_distances : boolean, default: True</span>\n<span class=\"sd\">        Precompute distances (faster but takes more memory).</span>\n\n<span class=\"sd\">    distances : float array, shape (n_samples,)</span>\n<span class=\"sd\">        Pre-allocated array to be filled in with each sample&#39;s distance</span>\n<span class=\"sd\">        to the closest center.</span>\n\n<span class=\"sd\">    Returns</span>\n<span class=\"sd\">    -------</span>\n<span class=\"sd\">    labels : int array of shape(n)</span>\n<span class=\"sd\">        The resulting assignment</span>\n\n<span class=\"sd\">    inertia : float</span>\n<span class=\"sd\">        Sum of distances of samples to their closest cluster center.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"n\">n_samples</span> <span class=\"o\">=</span> <span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n    <span class=\"c1\"># set the default value of centers to -1 to be able to detect any anomaly</span>\n    <span class=\"c1\"># easily</span>\n    <span class=\"n\">labels</span> <span class=\"o\">=</span> <span class=\"o\">-</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">ones</span><span class=\"p\">(</span><span class=\"n\">n_samples</span><span class=\"p\">,</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">int32</span><span class=\"p\">)</span>\n    <span class=\"k\">if</span> <span class=\"n\">distances</span> <span class=\"ow\">is</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n        <span class=\"n\">distances</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">(</span><span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"p\">,),</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">dtype</span><span class=\"p\">)</span>\n    <span class=\"c1\"># distances will be changed in-place</span>\n    <span class=\"k\">if</span> <span class=\"n\">sp</span><span class=\"o\">.</span><span class=\"n\">issparse</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">):</span>\n        <span class=\"n\">inertia</span> <span class=\"o\">=</span> <span class=\"n\">_k_means</span><span class=\"o\">.</span><span class=\"n\">_assign_labels_csr</span><span class=\"p\">(</span>\n            <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">x_squared_norms</span><span class=\"p\">,</span> <span class=\"n\">centers</span><span class=\"p\">,</span> <span class=\"n\">labels</span><span class=\"p\">,</span> <span class=\"n\">distances</span><span class=\"o\">=</span><span class=\"n\">distances</span><span class=\"p\">)</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"k\">if</span> <span class=\"n\">precompute_distances</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"n\">_labels_inertia_precompute_dense</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">x_squared_norms</span><span class=\"p\">,</span>\n                                                    <span class=\"n\">centers</span><span class=\"p\">,</span> <span class=\"n\">distances</span><span class=\"p\">)</span>\n        <span class=\"n\">inertia</span> <span class=\"o\">=</span> <span class=\"n\">_k_means</span><span class=\"o\">.</span><span class=\"n\">_assign_labels_array</span><span class=\"p\">(</span>\n            <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">x_squared_norms</span><span class=\"p\">,</span> <span class=\"n\">centers</span><span class=\"p\">,</span> <span class=\"n\">labels</span><span class=\"p\">,</span> <span class=\"n\">distances</span><span class=\"o\">=</span><span class=\"n\">distances</span><span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">labels</span><span class=\"p\">,</span> <span class=\"n\">inertia</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">_init_centroids</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">k</span><span class=\"p\">,</span> <span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"n\">random_state</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">x_squared_norms</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span>\n                    <span class=\"n\">init_size</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Compute the initial centroids</span>\n\n<span class=\"sd\">    Parameters</span>\n<span class=\"sd\">    ----------</span>\n\n<span class=\"sd\">    X : array, shape (n_samples, n_features)</span>\n\n<span class=\"sd\">    k : int</span>\n<span class=\"sd\">        number of centroids</span>\n\n<span class=\"sd\">    init : {&#39;k-means++&#39;, &#39;random&#39; or ndarray or callable} optional</span>\n<span class=\"sd\">        Method for initialization</span>\n\n<span class=\"sd\">    random_state : int, RandomState instance or None, optional, default: None</span>\n<span class=\"sd\">        If int, random_state is the seed used by the random number generator;</span>\n<span class=\"sd\">        If RandomState instance, random_state is the random number generator;</span>\n<span class=\"sd\">        If None, the random number generator is the RandomState instance used</span>\n<span class=\"sd\">        by `np.random`.</span>\n\n<span class=\"sd\">    x_squared_norms :  array, shape (n_samples,), optional</span>\n<span class=\"sd\">        Squared euclidean norm of each data point. Pass it if you have it at</span>\n<span class=\"sd\">        hands already to avoid it being recomputed here. Default: None</span>\n\n<span class=\"sd\">    init_size : int, optional</span>\n<span class=\"sd\">        Number of samples to randomly sample for speeding up the</span>\n<span class=\"sd\">        initialization (sometimes at the expense of accuracy): the</span>\n<span class=\"sd\">        only algorithm is initialized by running a batch KMeans on a</span>\n<span class=\"sd\">        random subset of the data. This needs to be larger than k.</span>\n\n<span class=\"sd\">    Returns</span>\n<span class=\"sd\">    -------</span>\n<span class=\"sd\">    centers : array, shape(k, n_features)</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"n\">random_state</span> <span class=\"o\">=</span> <span class=\"n\">check_random_state</span><span class=\"p\">(</span><span class=\"n\">random_state</span><span class=\"p\">)</span>\n    <span class=\"n\">n_samples</span> <span class=\"o\">=</span> <span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n\n    <span class=\"k\">if</span> <span class=\"n\">x_squared_norms</span> <span class=\"ow\">is</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n        <span class=\"n\">x_squared_norms</span> <span class=\"o\">=</span> <span class=\"n\">row_norms</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">squared</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n\n    <span class=\"k\">if</span> <span class=\"n\">init_size</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span> <span class=\"ow\">and</span> <span class=\"n\">init_size</span> <span class=\"o\">&lt;</span> <span class=\"n\">n_samples</span><span class=\"p\">:</span>\n        <span class=\"k\">if</span> <span class=\"n\">init_size</span> <span class=\"o\">&lt;</span> <span class=\"n\">k</span><span class=\"p\">:</span>\n            <span class=\"n\">warnings</span><span class=\"o\">.</span><span class=\"n\">warn</span><span class=\"p\">(</span>\n                <span class=\"s2\">&quot;init_size=</span><span class=\"si\">%d</span><span class=\"s2\"> should be larger than k=</span><span class=\"si\">%d</span><span class=\"s2\">. &quot;</span>\n                <span class=\"s2\">&quot;Setting it to 3*k&quot;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">init_size</span><span class=\"p\">,</span> <span class=\"n\">k</span><span class=\"p\">),</span>\n                <span class=\"ne\">RuntimeWarning</span><span class=\"p\">,</span> <span class=\"n\">stacklevel</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n            <span class=\"n\">init_size</span> <span class=\"o\">=</span> <span class=\"mi\">3</span> <span class=\"o\">*</span> <span class=\"n\">k</span>\n        <span class=\"n\">init_indices</span> <span class=\"o\">=</span> <span class=\"n\">random_state</span><span class=\"o\">.</span><span class=\"n\">randint</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">n_samples</span><span class=\"p\">,</span> <span class=\"n\">init_size</span><span class=\"p\">)</span>\n        <span class=\"n\">X</span> <span class=\"o\">=</span> <span class=\"n\">X</span><span class=\"p\">[</span><span class=\"n\">init_indices</span><span class=\"p\">]</span>\n        <span class=\"n\">x_squared_norms</span> <span class=\"o\">=</span> <span class=\"n\">x_squared_norms</span><span class=\"p\">[</span><span class=\"n\">init_indices</span><span class=\"p\">]</span>\n        <span class=\"n\">n_samples</span> <span class=\"o\">=</span> <span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n    <span class=\"k\">elif</span> <span class=\"n\">n_samples</span> <span class=\"o\">&lt;</span> <span class=\"n\">k</span><span class=\"p\">:</span>\n        <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span>\n            <span class=\"s2\">&quot;n_samples=</span><span class=\"si\">%d</span><span class=\"s2\"> should be larger than k=</span><span class=\"si\">%d</span><span class=\"s2\">&quot;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">n_samples</span><span class=\"p\">,</span> <span class=\"n\">k</span><span class=\"p\">))</span>\n\n    <span class=\"k\">if</span> <span class=\"nb\">isinstance</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"n\">string_types</span><span class=\"p\">)</span> <span class=\"ow\">and</span> <span class=\"n\">init</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;k-means++&#39;</span><span class=\"p\">:</span>\n        <span class=\"n\">centers</span> <span class=\"o\">=</span> <span class=\"n\">_k_init</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">k</span><span class=\"p\">,</span> <span class=\"n\">random_state</span><span class=\"o\">=</span><span class=\"n\">random_state</span><span class=\"p\">,</span>\n                          <span class=\"n\">x_squared_norms</span><span class=\"o\">=</span><span class=\"n\">x_squared_norms</span><span class=\"p\">)</span>\n    <span class=\"k\">elif</span> <span class=\"nb\">isinstance</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"n\">string_types</span><span class=\"p\">)</span> <span class=\"ow\">and</span> <span class=\"n\">init</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;random&#39;</span><span class=\"p\">:</span>\n        <span class=\"n\">seeds</span> <span class=\"o\">=</span> <span class=\"n\">random_state</span><span class=\"o\">.</span><span class=\"n\">permutation</span><span class=\"p\">(</span><span class=\"n\">n_samples</span><span class=\"p\">)[:</span><span class=\"n\">k</span><span class=\"p\">]</span>\n        <span class=\"n\">centers</span> <span class=\"o\">=</span> <span class=\"n\">X</span><span class=\"p\">[</span><span class=\"n\">seeds</span><span class=\"p\">]</span>\n    <span class=\"k\">elif</span> <span class=\"nb\">hasattr</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"s1\">&#39;__array__&#39;</span><span class=\"p\">):</span>\n        <span class=\"c1\"># ensure that the centers have the same dtype as X</span>\n        <span class=\"c1\"># this is a requirement of fused types of cython</span>\n        <span class=\"n\">centers</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">dtype</span><span class=\"p\">)</span>\n    <span class=\"k\">elif</span> <span class=\"n\">callable</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"p\">):</span>\n        <span class=\"n\">centers</span> <span class=\"o\">=</span> <span class=\"n\">init</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">k</span><span class=\"p\">,</span> <span class=\"n\">random_state</span><span class=\"o\">=</span><span class=\"n\">random_state</span><span class=\"p\">)</span>\n        <span class=\"n\">centers</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">asarray</span><span class=\"p\">(</span><span class=\"n\">centers</span><span class=\"p\">,</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">dtype</span><span class=\"p\">)</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s2\">&quot;the init parameter for the k-means should &quot;</span>\n                         <span class=\"s2\">&quot;be &#39;k-means++&#39; or &#39;random&#39; or an ndarray, &quot;</span>\n                         <span class=\"s2\">&quot;&#39;</span><span class=\"si\">%s</span><span class=\"s2\">&#39; (type &#39;</span><span class=\"si\">%s</span><span class=\"s2\">&#39;) was passed.&quot;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"nb\">type</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"p\">)))</span>\n\n    <span class=\"k\">if</span> <span class=\"n\">sp</span><span class=\"o\">.</span><span class=\"n\">issparse</span><span class=\"p\">(</span><span class=\"n\">centers</span><span class=\"p\">):</span>\n        <span class=\"n\">centers</span> <span class=\"o\">=</span> <span class=\"n\">centers</span><span class=\"o\">.</span><span class=\"n\">toarray</span><span class=\"p\">()</span>\n\n    <span class=\"n\">_validate_center_shape</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">k</span><span class=\"p\">,</span> <span class=\"n\">centers</span><span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">centers</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">KMeans</span><span class=\"p\">(</span><span class=\"n\">BaseEstimator</span><span class=\"p\">,</span> <span class=\"n\">ClusterMixin</span><span class=\"p\">,</span> <span class=\"n\">TransformerMixin</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;K-Means clustering</span>\n\n<span class=\"sd\">    Read more in the :ref:`User Guide &lt;k_means&gt;`.</span>\n\n<span class=\"sd\">    Parameters</span>\n<span class=\"sd\">    ----------</span>\n\n<span class=\"sd\">    n_clusters : int, optional, default: 8</span>\n<span class=\"sd\">        The number of clusters to form as well as the number of</span>\n<span class=\"sd\">        centroids to generate.</span>\n\n<span class=\"sd\">    init : {&#39;k-means++&#39;, &#39;random&#39; or an ndarray}</span>\n<span class=\"sd\">        Method for initialization, defaults to &#39;k-means++&#39;:</span>\n\n<span class=\"sd\">        &#39;k-means++&#39; : selects initial cluster centers for k-mean</span>\n<span class=\"sd\">        clustering in a smart way to speed up convergence. See section</span>\n<span class=\"sd\">        Notes in k_init for more details.</span>\n\n<span class=\"sd\">        &#39;random&#39;: choose k observations (rows) at random from data for</span>\n<span class=\"sd\">        the initial centroids.</span>\n\n<span class=\"sd\">        If an ndarray is passed, it should be of shape (n_clusters, n_features)</span>\n<span class=\"sd\">        and gives the initial centers.</span>\n\n<span class=\"sd\">    n_init : int, default: 10</span>\n<span class=\"sd\">        Number of time the k-means algorithm will be run with different</span>\n<span class=\"sd\">        centroid seeds. The final results will be the best output of</span>\n<span class=\"sd\">        n_init consecutive runs in terms of inertia.</span>\n\n<span class=\"sd\">    max_iter : int, default: 300</span>\n<span class=\"sd\">        Maximum number of iterations of the k-means algorithm for a</span>\n<span class=\"sd\">        single run.</span>\n\n<span class=\"sd\">    tol : float, default: 1e-4</span>\n<span class=\"sd\">        Relative tolerance with regards to inertia to declare convergence</span>\n\n<span class=\"sd\">    precompute_distances : {&#39;auto&#39;, True, False}</span>\n<span class=\"sd\">        Precompute distances (faster but takes more memory).</span>\n\n<span class=\"sd\">        &#39;auto&#39; : do not precompute distances if n_samples * n_clusters &gt; 12</span>\n<span class=\"sd\">        million. This corresponds to about 100MB overhead per job using</span>\n<span class=\"sd\">        double precision.</span>\n\n<span class=\"sd\">        True : always precompute distances</span>\n\n<span class=\"sd\">        False : never precompute distances</span>\n\n<span class=\"sd\">    verbose : int, default 0</span>\n<span class=\"sd\">        Verbosity mode.</span>\n\n<span class=\"sd\">    random_state : int, RandomState instance or None, optional, default: None</span>\n<span class=\"sd\">        If int, random_state is the seed used by the random number generator;</span>\n<span class=\"sd\">        If RandomState instance, random_state is the random number generator;</span>\n<span class=\"sd\">        If None, the random number generator is the RandomState instance used</span>\n<span class=\"sd\">        by `np.random`.</span>\n\n<span class=\"sd\">    copy_x : boolean, default True</span>\n<span class=\"sd\">        When pre-computing distances it is more numerically accurate to center</span>\n<span class=\"sd\">        the data first.  If copy_x is True, then the original data is not</span>\n<span class=\"sd\">        modified.  If False, the original data is modified, and put back before</span>\n<span class=\"sd\">        the function returns, but small numerical differences may be introduced</span>\n<span class=\"sd\">        by subtracting and then adding the data mean.</span>\n\n<span class=\"sd\">    n_jobs : int</span>\n<span class=\"sd\">        The number of jobs to use for the computation. This works by computing</span>\n<span class=\"sd\">        each of the n_init runs in parallel.</span>\n\n<span class=\"sd\">        If -1 all CPUs are used. If 1 is given, no parallel computing code is</span>\n<span class=\"sd\">        used at all, which is useful for debugging. For n_jobs below -1,</span>\n<span class=\"sd\">        (n_cpus + 1 + n_jobs) are used. Thus for n_jobs = -2, all CPUs but one</span>\n<span class=\"sd\">        are used.</span>\n\n<span class=\"sd\">    algorithm : &quot;auto&quot;, &quot;full&quot; or &quot;elkan&quot;, default=&quot;auto&quot;</span>\n<span class=\"sd\">        K-means algorithm to use. The classical EM-style algorithm is &quot;full&quot;.</span>\n<span class=\"sd\">        The &quot;elkan&quot; variation is more efficient by using the triangle</span>\n<span class=\"sd\">        inequality, but currently doesn&#39;t support sparse data. &quot;auto&quot; chooses</span>\n<span class=\"sd\">        &quot;elkan&quot; for dense data and &quot;full&quot; for sparse data.</span>\n\n<span class=\"sd\">    Attributes</span>\n<span class=\"sd\">    ----------</span>\n<span class=\"sd\">    cluster_centers_ : array, [n_clusters, n_features]</span>\n<span class=\"sd\">        Coordinates of cluster centers</span>\n\n<span class=\"sd\">    labels_ :</span>\n<span class=\"sd\">        Labels of each point</span>\n\n<span class=\"sd\">    inertia_ : float</span>\n<span class=\"sd\">        Sum of distances of samples to their closest cluster center.</span>\n\n<span class=\"sd\">    Examples</span>\n<span class=\"sd\">    --------</span>\n\n<span class=\"sd\">    &gt;&gt;&gt; from sklearn.cluster import KMeans</span>\n<span class=\"sd\">    &gt;&gt;&gt; import numpy as np</span>\n<span class=\"sd\">    &gt;&gt;&gt; X = np.array([[1, 2], [1, 4], [1, 0],</span>\n<span class=\"sd\">    ...               [4, 2], [4, 4], [4, 0]])</span>\n<span class=\"sd\">    &gt;&gt;&gt; kmeans = KMeans(n_clusters=2, random_state=0).fit(X)</span>\n<span class=\"sd\">    &gt;&gt;&gt; kmeans.labels_</span>\n<span class=\"sd\">    array([0, 0, 0, 1, 1, 1], dtype=int32)</span>\n<span class=\"sd\">    &gt;&gt;&gt; kmeans.predict([[0, 0], [4, 4]])</span>\n<span class=\"sd\">    array([0, 1], dtype=int32)</span>\n<span class=\"sd\">    &gt;&gt;&gt; kmeans.cluster_centers_</span>\n<span class=\"sd\">    array([[ 1.,  2.],</span>\n<span class=\"sd\">           [ 4.,  2.]])</span>\n\n<span class=\"sd\">    See also</span>\n<span class=\"sd\">    --------</span>\n\n<span class=\"sd\">    MiniBatchKMeans</span>\n<span class=\"sd\">        Alternative online implementation that does incremental updates</span>\n<span class=\"sd\">        of the centers positions using mini-batches.</span>\n<span class=\"sd\">        For large scale learning (say n_samples &gt; 10k) MiniBatchKMeans is</span>\n<span class=\"sd\">        probably much faster than the default batch implementation.</span>\n\n<span class=\"sd\">    Notes</span>\n<span class=\"sd\">    ------</span>\n<span class=\"sd\">    The k-means problem is solved using Lloyd&#39;s algorithm.</span>\n\n<span class=\"sd\">    The average complexity is given by O(k n T), were n is the number of</span>\n<span class=\"sd\">    samples and T is the number of iteration.</span>\n\n<span class=\"sd\">    The worst case complexity is given by O(n^(k+2/p)) with</span>\n<span class=\"sd\">    n = n_samples, p = n_features. (D. Arthur and S. Vassilvitskii,</span>\n<span class=\"sd\">    &#39;How slow is the k-means method?&#39; SoCG2006)</span>\n\n<span class=\"sd\">    In practice, the k-means algorithm is very fast (one of the fastest</span>\n<span class=\"sd\">    clustering algorithms available), but it falls in local minima. That&#39;s why</span>\n<span class=\"sd\">    it can be useful to restart it several times.</span>\n\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n\n    <span class=\"k\">def</span> <span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">n_clusters</span><span class=\"o\">=</span><span class=\"mi\">8</span><span class=\"p\">,</span> <span class=\"n\">init</span><span class=\"o\">=</span><span class=\"s1\">&#39;k-means++&#39;</span><span class=\"p\">,</span> <span class=\"n\">n_init</span><span class=\"o\">=</span><span class=\"mi\">10</span><span class=\"p\">,</span>\n                 <span class=\"n\">max_iter</span><span class=\"o\">=</span><span class=\"mi\">300</span><span class=\"p\">,</span> <span class=\"n\">tol</span><span class=\"o\">=</span><span class=\"mf\">1e-4</span><span class=\"p\">,</span> <span class=\"n\">precompute_distances</span><span class=\"o\">=</span><span class=\"s1\">&#39;auto&#39;</span><span class=\"p\">,</span>\n                 <span class=\"n\">verbose</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">random_state</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">copy_x</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span>\n                 <span class=\"n\">n_jobs</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">algorithm</span><span class=\"o\">=</span><span class=\"s1\">&#39;auto&#39;</span><span class=\"p\">):</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">n_clusters</span> <span class=\"o\">=</span> <span class=\"n\">n_clusters</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">init</span> <span class=\"o\">=</span> <span class=\"n\">init</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">max_iter</span> <span class=\"o\">=</span> <span class=\"n\">max_iter</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">tol</span> <span class=\"o\">=</span> <span class=\"n\">tol</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">precompute_distances</span> <span class=\"o\">=</span> <span class=\"n\">precompute_distances</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">n_init</span> <span class=\"o\">=</span> <span class=\"n\">n_init</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">verbose</span> <span class=\"o\">=</span> <span class=\"n\">verbose</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">random_state</span> <span class=\"o\">=</span> <span class=\"n\">random_state</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">copy_x</span> <span class=\"o\">=</span> <span class=\"n\">copy_x</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">n_jobs</span> <span class=\"o\">=</span> <span class=\"n\">n_jobs</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">algorithm</span> <span class=\"o\">=</span> <span class=\"n\">algorithm</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">_check_fit_data</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Verify that the number of samples given is larger than k&quot;&quot;&quot;</span>\n        <span class=\"n\">X</span> <span class=\"o\">=</span> <span class=\"n\">check_array</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">accept_sparse</span><span class=\"o\">=</span><span class=\"s1\">&#39;csr&#39;</span><span class=\"p\">,</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float64</span><span class=\"p\">,</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">float32</span><span class=\"p\">])</span>\n        <span class=\"k\">if</span> <span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">&lt;</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">n_clusters</span><span class=\"p\">:</span>\n            <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s2\">&quot;n_samples=</span><span class=\"si\">%d</span><span class=\"s2\"> should be &gt;= n_clusters=</span><span class=\"si\">%d</span><span class=\"s2\">&quot;</span> <span class=\"o\">%</span> <span class=\"p\">(</span>\n                <span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">n_clusters</span><span class=\"p\">))</span>\n        <span class=\"k\">return</span> <span class=\"n\">X</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">_check_test_data</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">):</span>\n        <span class=\"n\">X</span> <span class=\"o\">=</span> <span class=\"n\">check_array</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">accept_sparse</span><span class=\"o\">=</span><span class=\"s1\">&#39;csr&#39;</span><span class=\"p\">,</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">FLOAT_DTYPES</span><span class=\"p\">)</span>\n        <span class=\"n\">n_samples</span><span class=\"p\">,</span> <span class=\"n\">n_features</span> <span class=\"o\">=</span> <span class=\"n\">X</span><span class=\"o\">.</span><span class=\"n\">shape</span>\n        <span class=\"n\">expected_n_features</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">cluster_centers_</span><span class=\"o\">.</span><span class=\"n\">shape</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n        <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"n\">n_features</span> <span class=\"o\">==</span> <span class=\"n\">expected_n_features</span><span class=\"p\">:</span>\n            <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s2\">&quot;Incorrect number of features. &quot;</span>\n                             <span class=\"s2\">&quot;Got </span><span class=\"si\">%d</span><span class=\"s2\"> features, expected </span><span class=\"si\">%d</span><span class=\"s2\">&quot;</span> <span class=\"o\">%</span> <span class=\"p\">(</span>\n                                 <span class=\"n\">n_features</span><span class=\"p\">,</span> <span class=\"n\">expected_n_features</span><span class=\"p\">))</span>\n\n        <span class=\"k\">return</span> <span class=\"n\">X</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">fit</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Compute k-means clustering.</span>\n\n<span class=\"sd\">        Parameters</span>\n<span class=\"sd\">        ----------</span>\n<span class=\"sd\">        X : array-like or sparse matrix, shape=(n_samples, n_features)</span>\n<span class=\"sd\">            Training instances to cluster.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"c1\"># Added to remove scikit-learn internal dependenceies</span>\n        <span class=\"k\">raise</span> <span class=\"bp\">NotImplemented</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">fit_predict</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Compute cluster centers and predict cluster index for each sample.</span>\n\n<span class=\"sd\">        Convenience method; equivalent to calling fit(X) followed by</span>\n<span class=\"sd\">        predict(X).</span>\n\n<span class=\"sd\">        Parameters</span>\n<span class=\"sd\">        ----------</span>\n<span class=\"sd\">        X : {array-like, sparse matrix}, shape = [n_samples, n_features]</span>\n<span class=\"sd\">            New data to transform.</span>\n\n<span class=\"sd\">        Returns</span>\n<span class=\"sd\">        -------</span>\n<span class=\"sd\">        labels : array, shape [n_samples,]</span>\n<span class=\"sd\">            Index of the cluster each sample belongs to.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">fit</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">labels_</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">fit_transform</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Compute clustering and transform X to cluster-distance space.</span>\n\n<span class=\"sd\">        Equivalent to fit(X).transform(X), but more efficiently implemented.</span>\n\n<span class=\"sd\">        Parameters</span>\n<span class=\"sd\">        ----------</span>\n<span class=\"sd\">        X : {array-like, sparse matrix}, shape = [n_samples, n_features]</span>\n<span class=\"sd\">            New data to transform.</span>\n\n<span class=\"sd\">        Returns</span>\n<span class=\"sd\">        -------</span>\n<span class=\"sd\">        X_new : array, shape [n_samples, k]</span>\n<span class=\"sd\">            X transformed in the new space.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"c1\"># Currently, this just skips a copy of the data if it is not in</span>\n        <span class=\"c1\"># np.array or CSR format already.</span>\n        <span class=\"c1\"># XXX This skips _check_test_data, which may change the dtype;</span>\n        <span class=\"c1\"># we should refactor the input validation.</span>\n        <span class=\"n\">X</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_check_fit_data</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">fit</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">_transform</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">transform</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Transform X to a cluster-distance space.</span>\n\n<span class=\"sd\">        In the new space, each dimension is the distance to the cluster</span>\n<span class=\"sd\">        centers.  Note that even if X is sparse, the array returned by</span>\n<span class=\"sd\">        `transform` will typically be dense.</span>\n\n<span class=\"sd\">        Parameters</span>\n<span class=\"sd\">        ----------</span>\n<span class=\"sd\">        X : {array-like, sparse matrix}, shape = [n_samples, n_features]</span>\n<span class=\"sd\">            New data to transform.</span>\n\n<span class=\"sd\">        Returns</span>\n<span class=\"sd\">        -------</span>\n<span class=\"sd\">        X_new : array, shape [n_samples, k]</span>\n<span class=\"sd\">            X transformed in the new space.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"n\">check_is_fitted</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"s1\">&#39;cluster_centers_&#39;</span><span class=\"p\">)</span>\n\n        <span class=\"n\">X</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_check_test_data</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_transform</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">_transform</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;guts of transform method; no input validation&quot;&quot;&quot;</span>\n        <span class=\"k\">return</span> <span class=\"n\">euclidean_distances</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">cluster_centers_</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">predict</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Predict the closest cluster each sample in X belongs to.</span>\n\n<span class=\"sd\">        In the vector quantization literature, `cluster_centers_` is called</span>\n<span class=\"sd\">        the code book and each value returned by `predict` is the index of</span>\n<span class=\"sd\">        the closest code in the code book.</span>\n\n<span class=\"sd\">        Parameters</span>\n<span class=\"sd\">        ----------</span>\n<span class=\"sd\">        X : {array-like, sparse matrix}, shape = [n_samples, n_features]</span>\n<span class=\"sd\">            New data to predict.</span>\n\n<span class=\"sd\">        Returns</span>\n<span class=\"sd\">        -------</span>\n<span class=\"sd\">        labels : array, shape [n_samples,]</span>\n<span class=\"sd\">            Index of the cluster each sample belongs to.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"n\">check_is_fitted</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"s1\">&#39;cluster_centers_&#39;</span><span class=\"p\">)</span>\n\n        <span class=\"n\">X</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_check_test_data</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span>\n        <span class=\"n\">x_squared_norms</span> <span class=\"o\">=</span> <span class=\"n\">row_norms</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">squared</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"n\">_labels_inertia</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">x_squared_norms</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">cluster_centers_</span><span class=\"p\">)[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">score</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Opposite of the value of X on the K-means objective.</span>\n\n<span class=\"sd\">        Parameters</span>\n<span class=\"sd\">        ----------</span>\n<span class=\"sd\">        X : {array-like, sparse matrix}, shape = [n_samples, n_features]</span>\n<span class=\"sd\">            New data.</span>\n\n<span class=\"sd\">        Returns</span>\n<span class=\"sd\">        -------</span>\n<span class=\"sd\">        score : float</span>\n<span class=\"sd\">            Opposite of the value of X on the K-means objective.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"n\">check_is_fitted</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"s1\">&#39;cluster_centers_&#39;</span><span class=\"p\">)</span>\n\n        <span class=\"n\">X</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_check_test_data</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span>\n        <span class=\"n\">x_squared_norms</span> <span class=\"o\">=</span> <span class=\"n\">row_norms</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">squared</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"o\">-</span><span class=\"n\">_labels_inertia</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">x_squared_norms</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">cluster_centers_</span><span class=\"p\">)[</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n\n\n</pre></div>\n\n           </div>\n           \n          </div>\n          <footer>\n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &#169; Copyright 2020, Josh Levy-Kramer. Documentation derived from Scikit-Learn.\n\n    </p>\n  </div>\n    \n    \n    \n    Built with <a href=\"https://www.sphinx-doc.org/\">Sphinx</a> using a\n    \n    <a href=\"https://github.com/readthedocs/sphinx_rtd_theme\">theme</a>\n    \n    provided by <a href=\"https://readthedocs.org\">Read the Docs</a>. \n\n</footer>\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.Navigation.enable(true);\n      });\n  </script>\n\n  \n  \n    \n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/_modules/sklearn/base.html",
    "content": "\n<!DOCTYPE html>\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>sklearn.base &#8212; k-means-constrained 0.0.2 documentation</title>\n    <link rel=\"stylesheet\" href=\"../../_static/alabaster.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../_static/pygments.css\" type=\"text/css\" />\n    <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"../../\" src=\"../../_static/documentation_options.js\"></script>\n    <script type=\"text/javascript\" src=\"../../_static/jquery.js\"></script>\n    <script type=\"text/javascript\" src=\"../../_static/underscore.js\"></script>\n    <script type=\"text/javascript\" src=\"../../_static/doctools.js\"></script>\n    <script type=\"text/javascript\" src=\"../../_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"../../genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"../../search.html\" />\n   \n  <link rel=\"stylesheet\" href=\"../../_static/custom.css\" type=\"text/css\" />\n  \n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=0.9, maximum-scale=0.9\" />\n\n  </head><body>\n  \n\n    <div class=\"document\">\n      <div class=\"documentwrapper\">\n        <div class=\"bodywrapper\">\n          \n\n          <div class=\"body\" role=\"main\">\n            \n  <h1>Source code for sklearn.base</h1><div class=\"highlight\"><pre>\n<span></span><span class=\"sd\">&quot;&quot;&quot;Base classes for all estimators.&quot;&quot;&quot;</span>\n\n<span class=\"c1\"># Author: Gael Varoquaux &lt;gael.varoquaux@normalesup.org&gt;</span>\n<span class=\"c1\"># License: BSD 3 clause</span>\n\n<span class=\"kn\">import</span> <span class=\"nn\">copy</span>\n<span class=\"kn\">import</span> <span class=\"nn\">warnings</span>\n<span class=\"kn\">from</span> <span class=\"nn\">collections</span> <span class=\"k\">import</span> <span class=\"n\">defaultdict</span>\n<span class=\"kn\">import</span> <span class=\"nn\">platform</span>\n<span class=\"kn\">import</span> <span class=\"nn\">inspect</span>\n<span class=\"kn\">import</span> <span class=\"nn\">re</span>\n\n<span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">.</span> <span class=\"k\">import</span> <span class=\"n\">__version__</span>\n<span class=\"kn\">from</span> <span class=\"nn\">.utils</span> <span class=\"k\">import</span> <span class=\"n\">_IS_32BIT</span>\n\n<span class=\"n\">_DEFAULT_TAGS</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"s1\">&#39;non_deterministic&#39;</span><span class=\"p\">:</span> <span class=\"kc\">False</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;requires_positive_data&#39;</span><span class=\"p\">:</span> <span class=\"kc\">False</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;X_types&#39;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s1\">&#39;2darray&#39;</span><span class=\"p\">],</span>\n    <span class=\"s1\">&#39;poor_score&#39;</span><span class=\"p\">:</span> <span class=\"kc\">False</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;no_validation&#39;</span><span class=\"p\">:</span> <span class=\"kc\">False</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;multioutput&#39;</span><span class=\"p\">:</span> <span class=\"kc\">False</span><span class=\"p\">,</span>\n    <span class=\"s2\">&quot;allow_nan&quot;</span><span class=\"p\">:</span> <span class=\"kc\">False</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;stateless&#39;</span><span class=\"p\">:</span> <span class=\"kc\">False</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;multilabel&#39;</span><span class=\"p\">:</span> <span class=\"kc\">False</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;_skip_test&#39;</span><span class=\"p\">:</span> <span class=\"kc\">False</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;multioutput_only&#39;</span><span class=\"p\">:</span> <span class=\"kc\">False</span><span class=\"p\">}</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">clone</span><span class=\"p\">(</span><span class=\"n\">estimator</span><span class=\"p\">,</span> <span class=\"n\">safe</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Constructs a new estimator with the same parameters.</span>\n\n<span class=\"sd\">    Clone does a deep copy of the model in an estimator</span>\n<span class=\"sd\">    without actually copying attached data. It yields a new estimator</span>\n<span class=\"sd\">    with the same parameters that has not been fit on any data.</span>\n\n<span class=\"sd\">    Parameters</span>\n<span class=\"sd\">    ----------</span>\n<span class=\"sd\">    estimator : estimator object, or list, tuple or set of objects</span>\n<span class=\"sd\">        The estimator or group of estimators to be cloned</span>\n\n<span class=\"sd\">    safe : boolean, optional</span>\n<span class=\"sd\">        If safe is false, clone will fall back to a deep copy on objects</span>\n<span class=\"sd\">        that are not estimators.</span>\n\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"n\">estimator_type</span> <span class=\"o\">=</span> <span class=\"nb\">type</span><span class=\"p\">(</span><span class=\"n\">estimator</span><span class=\"p\">)</span>\n    <span class=\"c1\"># XXX: not handling dictionaries</span>\n    <span class=\"k\">if</span> <span class=\"n\">estimator_type</span> <span class=\"ow\">in</span> <span class=\"p\">(</span><span class=\"nb\">list</span><span class=\"p\">,</span> <span class=\"nb\">tuple</span><span class=\"p\">,</span> <span class=\"nb\">set</span><span class=\"p\">,</span> <span class=\"nb\">frozenset</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"n\">estimator_type</span><span class=\"p\">([</span><span class=\"n\">clone</span><span class=\"p\">(</span><span class=\"n\">e</span><span class=\"p\">,</span> <span class=\"n\">safe</span><span class=\"o\">=</span><span class=\"n\">safe</span><span class=\"p\">)</span> <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"n\">estimator</span><span class=\"p\">])</span>\n    <span class=\"k\">elif</span> <span class=\"ow\">not</span> <span class=\"nb\">hasattr</span><span class=\"p\">(</span><span class=\"n\">estimator</span><span class=\"p\">,</span> <span class=\"s1\">&#39;get_params&#39;</span><span class=\"p\">)</span> <span class=\"ow\">or</span> <span class=\"nb\">isinstance</span><span class=\"p\">(</span><span class=\"n\">estimator</span><span class=\"p\">,</span> <span class=\"nb\">type</span><span class=\"p\">):</span>\n        <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"n\">safe</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"n\">copy</span><span class=\"o\">.</span><span class=\"n\">deepcopy</span><span class=\"p\">(</span><span class=\"n\">estimator</span><span class=\"p\">)</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"k\">raise</span> <span class=\"ne\">TypeError</span><span class=\"p\">(</span><span class=\"s2\">&quot;Cannot clone object &#39;</span><span class=\"si\">%s</span><span class=\"s2\">&#39; (type </span><span class=\"si\">%s</span><span class=\"s2\">): &quot;</span>\n                            <span class=\"s2\">&quot;it does not seem to be a scikit-learn estimator &quot;</span>\n                            <span class=\"s2\">&quot;as it does not implement a &#39;get_params&#39; methods.&quot;</span>\n                            <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"nb\">repr</span><span class=\"p\">(</span><span class=\"n\">estimator</span><span class=\"p\">),</span> <span class=\"nb\">type</span><span class=\"p\">(</span><span class=\"n\">estimator</span><span class=\"p\">)))</span>\n    <span class=\"n\">klass</span> <span class=\"o\">=</span> <span class=\"n\">estimator</span><span class=\"o\">.</span><span class=\"vm\">__class__</span>\n    <span class=\"n\">new_object_params</span> <span class=\"o\">=</span> <span class=\"n\">estimator</span><span class=\"o\">.</span><span class=\"n\">get_params</span><span class=\"p\">(</span><span class=\"n\">deep</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n    <span class=\"k\">for</span> <span class=\"n\">name</span><span class=\"p\">,</span> <span class=\"n\">param</span> <span class=\"ow\">in</span> <span class=\"n\">new_object_params</span><span class=\"o\">.</span><span class=\"n\">items</span><span class=\"p\">():</span>\n        <span class=\"n\">new_object_params</span><span class=\"p\">[</span><span class=\"n\">name</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">clone</span><span class=\"p\">(</span><span class=\"n\">param</span><span class=\"p\">,</span> <span class=\"n\">safe</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n    <span class=\"n\">new_object</span> <span class=\"o\">=</span> <span class=\"n\">klass</span><span class=\"p\">(</span><span class=\"o\">**</span><span class=\"n\">new_object_params</span><span class=\"p\">)</span>\n    <span class=\"n\">params_set</span> <span class=\"o\">=</span> <span class=\"n\">new_object</span><span class=\"o\">.</span><span class=\"n\">get_params</span><span class=\"p\">(</span><span class=\"n\">deep</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n\n    <span class=\"c1\"># quick sanity check of the parameters of the clone</span>\n    <span class=\"k\">for</span> <span class=\"n\">name</span> <span class=\"ow\">in</span> <span class=\"n\">new_object_params</span><span class=\"p\">:</span>\n        <span class=\"n\">param1</span> <span class=\"o\">=</span> <span class=\"n\">new_object_params</span><span class=\"p\">[</span><span class=\"n\">name</span><span class=\"p\">]</span>\n        <span class=\"n\">param2</span> <span class=\"o\">=</span> <span class=\"n\">params_set</span><span class=\"p\">[</span><span class=\"n\">name</span><span class=\"p\">]</span>\n        <span class=\"k\">if</span> <span class=\"n\">param1</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"n\">param2</span><span class=\"p\">:</span>\n            <span class=\"k\">raise</span> <span class=\"ne\">RuntimeError</span><span class=\"p\">(</span><span class=\"s1\">&#39;Cannot clone object </span><span class=\"si\">%s</span><span class=\"s1\">, as the constructor &#39;</span>\n                               <span class=\"s1\">&#39;either does not set or modifies parameter </span><span class=\"si\">%s</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span>\n                               <span class=\"p\">(</span><span class=\"n\">estimator</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"p\">))</span>\n    <span class=\"k\">return</span> <span class=\"n\">new_object</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">_pprint</span><span class=\"p\">(</span><span class=\"n\">params</span><span class=\"p\">,</span> <span class=\"n\">offset</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">printer</span><span class=\"o\">=</span><span class=\"nb\">repr</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Pretty print the dictionary &#39;params&#39;</span>\n\n<span class=\"sd\">    Parameters</span>\n<span class=\"sd\">    ----------</span>\n<span class=\"sd\">    params : dict</span>\n<span class=\"sd\">        The dictionary to pretty print</span>\n\n<span class=\"sd\">    offset : int</span>\n<span class=\"sd\">        The offset in characters to add at the begin of each line.</span>\n\n<span class=\"sd\">    printer : callable</span>\n<span class=\"sd\">        The function to convert entries to strings, typically</span>\n<span class=\"sd\">        the builtin str or repr</span>\n\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"c1\"># Do a multi-line justified repr:</span>\n    <span class=\"n\">options</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">get_printoptions</span><span class=\"p\">()</span>\n    <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">set_printoptions</span><span class=\"p\">(</span><span class=\"n\">precision</span><span class=\"o\">=</span><span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"n\">threshold</span><span class=\"o\">=</span><span class=\"mi\">64</span><span class=\"p\">,</span> <span class=\"n\">edgeitems</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n    <span class=\"n\">params_list</span> <span class=\"o\">=</span> <span class=\"nb\">list</span><span class=\"p\">()</span>\n    <span class=\"n\">this_line_length</span> <span class=\"o\">=</span> <span class=\"n\">offset</span>\n    <span class=\"n\">line_sep</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;,</span><span class=\"se\">\\n</span><span class=\"s1\">&#39;</span> <span class=\"o\">+</span> <span class=\"p\">(</span><span class=\"mi\">1</span> <span class=\"o\">+</span> <span class=\"n\">offset</span> <span class=\"o\">//</span> <span class=\"mi\">2</span><span class=\"p\">)</span> <span class=\"o\">*</span> <span class=\"s1\">&#39; &#39;</span>\n    <span class=\"k\">for</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"n\">k</span><span class=\"p\">,</span> <span class=\"n\">v</span><span class=\"p\">)</span> <span class=\"ow\">in</span> <span class=\"nb\">enumerate</span><span class=\"p\">(</span><span class=\"nb\">sorted</span><span class=\"p\">(</span><span class=\"n\">params</span><span class=\"o\">.</span><span class=\"n\">items</span><span class=\"p\">())):</span>\n        <span class=\"k\">if</span> <span class=\"nb\">type</span><span class=\"p\">(</span><span class=\"n\">v</span><span class=\"p\">)</span> <span class=\"ow\">is</span> <span class=\"nb\">float</span><span class=\"p\">:</span>\n            <span class=\"c1\"># use str for representing floating point numbers</span>\n            <span class=\"c1\"># this way we get consistent representation across</span>\n            <span class=\"c1\"># architectures and versions.</span>\n            <span class=\"n\">this_repr</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;</span><span class=\"si\">%s</span><span class=\"s1\">=</span><span class=\"si\">%s</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">k</span><span class=\"p\">,</span> <span class=\"nb\">str</span><span class=\"p\">(</span><span class=\"n\">v</span><span class=\"p\">))</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"c1\"># use repr of the rest</span>\n            <span class=\"n\">this_repr</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;</span><span class=\"si\">%s</span><span class=\"s1\">=</span><span class=\"si\">%s</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">k</span><span class=\"p\">,</span> <span class=\"n\">printer</span><span class=\"p\">(</span><span class=\"n\">v</span><span class=\"p\">))</span>\n        <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">this_repr</span><span class=\"p\">)</span> <span class=\"o\">&gt;</span> <span class=\"mi\">500</span><span class=\"p\">:</span>\n            <span class=\"n\">this_repr</span> <span class=\"o\">=</span> <span class=\"n\">this_repr</span><span class=\"p\">[:</span><span class=\"mi\">300</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"s1\">&#39;...&#39;</span> <span class=\"o\">+</span> <span class=\"n\">this_repr</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">100</span><span class=\"p\">:]</span>\n        <span class=\"k\">if</span> <span class=\"n\">i</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n            <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"n\">this_line_length</span> <span class=\"o\">+</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">this_repr</span><span class=\"p\">)</span> <span class=\"o\">&gt;=</span> <span class=\"mi\">75</span> <span class=\"ow\">or</span> <span class=\"s1\">&#39;</span><span class=\"se\">\\n</span><span class=\"s1\">&#39;</span> <span class=\"ow\">in</span> <span class=\"n\">this_repr</span><span class=\"p\">):</span>\n                <span class=\"n\">params_list</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">line_sep</span><span class=\"p\">)</span>\n                <span class=\"n\">this_line_length</span> <span class=\"o\">=</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">line_sep</span><span class=\"p\">)</span>\n            <span class=\"k\">else</span><span class=\"p\">:</span>\n                <span class=\"n\">params_list</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"s1\">&#39;, &#39;</span><span class=\"p\">)</span>\n                <span class=\"n\">this_line_length</span> <span class=\"o\">+=</span> <span class=\"mi\">2</span>\n        <span class=\"n\">params_list</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">this_repr</span><span class=\"p\">)</span>\n        <span class=\"n\">this_line_length</span> <span class=\"o\">+=</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">this_repr</span><span class=\"p\">)</span>\n\n    <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">set_printoptions</span><span class=\"p\">(</span><span class=\"o\">**</span><span class=\"n\">options</span><span class=\"p\">)</span>\n    <span class=\"n\">lines</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;&#39;</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">(</span><span class=\"n\">params_list</span><span class=\"p\">)</span>\n    <span class=\"c1\"># Strip trailing space to avoid nightmare in doctests</span>\n    <span class=\"n\">lines</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;</span><span class=\"se\">\\n</span><span class=\"s1\">&#39;</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">(</span><span class=\"n\">l</span><span class=\"o\">.</span><span class=\"n\">rstrip</span><span class=\"p\">(</span><span class=\"s1\">&#39; &#39;</span><span class=\"p\">)</span> <span class=\"k\">for</span> <span class=\"n\">l</span> <span class=\"ow\">in</span> <span class=\"n\">lines</span><span class=\"o\">.</span><span class=\"n\">split</span><span class=\"p\">(</span><span class=\"s1\">&#39;</span><span class=\"se\">\\n</span><span class=\"s1\">&#39;</span><span class=\"p\">))</span>\n    <span class=\"k\">return</span> <span class=\"n\">lines</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">_update_if_consistent</span><span class=\"p\">(</span><span class=\"n\">dict1</span><span class=\"p\">,</span> <span class=\"n\">dict2</span><span class=\"p\">):</span>\n    <span class=\"n\">common_keys</span> <span class=\"o\">=</span> <span class=\"nb\">set</span><span class=\"p\">(</span><span class=\"n\">dict1</span><span class=\"o\">.</span><span class=\"n\">keys</span><span class=\"p\">())</span><span class=\"o\">.</span><span class=\"n\">intersection</span><span class=\"p\">(</span><span class=\"n\">dict2</span><span class=\"o\">.</span><span class=\"n\">keys</span><span class=\"p\">())</span>\n    <span class=\"k\">for</span> <span class=\"n\">key</span> <span class=\"ow\">in</span> <span class=\"n\">common_keys</span><span class=\"p\">:</span>\n        <span class=\"k\">if</span> <span class=\"n\">dict1</span><span class=\"p\">[</span><span class=\"n\">key</span><span class=\"p\">]</span> <span class=\"o\">!=</span> <span class=\"n\">dict2</span><span class=\"p\">[</span><span class=\"n\">key</span><span class=\"p\">]:</span>\n            <span class=\"k\">raise</span> <span class=\"ne\">TypeError</span><span class=\"p\">(</span><span class=\"s2\">&quot;Inconsistent values for tag </span><span class=\"si\">{}</span><span class=\"s2\">: </span><span class=\"si\">{}</span><span class=\"s2\"> != </span><span class=\"si\">{}</span><span class=\"s2\">&quot;</span><span class=\"o\">.</span><span class=\"n\">format</span><span class=\"p\">(</span>\n                <span class=\"n\">key</span><span class=\"p\">,</span> <span class=\"n\">dict1</span><span class=\"p\">[</span><span class=\"n\">key</span><span class=\"p\">],</span> <span class=\"n\">dict2</span><span class=\"p\">[</span><span class=\"n\">key</span><span class=\"p\">]</span>\n            <span class=\"p\">))</span>\n    <span class=\"n\">dict1</span><span class=\"o\">.</span><span class=\"n\">update</span><span class=\"p\">(</span><span class=\"n\">dict2</span><span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">dict1</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">BaseEstimator</span><span class=\"p\">:</span>\n    <span class=\"sd\">&quot;&quot;&quot;Base class for all estimators in scikit-learn</span>\n\n<span class=\"sd\">    Notes</span>\n<span class=\"sd\">    -----</span>\n<span class=\"sd\">    All estimators should specify all the parameters that can be set</span>\n<span class=\"sd\">    at the class level in their ``__init__`` as explicit keyword</span>\n<span class=\"sd\">    arguments (no ``*args`` or ``**kwargs``).</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n\n    <span class=\"nd\">@classmethod</span>\n    <span class=\"k\">def</span> <span class=\"nf\">_get_param_names</span><span class=\"p\">(</span><span class=\"bp\">cls</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Get parameter names for the estimator&quot;&quot;&quot;</span>\n        <span class=\"c1\"># fetch the constructor or the original constructor before</span>\n        <span class=\"c1\"># deprecation wrapping if any</span>\n        <span class=\"n\">init</span> <span class=\"o\">=</span> <span class=\"nb\">getattr</span><span class=\"p\">(</span><span class=\"bp\">cls</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">,</span> <span class=\"s1\">&#39;deprecated_original&#39;</span><span class=\"p\">,</span> <span class=\"bp\">cls</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"n\">init</span> <span class=\"ow\">is</span> <span class=\"nb\">object</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">:</span>\n            <span class=\"c1\"># No explicit constructor to introspect</span>\n            <span class=\"k\">return</span> <span class=\"p\">[]</span>\n\n        <span class=\"c1\"># introspect the constructor arguments to find the model parameters</span>\n        <span class=\"c1\"># to represent</span>\n        <span class=\"n\">init_signature</span> <span class=\"o\">=</span> <span class=\"n\">inspect</span><span class=\"o\">.</span><span class=\"n\">signature</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"p\">)</span>\n        <span class=\"c1\"># Consider the constructor parameters excluding &#39;self&#39;</span>\n        <span class=\"n\">parameters</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">p</span> <span class=\"k\">for</span> <span class=\"n\">p</span> <span class=\"ow\">in</span> <span class=\"n\">init_signature</span><span class=\"o\">.</span><span class=\"n\">parameters</span><span class=\"o\">.</span><span class=\"n\">values</span><span class=\"p\">()</span>\n                      <span class=\"k\">if</span> <span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">name</span> <span class=\"o\">!=</span> <span class=\"s1\">&#39;self&#39;</span> <span class=\"ow\">and</span> <span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">kind</span> <span class=\"o\">!=</span> <span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">VAR_KEYWORD</span><span class=\"p\">]</span>\n        <span class=\"k\">for</span> <span class=\"n\">p</span> <span class=\"ow\">in</span> <span class=\"n\">parameters</span><span class=\"p\">:</span>\n            <span class=\"k\">if</span> <span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">kind</span> <span class=\"o\">==</span> <span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">VAR_POSITIONAL</span><span class=\"p\">:</span>\n                <span class=\"k\">raise</span> <span class=\"ne\">RuntimeError</span><span class=\"p\">(</span><span class=\"s2\">&quot;scikit-learn estimators should always &quot;</span>\n                                   <span class=\"s2\">&quot;specify their parameters in the signature&quot;</span>\n                                   <span class=\"s2\">&quot; of their __init__ (no varargs).&quot;</span>\n                                   <span class=\"s2\">&quot; </span><span class=\"si\">%s</span><span class=\"s2\"> with constructor </span><span class=\"si\">%s</span><span class=\"s2\"> doesn&#39;t &quot;</span>\n                                   <span class=\"s2\">&quot; follow this convention.&quot;</span>\n                                   <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"bp\">cls</span><span class=\"p\">,</span> <span class=\"n\">init_signature</span><span class=\"p\">))</span>\n        <span class=\"c1\"># Extract and sort argument names excluding &#39;self&#39;</span>\n        <span class=\"k\">return</span> <span class=\"nb\">sorted</span><span class=\"p\">([</span><span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">name</span> <span class=\"k\">for</span> <span class=\"n\">p</span> <span class=\"ow\">in</span> <span class=\"n\">parameters</span><span class=\"p\">])</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">get_params</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">deep</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Get parameters for this estimator.</span>\n\n<span class=\"sd\">        Parameters</span>\n<span class=\"sd\">        ----------</span>\n<span class=\"sd\">        deep : boolean, optional</span>\n<span class=\"sd\">            If True, will return the parameters for this estimator and</span>\n<span class=\"sd\">            contained subobjects that are estimators.</span>\n\n<span class=\"sd\">        Returns</span>\n<span class=\"sd\">        -------</span>\n<span class=\"sd\">        params : mapping of string to any</span>\n<span class=\"sd\">            Parameter names mapped to their values.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"n\">out</span> <span class=\"o\">=</span> <span class=\"nb\">dict</span><span class=\"p\">()</span>\n        <span class=\"k\">for</span> <span class=\"n\">key</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_get_param_names</span><span class=\"p\">():</span>\n            <span class=\"n\">value</span> <span class=\"o\">=</span> <span class=\"nb\">getattr</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">key</span><span class=\"p\">,</span> <span class=\"kc\">None</span><span class=\"p\">)</span>\n            <span class=\"k\">if</span> <span class=\"n\">deep</span> <span class=\"ow\">and</span> <span class=\"nb\">hasattr</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">,</span> <span class=\"s1\">&#39;get_params&#39;</span><span class=\"p\">):</span>\n                <span class=\"n\">deep_items</span> <span class=\"o\">=</span> <span class=\"n\">value</span><span class=\"o\">.</span><span class=\"n\">get_params</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">items</span><span class=\"p\">()</span>\n                <span class=\"n\">out</span><span class=\"o\">.</span><span class=\"n\">update</span><span class=\"p\">((</span><span class=\"n\">key</span> <span class=\"o\">+</span> <span class=\"s1\">&#39;__&#39;</span> <span class=\"o\">+</span> <span class=\"n\">k</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"p\">)</span> <span class=\"k\">for</span> <span class=\"n\">k</span><span class=\"p\">,</span> <span class=\"n\">val</span> <span class=\"ow\">in</span> <span class=\"n\">deep_items</span><span class=\"p\">)</span>\n            <span class=\"n\">out</span><span class=\"p\">[</span><span class=\"n\">key</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">value</span>\n        <span class=\"k\">return</span> <span class=\"n\">out</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">set_params</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">params</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Set the parameters of this estimator.</span>\n\n<span class=\"sd\">        The method works on simple estimators as well as on nested objects</span>\n<span class=\"sd\">        (such as pipelines). The latter have parameters of the form</span>\n<span class=\"sd\">        ``&lt;component&gt;__&lt;parameter&gt;`` so that it&#39;s possible to update each</span>\n<span class=\"sd\">        component of a nested object.</span>\n\n<span class=\"sd\">        Returns</span>\n<span class=\"sd\">        -------</span>\n<span class=\"sd\">        self</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"n\">params</span><span class=\"p\">:</span>\n            <span class=\"c1\"># Simple optimization to gain speed (inspect is slow)</span>\n            <span class=\"k\">return</span> <span class=\"bp\">self</span>\n        <span class=\"n\">valid_params</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">get_params</span><span class=\"p\">(</span><span class=\"n\">deep</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n\n        <span class=\"n\">nested_params</span> <span class=\"o\">=</span> <span class=\"n\">defaultdict</span><span class=\"p\">(</span><span class=\"nb\">dict</span><span class=\"p\">)</span>  <span class=\"c1\"># grouped by prefix</span>\n        <span class=\"k\">for</span> <span class=\"n\">key</span><span class=\"p\">,</span> <span class=\"n\">value</span> <span class=\"ow\">in</span> <span class=\"n\">params</span><span class=\"o\">.</span><span class=\"n\">items</span><span class=\"p\">():</span>\n            <span class=\"n\">key</span><span class=\"p\">,</span> <span class=\"n\">delim</span><span class=\"p\">,</span> <span class=\"n\">sub_key</span> <span class=\"o\">=</span> <span class=\"n\">key</span><span class=\"o\">.</span><span class=\"n\">partition</span><span class=\"p\">(</span><span class=\"s1\">&#39;__&#39;</span><span class=\"p\">)</span>\n            <span class=\"k\">if</span> <span class=\"n\">key</span> <span class=\"ow\">not</span> <span class=\"ow\">in</span> <span class=\"n\">valid_params</span><span class=\"p\">:</span>\n                <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s1\">&#39;Invalid parameter </span><span class=\"si\">%s</span><span class=\"s1\"> for estimator </span><span class=\"si\">%s</span><span class=\"s1\">. &#39;</span>\n                                 <span class=\"s1\">&#39;Check the list of available parameters &#39;</span>\n                                 <span class=\"s1\">&#39;with `estimator.get_params().keys()`.&#39;</span> <span class=\"o\">%</span>\n                                 <span class=\"p\">(</span><span class=\"n\">key</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"p\">))</span>\n\n            <span class=\"k\">if</span> <span class=\"n\">delim</span><span class=\"p\">:</span>\n                <span class=\"n\">nested_params</span><span class=\"p\">[</span><span class=\"n\">key</span><span class=\"p\">][</span><span class=\"n\">sub_key</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">value</span>\n            <span class=\"k\">else</span><span class=\"p\">:</span>\n                <span class=\"nb\">setattr</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">key</span><span class=\"p\">,</span> <span class=\"n\">value</span><span class=\"p\">)</span>\n                <span class=\"n\">valid_params</span><span class=\"p\">[</span><span class=\"n\">key</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">value</span>\n\n        <span class=\"k\">for</span> <span class=\"n\">key</span><span class=\"p\">,</span> <span class=\"n\">sub_params</span> <span class=\"ow\">in</span> <span class=\"n\">nested_params</span><span class=\"o\">.</span><span class=\"n\">items</span><span class=\"p\">():</span>\n            <span class=\"n\">valid_params</span><span class=\"p\">[</span><span class=\"n\">key</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">set_params</span><span class=\"p\">(</span><span class=\"o\">**</span><span class=\"n\">sub_params</span><span class=\"p\">)</span>\n\n        <span class=\"k\">return</span> <span class=\"bp\">self</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">__repr__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">N_CHAR_MAX</span><span class=\"o\">=</span><span class=\"mi\">700</span><span class=\"p\">):</span>\n        <span class=\"c1\"># N_CHAR_MAX is the (approximate) maximum number of non-blank</span>\n        <span class=\"c1\"># characters to render. We pass it as an optional parameter to ease</span>\n        <span class=\"c1\"># the tests.</span>\n\n        <span class=\"kn\">from</span> <span class=\"nn\">.utils._pprint</span> <span class=\"k\">import</span> <span class=\"n\">_EstimatorPrettyPrinter</span>\n\n        <span class=\"n\">N_MAX_ELEMENTS_TO_SHOW</span> <span class=\"o\">=</span> <span class=\"mi\">30</span>  <span class=\"c1\"># number of elements to show in sequences</span>\n\n        <span class=\"c1\"># use ellipsis for sequences with a lot of elements</span>\n        <span class=\"n\">pp</span> <span class=\"o\">=</span> <span class=\"n\">_EstimatorPrettyPrinter</span><span class=\"p\">(</span>\n            <span class=\"n\">compact</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span> <span class=\"n\">indent</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">indent_at_name</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span>\n            <span class=\"n\">n_max_elements_to_show</span><span class=\"o\">=</span><span class=\"n\">N_MAX_ELEMENTS_TO_SHOW</span><span class=\"p\">)</span>\n\n        <span class=\"n\">repr_</span> <span class=\"o\">=</span> <span class=\"n\">pp</span><span class=\"o\">.</span><span class=\"n\">pformat</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">)</span>\n\n        <span class=\"c1\"># Use bruteforce ellipsis when there are a lot of non-blank characters</span>\n        <span class=\"n\">n_nonblank</span> <span class=\"o\">=</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"s1\">&#39;&#39;</span><span class=\"o\">.</span><span class=\"n\">join</span><span class=\"p\">(</span><span class=\"n\">repr_</span><span class=\"o\">.</span><span class=\"n\">split</span><span class=\"p\">()))</span>\n        <span class=\"k\">if</span> <span class=\"n\">n_nonblank</span> <span class=\"o\">&gt;</span> <span class=\"n\">N_CHAR_MAX</span><span class=\"p\">:</span>\n            <span class=\"n\">lim</span> <span class=\"o\">=</span> <span class=\"n\">N_CHAR_MAX</span> <span class=\"o\">//</span> <span class=\"mi\">2</span>  <span class=\"c1\"># apprx number of chars to keep on both ends</span>\n            <span class=\"n\">regex</span> <span class=\"o\">=</span> <span class=\"sa\">r</span><span class=\"s1\">&#39;^(\\s*\\S){</span><span class=\"si\">%d</span><span class=\"s1\">}&#39;</span> <span class=\"o\">%</span> <span class=\"n\">lim</span>\n            <span class=\"c1\"># The regex &#39;^(\\s*\\S){%d}&#39; % n</span>\n            <span class=\"c1\"># matches from the start of the string until the nth non-blank</span>\n            <span class=\"c1\"># character:</span>\n            <span class=\"c1\"># - ^ matches the start of string</span>\n            <span class=\"c1\"># - (pattern){n} matches n repetitions of pattern</span>\n            <span class=\"c1\"># - \\s*\\S matches a non-blank char following zero or more blanks</span>\n            <span class=\"n\">left_lim</span> <span class=\"o\">=</span> <span class=\"n\">re</span><span class=\"o\">.</span><span class=\"n\">match</span><span class=\"p\">(</span><span class=\"n\">regex</span><span class=\"p\">,</span> <span class=\"n\">repr_</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">end</span><span class=\"p\">()</span>\n            <span class=\"n\">right_lim</span> <span class=\"o\">=</span> <span class=\"n\">re</span><span class=\"o\">.</span><span class=\"n\">match</span><span class=\"p\">(</span><span class=\"n\">regex</span><span class=\"p\">,</span> <span class=\"n\">repr_</span><span class=\"p\">[::</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">])</span><span class=\"o\">.</span><span class=\"n\">end</span><span class=\"p\">()</span>\n\n            <span class=\"k\">if</span> <span class=\"s1\">&#39;</span><span class=\"se\">\\n</span><span class=\"s1\">&#39;</span> <span class=\"ow\">in</span> <span class=\"n\">repr_</span><span class=\"p\">[</span><span class=\"n\">left_lim</span><span class=\"p\">:</span><span class=\"o\">-</span><span class=\"n\">right_lim</span><span class=\"p\">]:</span>\n                <span class=\"c1\"># The left side and right side aren&#39;t on the same line.</span>\n                <span class=\"c1\"># To avoid weird cuts, e.g.:</span>\n                <span class=\"c1\"># categoric...ore&#39;,</span>\n                <span class=\"c1\"># we need to start the right side with an appropriate newline</span>\n                <span class=\"c1\"># character so that it renders properly as:</span>\n                <span class=\"c1\"># categoric...</span>\n                <span class=\"c1\"># handle_unknown=&#39;ignore&#39;,</span>\n                <span class=\"c1\"># so we add [^\\n]*\\n which matches until the next \\n</span>\n                <span class=\"n\">regex</span> <span class=\"o\">+=</span> <span class=\"sa\">r</span><span class=\"s1\">&#39;[^\\n]*\\n&#39;</span>\n                <span class=\"n\">right_lim</span> <span class=\"o\">=</span> <span class=\"n\">re</span><span class=\"o\">.</span><span class=\"n\">match</span><span class=\"p\">(</span><span class=\"n\">regex</span><span class=\"p\">,</span> <span class=\"n\">repr_</span><span class=\"p\">[::</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">])</span><span class=\"o\">.</span><span class=\"n\">end</span><span class=\"p\">()</span>\n\n            <span class=\"n\">ellipsis</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;...&#39;</span>\n            <span class=\"k\">if</span> <span class=\"n\">left_lim</span> <span class=\"o\">+</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">ellipsis</span><span class=\"p\">)</span> <span class=\"o\">&lt;</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">repr_</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"n\">right_lim</span><span class=\"p\">:</span>\n                <span class=\"c1\"># Only add ellipsis if it results in a shorter repr</span>\n                <span class=\"n\">repr_</span> <span class=\"o\">=</span> <span class=\"n\">repr_</span><span class=\"p\">[:</span><span class=\"n\">left_lim</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"s1\">&#39;...&#39;</span> <span class=\"o\">+</span> <span class=\"n\">repr_</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"n\">right_lim</span><span class=\"p\">:]</span>\n\n        <span class=\"k\">return</span> <span class=\"n\">repr_</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">__getstate__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">try</span><span class=\"p\">:</span>\n            <span class=\"n\">state</span> <span class=\"o\">=</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">__getstate__</span><span class=\"p\">()</span>\n        <span class=\"k\">except</span> <span class=\"ne\">AttributeError</span><span class=\"p\">:</span>\n            <span class=\"n\">state</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"vm\">__dict__</span><span class=\"o\">.</span><span class=\"n\">copy</span><span class=\"p\">()</span>\n\n        <span class=\"k\">if</span> <span class=\"nb\">type</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"vm\">__module__</span><span class=\"o\">.</span><span class=\"n\">startswith</span><span class=\"p\">(</span><span class=\"s1\">&#39;sklearn.&#39;</span><span class=\"p\">):</span>\n            <span class=\"k\">return</span> <span class=\"nb\">dict</span><span class=\"p\">(</span><span class=\"n\">state</span><span class=\"o\">.</span><span class=\"n\">items</span><span class=\"p\">(),</span> <span class=\"n\">_sklearn_version</span><span class=\"o\">=</span><span class=\"n\">__version__</span><span class=\"p\">)</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"n\">state</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">__setstate__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">state</span><span class=\"p\">):</span>\n        <span class=\"k\">if</span> <span class=\"nb\">type</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"vm\">__module__</span><span class=\"o\">.</span><span class=\"n\">startswith</span><span class=\"p\">(</span><span class=\"s1\">&#39;sklearn.&#39;</span><span class=\"p\">):</span>\n            <span class=\"n\">pickle_version</span> <span class=\"o\">=</span> <span class=\"n\">state</span><span class=\"o\">.</span><span class=\"n\">pop</span><span class=\"p\">(</span><span class=\"s2\">&quot;_sklearn_version&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;pre-0.18&quot;</span><span class=\"p\">)</span>\n            <span class=\"k\">if</span> <span class=\"n\">pickle_version</span> <span class=\"o\">!=</span> <span class=\"n\">__version__</span><span class=\"p\">:</span>\n                <span class=\"n\">warnings</span><span class=\"o\">.</span><span class=\"n\">warn</span><span class=\"p\">(</span>\n                    <span class=\"s2\">&quot;Trying to unpickle estimator </span><span class=\"si\">{0}</span><span class=\"s2\"> from version </span><span class=\"si\">{1}</span><span class=\"s2\"> when &quot;</span>\n                    <span class=\"s2\">&quot;using version </span><span class=\"si\">{2}</span><span class=\"s2\">. This might lead to breaking code or &quot;</span>\n                    <span class=\"s2\">&quot;invalid results. Use at your own risk.&quot;</span><span class=\"o\">.</span><span class=\"n\">format</span><span class=\"p\">(</span>\n                        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"vm\">__class__</span><span class=\"o\">.</span><span class=\"vm\">__name__</span><span class=\"p\">,</span> <span class=\"n\">pickle_version</span><span class=\"p\">,</span> <span class=\"n\">__version__</span><span class=\"p\">),</span>\n                    <span class=\"ne\">UserWarning</span><span class=\"p\">)</span>\n        <span class=\"k\">try</span><span class=\"p\">:</span>\n            <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">__setstate__</span><span class=\"p\">(</span><span class=\"n\">state</span><span class=\"p\">)</span>\n        <span class=\"k\">except</span> <span class=\"ne\">AttributeError</span><span class=\"p\">:</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"vm\">__dict__</span><span class=\"o\">.</span><span class=\"n\">update</span><span class=\"p\">(</span><span class=\"n\">state</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">_get_tags</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"n\">collected_tags</span> <span class=\"o\">=</span> <span class=\"p\">{}</span>\n        <span class=\"k\">for</span> <span class=\"n\">base_class</span> <span class=\"ow\">in</span> <span class=\"n\">inspect</span><span class=\"o\">.</span><span class=\"n\">getmro</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"vm\">__class__</span><span class=\"p\">):</span>\n            <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nb\">hasattr</span><span class=\"p\">(</span><span class=\"n\">base_class</span><span class=\"p\">,</span> <span class=\"s1\">&#39;_more_tags&#39;</span><span class=\"p\">)</span>\n                    <span class=\"ow\">and</span> <span class=\"n\">base_class</span> <span class=\"o\">!=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"vm\">__class__</span><span class=\"p\">):</span>\n                <span class=\"n\">more_tags</span> <span class=\"o\">=</span> <span class=\"n\">base_class</span><span class=\"o\">.</span><span class=\"n\">_more_tags</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">)</span>\n                <span class=\"n\">collected_tags</span> <span class=\"o\">=</span> <span class=\"n\">_update_if_consistent</span><span class=\"p\">(</span><span class=\"n\">collected_tags</span><span class=\"p\">,</span>\n                                                       <span class=\"n\">more_tags</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"nb\">hasattr</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"s1\">&#39;_more_tags&#39;</span><span class=\"p\">):</span>\n            <span class=\"n\">more_tags</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_more_tags</span><span class=\"p\">()</span>\n            <span class=\"n\">collected_tags</span> <span class=\"o\">=</span> <span class=\"n\">_update_if_consistent</span><span class=\"p\">(</span><span class=\"n\">collected_tags</span><span class=\"p\">,</span> <span class=\"n\">more_tags</span><span class=\"p\">)</span>\n        <span class=\"n\">tags</span> <span class=\"o\">=</span> <span class=\"n\">_DEFAULT_TAGS</span><span class=\"o\">.</span><span class=\"n\">copy</span><span class=\"p\">()</span>\n        <span class=\"n\">tags</span><span class=\"o\">.</span><span class=\"n\">update</span><span class=\"p\">(</span><span class=\"n\">collected_tags</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"n\">tags</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">ClassifierMixin</span><span class=\"p\">:</span>\n    <span class=\"sd\">&quot;&quot;&quot;Mixin class for all classifiers in scikit-learn.&quot;&quot;&quot;</span>\n    <span class=\"n\">_estimator_type</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;classifier&quot;</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">score</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"p\">,</span> <span class=\"n\">sample_weight</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Returns the mean accuracy on the given test data and labels.</span>\n\n<span class=\"sd\">        In multi-label classification, this is the subset accuracy</span>\n<span class=\"sd\">        which is a harsh metric since you require for each sample that</span>\n<span class=\"sd\">        each label set be correctly predicted.</span>\n\n<span class=\"sd\">        Parameters</span>\n<span class=\"sd\">        ----------</span>\n<span class=\"sd\">        X : array-like, shape = (n_samples, n_features)</span>\n<span class=\"sd\">            Test samples.</span>\n\n<span class=\"sd\">        y : array-like, shape = (n_samples) or (n_samples, n_outputs)</span>\n<span class=\"sd\">            True labels for X.</span>\n\n<span class=\"sd\">        sample_weight : array-like, shape = [n_samples], optional</span>\n<span class=\"sd\">            Sample weights.</span>\n\n<span class=\"sd\">        Returns</span>\n<span class=\"sd\">        -------</span>\n<span class=\"sd\">        score : float</span>\n<span class=\"sd\">            Mean accuracy of self.predict(X) wrt. y.</span>\n\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"kn\">from</span> <span class=\"nn\">.metrics</span> <span class=\"k\">import</span> <span class=\"n\">accuracy_score</span>\n        <span class=\"k\">return</span> <span class=\"n\">accuracy_score</span><span class=\"p\">(</span><span class=\"n\">y</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">predict</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">),</span> <span class=\"n\">sample_weight</span><span class=\"o\">=</span><span class=\"n\">sample_weight</span><span class=\"p\">)</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">RegressorMixin</span><span class=\"p\">:</span>\n    <span class=\"sd\">&quot;&quot;&quot;Mixin class for all regression estimators in scikit-learn.&quot;&quot;&quot;</span>\n    <span class=\"n\">_estimator_type</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;regressor&quot;</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">score</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"p\">,</span> <span class=\"n\">sample_weight</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Returns the coefficient of determination R^2 of the prediction.</span>\n\n<span class=\"sd\">        The coefficient R^2 is defined as (1 - u/v), where u is the residual</span>\n<span class=\"sd\">        sum of squares ((y_true - y_pred) ** 2).sum() and v is the total</span>\n<span class=\"sd\">        sum of squares ((y_true - y_true.mean()) ** 2).sum().</span>\n<span class=\"sd\">        The best possible score is 1.0 and it can be negative (because the</span>\n<span class=\"sd\">        model can be arbitrarily worse). A constant model that always</span>\n<span class=\"sd\">        predicts the expected value of y, disregarding the input features,</span>\n<span class=\"sd\">        would get a R^2 score of 0.0.</span>\n\n<span class=\"sd\">        Parameters</span>\n<span class=\"sd\">        ----------</span>\n<span class=\"sd\">        X : array-like, shape = (n_samples, n_features)</span>\n<span class=\"sd\">            Test samples. For some estimators this may be a</span>\n<span class=\"sd\">            precomputed kernel matrix instead, shape = (n_samples,</span>\n<span class=\"sd\">            n_samples_fitted], where n_samples_fitted is the number of</span>\n<span class=\"sd\">            samples used in the fitting for the estimator.</span>\n\n<span class=\"sd\">        y : array-like, shape = (n_samples) or (n_samples, n_outputs)</span>\n<span class=\"sd\">            True values for X.</span>\n\n<span class=\"sd\">        sample_weight : array-like, shape = [n_samples], optional</span>\n<span class=\"sd\">            Sample weights.</span>\n\n<span class=\"sd\">        Returns</span>\n<span class=\"sd\">        -------</span>\n<span class=\"sd\">        score : float</span>\n<span class=\"sd\">            R^2 of self.predict(X) wrt. y.</span>\n\n<span class=\"sd\">        Notes</span>\n<span class=\"sd\">        -----</span>\n<span class=\"sd\">        The R2 score used when calling ``score`` on a regressor will use</span>\n<span class=\"sd\">        ``multioutput=&#39;uniform_average&#39;`` from version 0.23 to keep consistent</span>\n<span class=\"sd\">        with `metrics.r2_score`. This will influence the ``score`` method of</span>\n<span class=\"sd\">        all the multioutput regressors (except for</span>\n<span class=\"sd\">        `multioutput.MultiOutputRegressor`). To specify the default value</span>\n<span class=\"sd\">        manually and avoid the warning, please either call `metrics.r2_score`</span>\n<span class=\"sd\">        directly or make a custom scorer with `metrics.make_scorer` (the</span>\n<span class=\"sd\">        built-in scorer ``&#39;r2&#39;`` uses ``multioutput=&#39;uniform_average&#39;``).</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n\n        <span class=\"kn\">from</span> <span class=\"nn\">.metrics</span> <span class=\"k\">import</span> <span class=\"n\">r2_score</span>\n        <span class=\"kn\">from</span> <span class=\"nn\">.metrics.regression</span> <span class=\"k\">import</span> <span class=\"n\">_check_reg_targets</span>\n        <span class=\"n\">y_pred</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">predict</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span>\n        <span class=\"c1\"># XXX: Remove the check in 0.23</span>\n        <span class=\"n\">y_type</span><span class=\"p\">,</span> <span class=\"n\">_</span><span class=\"p\">,</span> <span class=\"n\">_</span><span class=\"p\">,</span> <span class=\"n\">_</span> <span class=\"o\">=</span> <span class=\"n\">_check_reg_targets</span><span class=\"p\">(</span><span class=\"n\">y</span><span class=\"p\">,</span> <span class=\"n\">y_pred</span><span class=\"p\">,</span> <span class=\"kc\">None</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"n\">y_type</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;continuous-multioutput&#39;</span><span class=\"p\">:</span>\n            <span class=\"n\">warnings</span><span class=\"o\">.</span><span class=\"n\">warn</span><span class=\"p\">(</span><span class=\"s2\">&quot;The default value of multioutput (not exposed in &quot;</span>\n                          <span class=\"s2\">&quot;score method) will change from &#39;variance_weighted&#39; &quot;</span>\n                          <span class=\"s2\">&quot;to &#39;uniform_average&#39; in 0.23 to keep consistent &quot;</span>\n                          <span class=\"s2\">&quot;with &#39;metrics.r2_score&#39;. To specify the default &quot;</span>\n                          <span class=\"s2\">&quot;value manually and avoid the warning, please &quot;</span>\n                          <span class=\"s2\">&quot;either call &#39;metrics.r2_score&#39; directly or make a &quot;</span>\n                          <span class=\"s2\">&quot;custom scorer with &#39;metrics.make_scorer&#39; (the &quot;</span>\n                          <span class=\"s2\">&quot;built-in scorer &#39;r2&#39; uses &quot;</span>\n                          <span class=\"s2\">&quot;multioutput=&#39;uniform_average&#39;).&quot;</span><span class=\"p\">,</span> <span class=\"ne\">FutureWarning</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"n\">r2_score</span><span class=\"p\">(</span><span class=\"n\">y</span><span class=\"p\">,</span> <span class=\"n\">y_pred</span><span class=\"p\">,</span> <span class=\"n\">sample_weight</span><span class=\"o\">=</span><span class=\"n\">sample_weight</span><span class=\"p\">,</span>\n                        <span class=\"n\">multioutput</span><span class=\"o\">=</span><span class=\"s1\">&#39;variance_weighted&#39;</span><span class=\"p\">)</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">ClusterMixin</span><span class=\"p\">:</span>\n    <span class=\"sd\">&quot;&quot;&quot;Mixin class for all cluster estimators in scikit-learn.&quot;&quot;&quot;</span>\n    <span class=\"n\">_estimator_type</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;clusterer&quot;</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">fit_predict</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Performs clustering on X and returns cluster labels.</span>\n\n<span class=\"sd\">        Parameters</span>\n<span class=\"sd\">        ----------</span>\n<span class=\"sd\">        X : ndarray, shape (n_samples, n_features)</span>\n<span class=\"sd\">            Input data.</span>\n\n<span class=\"sd\">        y : Ignored</span>\n<span class=\"sd\">            not used, present for API consistency by convention.</span>\n\n<span class=\"sd\">        Returns</span>\n<span class=\"sd\">        -------</span>\n<span class=\"sd\">        labels : ndarray, shape (n_samples,)</span>\n<span class=\"sd\">            cluster labels</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"c1\"># non-optimized default implementation; override when a better</span>\n        <span class=\"c1\"># method is possible for a given clustering algorithm</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">fit</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">labels_</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">BiclusterMixin</span><span class=\"p\">:</span>\n    <span class=\"sd\">&quot;&quot;&quot;Mixin class for all bicluster estimators in scikit-learn&quot;&quot;&quot;</span>\n\n    <span class=\"nd\">@property</span>\n    <span class=\"k\">def</span> <span class=\"nf\">biclusters_</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Convenient way to get row and column indicators together.</span>\n\n<span class=\"sd\">        Returns the ``rows_`` and ``columns_`` members.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">rows_</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">columns_</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">get_indices</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">i</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Row and column indices of the i&#39;th bicluster.</span>\n\n<span class=\"sd\">        Only works if ``rows_`` and ``columns_`` attributes exist.</span>\n\n<span class=\"sd\">        Parameters</span>\n<span class=\"sd\">        ----------</span>\n<span class=\"sd\">        i : int</span>\n<span class=\"sd\">            The index of the cluster.</span>\n\n<span class=\"sd\">        Returns</span>\n<span class=\"sd\">        -------</span>\n<span class=\"sd\">        row_ind : np.array, dtype=np.intp</span>\n<span class=\"sd\">            Indices of rows in the dataset that belong to the bicluster.</span>\n<span class=\"sd\">        col_ind : np.array, dtype=np.intp</span>\n<span class=\"sd\">            Indices of columns in the dataset that belong to the bicluster.</span>\n\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"n\">rows</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">rows_</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span>\n        <span class=\"n\">columns</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">columns_</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span>\n        <span class=\"k\">return</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">nonzero</span><span class=\"p\">(</span><span class=\"n\">rows</span><span class=\"p\">)[</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">nonzero</span><span class=\"p\">(</span><span class=\"n\">columns</span><span class=\"p\">)[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">get_shape</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">i</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Shape of the i&#39;th bicluster.</span>\n\n<span class=\"sd\">        Parameters</span>\n<span class=\"sd\">        ----------</span>\n<span class=\"sd\">        i : int</span>\n<span class=\"sd\">            The index of the cluster.</span>\n\n<span class=\"sd\">        Returns</span>\n<span class=\"sd\">        -------</span>\n<span class=\"sd\">        shape : (int, int)</span>\n<span class=\"sd\">            Number of rows and columns (resp.) in the bicluster.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"n\">indices</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">get_indices</span><span class=\"p\">(</span><span class=\"n\">i</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"nb\">tuple</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">i</span><span class=\"p\">)</span> <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"n\">indices</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">get_submatrix</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">data</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Returns the submatrix corresponding to bicluster `i`.</span>\n\n<span class=\"sd\">        Parameters</span>\n<span class=\"sd\">        ----------</span>\n<span class=\"sd\">        i : int</span>\n<span class=\"sd\">            The index of the cluster.</span>\n<span class=\"sd\">        data : array</span>\n<span class=\"sd\">            The data.</span>\n\n<span class=\"sd\">        Returns</span>\n<span class=\"sd\">        -------</span>\n<span class=\"sd\">        submatrix : array</span>\n<span class=\"sd\">            The submatrix corresponding to bicluster i.</span>\n\n<span class=\"sd\">        Notes</span>\n<span class=\"sd\">        -----</span>\n<span class=\"sd\">        Works with sparse matrices. Only works if ``rows_`` and</span>\n<span class=\"sd\">        ``columns_`` attributes exist.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"kn\">from</span> <span class=\"nn\">.utils.validation</span> <span class=\"k\">import</span> <span class=\"n\">check_array</span>\n        <span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"n\">check_array</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">,</span> <span class=\"n\">accept_sparse</span><span class=\"o\">=</span><span class=\"s1\">&#39;csr&#39;</span><span class=\"p\">)</span>\n        <span class=\"n\">row_ind</span><span class=\"p\">,</span> <span class=\"n\">col_ind</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">get_indices</span><span class=\"p\">(</span><span class=\"n\">i</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"n\">data</span><span class=\"p\">[</span><span class=\"n\">row_ind</span><span class=\"p\">[:,</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">newaxis</span><span class=\"p\">],</span> <span class=\"n\">col_ind</span><span class=\"p\">]</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">TransformerMixin</span><span class=\"p\">:</span>\n    <span class=\"sd\">&quot;&quot;&quot;Mixin class for all transformers in scikit-learn.&quot;&quot;&quot;</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">fit_transform</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">fit_params</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Fit to data, then transform it.</span>\n\n<span class=\"sd\">        Fits transformer to X and y with optional parameters fit_params</span>\n<span class=\"sd\">        and returns a transformed version of X.</span>\n\n<span class=\"sd\">        Parameters</span>\n<span class=\"sd\">        ----------</span>\n<span class=\"sd\">        X : numpy array of shape [n_samples, n_features]</span>\n<span class=\"sd\">            Training set.</span>\n\n<span class=\"sd\">        y : numpy array of shape [n_samples]</span>\n<span class=\"sd\">            Target values.</span>\n\n<span class=\"sd\">        Returns</span>\n<span class=\"sd\">        -------</span>\n<span class=\"sd\">        X_new : numpy array of shape [n_samples, n_features_new]</span>\n<span class=\"sd\">            Transformed array.</span>\n\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"c1\"># non-optimized default implementation; override when a better</span>\n        <span class=\"c1\"># method is possible for a given clustering algorithm</span>\n        <span class=\"k\">if</span> <span class=\"n\">y</span> <span class=\"ow\">is</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n            <span class=\"c1\"># fit method of arity 1 (unsupervised transformation)</span>\n            <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">fit</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">fit_params</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">transform</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"c1\"># fit method of arity 2 (supervised transformation)</span>\n            <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">fit</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">fit_params</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">transform</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">DensityMixin</span><span class=\"p\">:</span>\n    <span class=\"sd\">&quot;&quot;&quot;Mixin class for all density estimators in scikit-learn.&quot;&quot;&quot;</span>\n    <span class=\"n\">_estimator_type</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;DensityEstimator&quot;</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">score</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Returns the score of the model on the data X</span>\n\n<span class=\"sd\">        Parameters</span>\n<span class=\"sd\">        ----------</span>\n<span class=\"sd\">        X : array-like, shape = (n_samples, n_features)</span>\n\n<span class=\"sd\">        Returns</span>\n<span class=\"sd\">        -------</span>\n<span class=\"sd\">        score : float</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"k\">pass</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">OutlierMixin</span><span class=\"p\">:</span>\n    <span class=\"sd\">&quot;&quot;&quot;Mixin class for all outlier detection estimators in scikit-learn.&quot;&quot;&quot;</span>\n    <span class=\"n\">_estimator_type</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;outlier_detector&quot;</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">fit_predict</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">X</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"sd\">&quot;&quot;&quot;Performs fit on X and returns labels for X.</span>\n\n<span class=\"sd\">        Returns -1 for outliers and 1 for inliers.</span>\n\n<span class=\"sd\">        Parameters</span>\n<span class=\"sd\">        ----------</span>\n<span class=\"sd\">        X : ndarray, shape (n_samples, n_features)</span>\n<span class=\"sd\">            Input data.</span>\n\n<span class=\"sd\">        y : Ignored</span>\n<span class=\"sd\">            not used, present for API consistency by convention.</span>\n\n<span class=\"sd\">        Returns</span>\n<span class=\"sd\">        -------</span>\n<span class=\"sd\">        y : ndarray, shape (n_samples,)</span>\n<span class=\"sd\">            1 for inliers, -1 for outliers.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"c1\"># override for transductive outlier detectors like LocalOulierFactor</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">fit</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">predict</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">MetaEstimatorMixin</span><span class=\"p\">:</span>\n    <span class=\"n\">_required_parameters</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s2\">&quot;estimator&quot;</span><span class=\"p\">]</span>\n    <span class=\"sd\">&quot;&quot;&quot;Mixin class for all meta estimators in scikit-learn.&quot;&quot;&quot;</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">MultiOutputMixin</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Mixin to mark estimators that support multioutput.&quot;&quot;&quot;</span>\n    <span class=\"k\">def</span> <span class=\"nf\">_more_tags</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"p\">{</span><span class=\"s1\">&#39;multioutput&#39;</span><span class=\"p\">:</span> <span class=\"kc\">True</span><span class=\"p\">}</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">_UnstableArchMixin</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Mark estimators that are non-determinstic on 32bit or PowerPC&quot;&quot;&quot;</span>\n    <span class=\"k\">def</span> <span class=\"nf\">_more_tags</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"p\">{</span><span class=\"s1\">&#39;non_deterministic&#39;</span><span class=\"p\">:</span> <span class=\"p\">(</span>\n            <span class=\"n\">_IS_32BIT</span> <span class=\"ow\">or</span> <span class=\"n\">platform</span><span class=\"o\">.</span><span class=\"n\">machine</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">startswith</span><span class=\"p\">((</span><span class=\"s1\">&#39;ppc&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;powerpc&#39;</span><span class=\"p\">)))}</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">is_classifier</span><span class=\"p\">(</span><span class=\"n\">estimator</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Returns True if the given estimator is (probably) a classifier.</span>\n\n<span class=\"sd\">    Parameters</span>\n<span class=\"sd\">    ----------</span>\n<span class=\"sd\">    estimator : object</span>\n<span class=\"sd\">        Estimator object to test.</span>\n\n<span class=\"sd\">    Returns</span>\n<span class=\"sd\">    -------</span>\n<span class=\"sd\">    out : bool</span>\n<span class=\"sd\">        True if estimator is a classifier and False otherwise.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"k\">return</span> <span class=\"nb\">getattr</span><span class=\"p\">(</span><span class=\"n\">estimator</span><span class=\"p\">,</span> <span class=\"s2\">&quot;_estimator_type&quot;</span><span class=\"p\">,</span> <span class=\"kc\">None</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"s2\">&quot;classifier&quot;</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">is_regressor</span><span class=\"p\">(</span><span class=\"n\">estimator</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Returns True if the given estimator is (probably) a regressor.</span>\n\n<span class=\"sd\">    Parameters</span>\n<span class=\"sd\">    ----------</span>\n<span class=\"sd\">    estimator : object</span>\n<span class=\"sd\">        Estimator object to test.</span>\n\n<span class=\"sd\">    Returns</span>\n<span class=\"sd\">    -------</span>\n<span class=\"sd\">    out : bool</span>\n<span class=\"sd\">        True if estimator is a regressor and False otherwise.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"k\">return</span> <span class=\"nb\">getattr</span><span class=\"p\">(</span><span class=\"n\">estimator</span><span class=\"p\">,</span> <span class=\"s2\">&quot;_estimator_type&quot;</span><span class=\"p\">,</span> <span class=\"kc\">None</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"s2\">&quot;regressor&quot;</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">is_outlier_detector</span><span class=\"p\">(</span><span class=\"n\">estimator</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Returns True if the given estimator is (probably) an outlier detector.</span>\n\n<span class=\"sd\">    Parameters</span>\n<span class=\"sd\">    ----------</span>\n<span class=\"sd\">    estimator : object</span>\n<span class=\"sd\">        Estimator object to test.</span>\n\n<span class=\"sd\">    Returns</span>\n<span class=\"sd\">    -------</span>\n<span class=\"sd\">    out : bool</span>\n<span class=\"sd\">        True if estimator is an outlier detector and False otherwise.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"k\">return</span> <span class=\"nb\">getattr</span><span class=\"p\">(</span><span class=\"n\">estimator</span><span class=\"p\">,</span> <span class=\"s2\">&quot;_estimator_type&quot;</span><span class=\"p\">,</span> <span class=\"kc\">None</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"s2\">&quot;outlier_detector&quot;</span>\n</pre></div>\n\n          </div>\n          \n        </div>\n      </div>\n      <div class=\"sphinxsidebar\" role=\"navigation\" aria-label=\"main navigation\">\n        <div class=\"sphinxsidebarwrapper\">\n<h1 class=\"logo\"><a href=\"../../index.html\">k-means-constrained</a></h1>\n\n\n\n\n\n\n\n\n<h3>Navigation</h3>\n\n<div class=\"relations\">\n<h3>Related Topics</h3>\n<ul>\n  <li><a href=\"../../index.html\">Documentation overview</a><ul>\n  <li><a href=\"../index.html\">Module code</a><ul>\n  </ul></li>\n  </ul></li>\n</ul>\n</div>\n<div id=\"searchbox\" style=\"display: none\" role=\"search\">\n  <h3 id=\"searchlabel\">Quick search</h3>\n    <div class=\"searchformwrapper\">\n    <form class=\"search\" action=\"../../search.html\" method=\"get\">\n      <input type=\"text\" name=\"q\" aria-labelledby=\"searchlabel\" />\n      <input type=\"submit\" value=\"Go\" />\n    </form>\n    </div>\n</div>\n<script type=\"text/javascript\">$('#searchbox').show(0);</script>\n\n\n\n\n\n\n\n\n        </div>\n      </div>\n      <div class=\"clearer\"></div>\n    </div>\n    <div class=\"footer\">\n      &copy;2020, Josh Levy-Kramer.\n      \n      |\n      Powered by <a href=\"http://sphinx-doc.org/\">Sphinx 2.2.0</a>\n      &amp; <a href=\"https://github.com/bitprophet/alabaster\">Alabaster 0.7.12</a>\n      \n    </div>\n\n    \n\n    \n  </body>\n</html>"
  },
  {
    "path": "docs/_sources/index.rst.txt",
    "content": ".. k-means-constrained documentation master file, created by\n   sphinx-quickstart on Fri Mar  6 13:31:12 2020.\n   You can adapt this file completely to your liking, but it should at least\n   contain the root `toctree` directive.\n\nWelcome to k-means-constrained's documentation!\n===============================================\n\nThe GitHub project can be found `here <https://github.com/joshlk/k-means-constrained>`_.\n\nTo install k-means-constrained using pip:\n\n.. code-block:: python\n\n   pip install k-means-constrained\n\n\nAPI documentation:\n\n\n.. automodule:: k_means_constrained\n   :members:\n   :undoc-members:\n   :inherited-members:\n\n\n\n\n\n"
  },
  {
    "path": "docs/_sources/modules.rst.txt",
    "content": "k_means_constrained\n===================\n\n.. toctree::\n   :maxdepth: 4\n\n   k_means_constrained\n"
  },
  {
    "path": "docs/_static/alabaster.css",
    "content": "@import url(\"basic.css\");\n\n/* -- page layout ----------------------------------------------------------- */\n\nbody {\n    font-family: Georgia, serif;\n    font-size: 17px;\n    background-color: #fff;\n    color: #000;\n    margin: 0;\n    padding: 0;\n}\n\n\ndiv.document {\n    width: 940px;\n    margin: 30px auto 0 auto;\n}\n\ndiv.documentwrapper {\n    float: left;\n    width: 100%;\n}\n\ndiv.bodywrapper {\n    margin: 0 0 0 220px;\n}\n\ndiv.sphinxsidebar {\n    width: 220px;\n    font-size: 14px;\n    line-height: 1.5;\n}\n\nhr {\n    border: 1px solid #B1B4B6;\n}\n\ndiv.body {\n    background-color: #fff;\n    color: #3E4349;\n    padding: 0 30px 0 30px;\n}\n\ndiv.body > .section {\n    text-align: left;\n}\n\ndiv.footer {\n    width: 940px;\n    margin: 20px auto 30px auto;\n    font-size: 14px;\n    color: #888;\n    text-align: right;\n}\n\ndiv.footer a {\n    color: #888;\n}\n\np.caption {\n    font-family: inherit;\n    font-size: inherit;\n}\n\n\ndiv.relations {\n    display: none;\n}\n\n\ndiv.sphinxsidebar a {\n    color: #444;\n    text-decoration: none;\n    border-bottom: 1px dotted #999;\n}\n\ndiv.sphinxsidebar a:hover {\n    border-bottom: 1px solid #999;\n}\n\ndiv.sphinxsidebarwrapper {\n    padding: 18px 10px;\n}\n\ndiv.sphinxsidebarwrapper p.logo {\n    padding: 0;\n    margin: -10px 0 0 0px;\n    text-align: center;\n}\n\ndiv.sphinxsidebarwrapper h1.logo {\n    margin-top: -10px;\n    text-align: center;\n    margin-bottom: 5px;\n    text-align: left;\n}\n\ndiv.sphinxsidebarwrapper h1.logo-name {\n    margin-top: 0px;\n}\n\ndiv.sphinxsidebarwrapper p.blurb {\n    margin-top: 0;\n    font-style: normal;\n}\n\ndiv.sphinxsidebar h3,\ndiv.sphinxsidebar h4 {\n    font-family: Georgia, serif;\n    color: #444;\n    font-size: 24px;\n    font-weight: normal;\n    margin: 0 0 5px 0;\n    padding: 0;\n}\n\ndiv.sphinxsidebar h4 {\n    font-size: 20px;\n}\n\ndiv.sphinxsidebar h3 a {\n    color: #444;\n}\n\ndiv.sphinxsidebar p.logo a,\ndiv.sphinxsidebar h3 a,\ndiv.sphinxsidebar p.logo a:hover,\ndiv.sphinxsidebar h3 a:hover {\n    border: none;\n}\n\ndiv.sphinxsidebar p {\n    color: #555;\n    margin: 10px 0;\n}\n\ndiv.sphinxsidebar ul {\n    margin: 10px 0;\n    padding: 0;\n    color: #000;\n}\n\ndiv.sphinxsidebar ul li.toctree-l1 > a {\n    font-size: 120%;\n}\n\ndiv.sphinxsidebar ul li.toctree-l2 > a {\n    font-size: 110%;\n}\n\ndiv.sphinxsidebar input {\n    border: 1px solid #CCC;\n    font-family: Georgia, serif;\n    font-size: 1em;\n}\n\ndiv.sphinxsidebar hr {\n    border: none;\n    height: 1px;\n    color: #AAA;\n    background: #AAA;\n\n    text-align: left;\n    margin-left: 0;\n    width: 50%;\n}\n\ndiv.sphinxsidebar .badge {\n    border-bottom: none;\n}\n\ndiv.sphinxsidebar .badge:hover {\n    border-bottom: none;\n}\n\n/* To address an issue with donation coming after search */\ndiv.sphinxsidebar h3.donation {\n    margin-top: 10px;\n}\n\n/* -- body styles ----------------------------------------------------------- */\n\na {\n    color: #004B6B;\n    text-decoration: underline;\n}\n\na:hover {\n    color: #6D4100;\n    text-decoration: underline;\n}\n\ndiv.body h1,\ndiv.body h2,\ndiv.body h3,\ndiv.body h4,\ndiv.body h5,\ndiv.body h6 {\n    font-family: Georgia, serif;\n    font-weight: normal;\n    margin: 30px 0px 10px 0px;\n    padding: 0;\n}\n\ndiv.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; }\ndiv.body h2 { font-size: 180%; }\ndiv.body h3 { font-size: 150%; }\ndiv.body h4 { font-size: 130%; }\ndiv.body h5 { font-size: 100%; }\ndiv.body h6 { font-size: 100%; }\n\na.headerlink {\n    color: #DDD;\n    padding: 0 4px;\n    text-decoration: none;\n}\n\na.headerlink:hover {\n    color: #444;\n    background: #EAEAEA;\n}\n\ndiv.body p, div.body dd, div.body li {\n    line-height: 1.4em;\n}\n\ndiv.admonition {\n    margin: 20px 0px;\n    padding: 10px 30px;\n    background-color: #EEE;\n    border: 1px solid #CCC;\n}\n\ndiv.admonition tt.xref, div.admonition code.xref, div.admonition a tt {\n    background-color: #FBFBFB;\n    border-bottom: 1px solid #fafafa;\n}\n\ndiv.admonition p.admonition-title {\n    font-family: Georgia, serif;\n    font-weight: normal;\n    font-size: 24px;\n    margin: 0 0 10px 0;\n    padding: 0;\n    line-height: 1;\n}\n\ndiv.admonition p.last {\n    margin-bottom: 0;\n}\n\ndiv.highlight {\n    background-color: #fff;\n}\n\ndt:target, .highlight {\n    background: #FAF3E8;\n}\n\ndiv.warning {\n    background-color: #FCC;\n    border: 1px solid #FAA;\n}\n\ndiv.danger {\n    background-color: #FCC;\n    border: 1px solid #FAA;\n    -moz-box-shadow: 2px 2px 4px #D52C2C;\n    -webkit-box-shadow: 2px 2px 4px #D52C2C;\n    box-shadow: 2px 2px 4px #D52C2C;\n}\n\ndiv.error {\n    background-color: #FCC;\n    border: 1px solid #FAA;\n    -moz-box-shadow: 2px 2px 4px #D52C2C;\n    -webkit-box-shadow: 2px 2px 4px #D52C2C;\n    box-shadow: 2px 2px 4px #D52C2C;\n}\n\ndiv.caution {\n    background-color: #FCC;\n    border: 1px solid #FAA;\n}\n\ndiv.attention {\n    background-color: #FCC;\n    border: 1px solid #FAA;\n}\n\ndiv.important {\n    background-color: #EEE;\n    border: 1px solid #CCC;\n}\n\ndiv.note {\n    background-color: #EEE;\n    border: 1px solid #CCC;\n}\n\ndiv.tip {\n    background-color: #EEE;\n    border: 1px solid #CCC;\n}\n\ndiv.hint {\n    background-color: #EEE;\n    border: 1px solid #CCC;\n}\n\ndiv.seealso {\n    background-color: #EEE;\n    border: 1px solid #CCC;\n}\n\ndiv.topic {\n    background-color: #EEE;\n}\n\np.admonition-title {\n    display: inline;\n}\n\np.admonition-title:after {\n    content: \":\";\n}\n\npre, tt, code {\n    font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;\n    font-size: 0.9em;\n}\n\n.hll {\n    background-color: #FFC;\n    margin: 0 -12px;\n    padding: 0 12px;\n    display: block;\n}\n\nimg.screenshot {\n}\n\ntt.descname, tt.descclassname, code.descname, code.descclassname {\n    font-size: 0.95em;\n}\n\ntt.descname, code.descname {\n    padding-right: 0.08em;\n}\n\nimg.screenshot {\n    -moz-box-shadow: 2px 2px 4px #EEE;\n    -webkit-box-shadow: 2px 2px 4px #EEE;\n    box-shadow: 2px 2px 4px #EEE;\n}\n\ntable.docutils {\n    border: 1px solid #888;\n    -moz-box-shadow: 2px 2px 4px #EEE;\n    -webkit-box-shadow: 2px 2px 4px #EEE;\n    box-shadow: 2px 2px 4px #EEE;\n}\n\ntable.docutils td, table.docutils th {\n    border: 1px solid #888;\n    padding: 0.25em 0.7em;\n}\n\ntable.field-list, table.footnote {\n    border: none;\n    -moz-box-shadow: none;\n    -webkit-box-shadow: none;\n    box-shadow: none;\n}\n\ntable.footnote {\n    margin: 15px 0;\n    width: 100%;\n    border: 1px solid #EEE;\n    background: #FDFDFD;\n    font-size: 0.9em;\n}\n\ntable.footnote + table.footnote {\n    margin-top: -15px;\n    border-top: none;\n}\n\ntable.field-list th {\n    padding: 0 0.8em 0 0;\n}\n\ntable.field-list td {\n    padding: 0;\n}\n\ntable.field-list p {\n    margin-bottom: 0.8em;\n}\n\n/* Cloned from\n * https://github.com/sphinx-doc/sphinx/commit/ef60dbfce09286b20b7385333d63a60321784e68\n */\n.field-name {\n    -moz-hyphens: manual;\n    -ms-hyphens: manual;\n    -webkit-hyphens: manual;\n    hyphens: manual;\n}\n\ntable.footnote td.label {\n    width: .1px;\n    padding: 0.3em 0 0.3em 0.5em;\n}\n\ntable.footnote td {\n    padding: 0.3em 0.5em;\n}\n\ndl {\n    margin: 0;\n    padding: 0;\n}\n\ndl dd {\n    margin-left: 30px;\n}\n\nblockquote {\n    margin: 0 0 0 30px;\n    padding: 0;\n}\n\nul, ol {\n    /* Matches the 30px from the narrow-screen \"li > ul\" selector below */\n    margin: 10px 0 10px 30px;\n    padding: 0;\n}\n\npre {\n    background: #EEE;\n    padding: 7px 30px;\n    margin: 15px 0px;\n    line-height: 1.3em;\n}\n\ndiv.viewcode-block:target {\n    background: #ffd;\n}\n\ndl pre, blockquote pre, li pre {\n    margin-left: 0;\n    padding-left: 30px;\n}\n\ntt, code {\n    background-color: #ecf0f3;\n    color: #222;\n    /* padding: 1px 2px; */\n}\n\ntt.xref, code.xref, a tt {\n    background-color: #FBFBFB;\n    border-bottom: 1px solid #fff;\n}\n\na.reference {\n    text-decoration: none;\n    border-bottom: 1px dotted #004B6B;\n}\n\n/* Don't put an underline on images */\na.image-reference, a.image-reference:hover {\n    border-bottom: none;\n}\n\na.reference:hover {\n    border-bottom: 1px solid #6D4100;\n}\n\na.footnote-reference {\n    text-decoration: none;\n    font-size: 0.7em;\n    vertical-align: top;\n    border-bottom: 1px dotted #004B6B;\n}\n\na.footnote-reference:hover {\n    border-bottom: 1px solid #6D4100;\n}\n\na:hover tt, a:hover code {\n    background: #EEE;\n}\n\n\n@media screen and (max-width: 870px) {\n\n    div.sphinxsidebar {\n    \tdisplay: none;\n    }\n\n    div.document {\n       width: 100%;\n\n    }\n\n    div.documentwrapper {\n    \tmargin-left: 0;\n    \tmargin-top: 0;\n    \tmargin-right: 0;\n    \tmargin-bottom: 0;\n    }\n\n    div.bodywrapper {\n    \tmargin-top: 0;\n    \tmargin-right: 0;\n    \tmargin-bottom: 0;\n    \tmargin-left: 0;\n    }\n\n    ul {\n    \tmargin-left: 0;\n    }\n\n\tli > ul {\n        /* Matches the 30px from the \"ul, ol\" selector above */\n\t\tmargin-left: 30px;\n\t}\n\n    .document {\n    \twidth: auto;\n    }\n\n    .footer {\n    \twidth: auto;\n    }\n\n    .bodywrapper {\n    \tmargin: 0;\n    }\n\n    .footer {\n    \twidth: auto;\n    }\n\n    .github {\n        display: none;\n    }\n\n\n\n}\n\n\n\n@media screen and (max-width: 875px) {\n\n    body {\n        margin: 0;\n        padding: 20px 30px;\n    }\n\n    div.documentwrapper {\n        float: none;\n        background: #fff;\n    }\n\n    div.sphinxsidebar {\n        display: block;\n        float: none;\n        width: 102.5%;\n        margin: 50px -30px -20px -30px;\n        padding: 10px 20px;\n        background: #333;\n        color: #FFF;\n    }\n\n    div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p,\n    div.sphinxsidebar h3 a {\n        color: #fff;\n    }\n\n    div.sphinxsidebar a {\n        color: #AAA;\n    }\n\n    div.sphinxsidebar p.logo {\n        display: none;\n    }\n\n    div.document {\n        width: 100%;\n        margin: 0;\n    }\n\n    div.footer {\n        display: none;\n    }\n\n    div.bodywrapper {\n        margin: 0;\n    }\n\n    div.body {\n        min-height: 0;\n        padding: 0;\n    }\n\n    .rtd_doc_footer {\n        display: none;\n    }\n\n    .document {\n        width: auto;\n    }\n\n    .footer {\n        width: auto;\n    }\n\n    .footer {\n        width: auto;\n    }\n\n    .github {\n        display: none;\n    }\n}\n\n\n/* misc. */\n\n.revsys-inline {\n    display: none!important;\n}\n\n/* Make nested-list/multi-paragraph items look better in Releases changelog\n * pages. Without this, docutils' magical list fuckery causes inconsistent\n * formatting between different release sub-lists.\n */\ndiv#changelog > div.section > ul > li > p:only-child {\n    margin-bottom: 0;\n}\n\n/* Hide fugly table cell borders in ..bibliography:: directive output */\ntable.docutils.citation, table.docutils.citation td, table.docutils.citation th {\n  border: none;\n  /* Below needed in some edge cases; if not applied, bottom shadows appear */\n  -moz-box-shadow: none;\n  -webkit-box-shadow: none;\n  box-shadow: none;\n}\n\n\n/* relbar */\n\n.related {\n    line-height: 30px;\n    width: 100%;\n    font-size: 0.9rem;\n}\n\n.related.top {\n    border-bottom: 1px solid #EEE;\n    margin-bottom: 20px;\n}\n\n.related.bottom {\n    border-top: 1px solid #EEE;\n}\n\n.related ul {\n    padding: 0;\n    margin: 0;\n    list-style: none;\n}\n\n.related li {\n    display: inline;\n}\n\nnav#rellinks {\n    float: right;\n}\n\nnav#rellinks li+li:before {\n    content: \"|\";\n}\n\nnav#breadcrumbs li+li:before {\n    content: \"\\00BB\";\n}\n\n/* Hide certain items when printing */\n@media print {\n    div.related {\n        display: none;\n    }\n}"
  },
  {
    "path": "docs/_static/basic.css",
    "content": "/*\n * basic.css\n * ~~~~~~~~~\n *\n * Sphinx stylesheet -- basic theme.\n *\n * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.\n * :license: BSD, see LICENSE for details.\n *\n */\n\n/* -- main layout ----------------------------------------------------------- */\n\ndiv.clearer {\n    clear: both;\n}\n\ndiv.section::after {\n    display: block;\n    content: '';\n    clear: left;\n}\n\n/* -- relbar ---------------------------------------------------------------- */\n\ndiv.related {\n    width: 100%;\n    font-size: 90%;\n}\n\ndiv.related h3 {\n    display: none;\n}\n\ndiv.related ul {\n    margin: 0;\n    padding: 0 0 0 10px;\n    list-style: none;\n}\n\ndiv.related li {\n    display: inline;\n}\n\ndiv.related li.right {\n    float: right;\n    margin-right: 5px;\n}\n\n/* -- sidebar --------------------------------------------------------------- */\n\ndiv.sphinxsidebarwrapper {\n    padding: 10px 5px 0 10px;\n}\n\ndiv.sphinxsidebar {\n    float: left;\n    width: 230px;\n    margin-left: -100%;\n    font-size: 90%;\n    word-wrap: break-word;\n    overflow-wrap : break-word;\n}\n\ndiv.sphinxsidebar ul {\n    list-style: none;\n}\n\ndiv.sphinxsidebar ul ul,\ndiv.sphinxsidebar ul.want-points {\n    margin-left: 20px;\n    list-style: square;\n}\n\ndiv.sphinxsidebar ul ul {\n    margin-top: 0;\n    margin-bottom: 0;\n}\n\ndiv.sphinxsidebar form {\n    margin-top: 10px;\n}\n\ndiv.sphinxsidebar input {\n    border: 1px solid #98dbcc;\n    font-family: sans-serif;\n    font-size: 1em;\n}\n\ndiv.sphinxsidebar #searchbox form.search {\n    overflow: hidden;\n}\n\ndiv.sphinxsidebar #searchbox input[type=\"text\"] {\n    float: left;\n    width: 80%;\n    padding: 0.25em;\n    box-sizing: border-box;\n}\n\ndiv.sphinxsidebar #searchbox input[type=\"submit\"] {\n    float: left;\n    width: 20%;\n    border-left: none;\n    padding: 0.25em;\n    box-sizing: border-box;\n}\n\n\nimg {\n    border: 0;\n    max-width: 100%;\n}\n\n/* -- search page ----------------------------------------------------------- */\n\nul.search {\n    margin: 10px 0 0 20px;\n    padding: 0;\n}\n\nul.search li {\n    padding: 5px 0 5px 20px;\n    background-image: url(file.png);\n    background-repeat: no-repeat;\n    background-position: 0 7px;\n}\n\nul.search li a {\n    font-weight: bold;\n}\n\nul.search li p.context {\n    color: #888;\n    margin: 2px 0 0 30px;\n    text-align: left;\n}\n\nul.keywordmatches li.goodmatch a {\n    font-weight: bold;\n}\n\n/* -- index page ------------------------------------------------------------ */\n\ntable.contentstable {\n    width: 90%;\n    margin-left: auto;\n    margin-right: auto;\n}\n\ntable.contentstable p.biglink {\n    line-height: 150%;\n}\n\na.biglink {\n    font-size: 1.3em;\n}\n\nspan.linkdescr {\n    font-style: italic;\n    padding-top: 5px;\n    font-size: 90%;\n}\n\n/* -- general index --------------------------------------------------------- */\n\ntable.indextable {\n    width: 100%;\n}\n\ntable.indextable td {\n    text-align: left;\n    vertical-align: top;\n}\n\ntable.indextable ul {\n    margin-top: 0;\n    margin-bottom: 0;\n    list-style-type: none;\n}\n\ntable.indextable > tbody > tr > td > ul {\n    padding-left: 0em;\n}\n\ntable.indextable tr.pcap {\n    height: 10px;\n}\n\ntable.indextable tr.cap {\n    margin-top: 10px;\n    background-color: #f2f2f2;\n}\n\nimg.toggler {\n    margin-right: 3px;\n    margin-top: 3px;\n    cursor: pointer;\n}\n\ndiv.modindex-jumpbox {\n    border-top: 1px solid #ddd;\n    border-bottom: 1px solid #ddd;\n    margin: 1em 0 1em 0;\n    padding: 0.4em;\n}\n\ndiv.genindex-jumpbox {\n    border-top: 1px solid #ddd;\n    border-bottom: 1px solid #ddd;\n    margin: 1em 0 1em 0;\n    padding: 0.4em;\n}\n\n/* -- domain module index --------------------------------------------------- */\n\ntable.modindextable td {\n    padding: 2px;\n    border-collapse: collapse;\n}\n\n/* -- general body styles --------------------------------------------------- */\n\ndiv.body {\n    min-width: 450px;\n    max-width: 800px;\n}\n\ndiv.body p, div.body dd, div.body li, div.body blockquote {\n    -moz-hyphens: auto;\n    -ms-hyphens: auto;\n    -webkit-hyphens: auto;\n    hyphens: auto;\n}\n\na.headerlink {\n    visibility: hidden;\n}\n\na.brackets:before,\nspan.brackets > a:before{\n    content: \"[\";\n}\n\na.brackets:after,\nspan.brackets > a:after {\n    content: \"]\";\n}\n\nh1:hover > a.headerlink,\nh2:hover > a.headerlink,\nh3:hover > a.headerlink,\nh4:hover > a.headerlink,\nh5:hover > a.headerlink,\nh6:hover > a.headerlink,\ndt:hover > a.headerlink,\ncaption:hover > a.headerlink,\np.caption:hover > a.headerlink,\ndiv.code-block-caption:hover > a.headerlink {\n    visibility: visible;\n}\n\ndiv.body p.caption {\n    text-align: inherit;\n}\n\ndiv.body td {\n    text-align: left;\n}\n\n.first {\n    margin-top: 0 !important;\n}\n\np.rubric {\n    margin-top: 30px;\n    font-weight: bold;\n}\n\nimg.align-left, figure.align-left, .figure.align-left, object.align-left {\n    clear: left;\n    float: left;\n    margin-right: 1em;\n}\n\nimg.align-right, figure.align-right, .figure.align-right, object.align-right {\n    clear: right;\n    float: right;\n    margin-left: 1em;\n}\n\nimg.align-center, figure.align-center, .figure.align-center, object.align-center {\n  display: block;\n  margin-left: auto;\n  margin-right: auto;\n}\n\nimg.align-default, figure.align-default, .figure.align-default {\n  display: block;\n  margin-left: auto;\n  margin-right: auto;\n}\n\n.align-left {\n    text-align: left;\n}\n\n.align-center {\n    text-align: center;\n}\n\n.align-default {\n    text-align: center;\n}\n\n.align-right {\n    text-align: right;\n}\n\n/* -- sidebars -------------------------------------------------------------- */\n\ndiv.sidebar,\naside.sidebar {\n    margin: 0 0 0.5em 1em;\n    border: 1px solid #ddb;\n    padding: 7px;\n    background-color: #ffe;\n    width: 40%;\n    float: right;\n    clear: right;\n    overflow-x: auto;\n}\n\np.sidebar-title {\n    font-weight: bold;\n}\n\ndiv.admonition, div.topic, blockquote {\n    clear: left;\n}\n\n/* -- topics ---------------------------------------------------------------- */\n\ndiv.topic {\n    border: 1px solid #ccc;\n    padding: 7px;\n    margin: 10px 0 10px 0;\n}\n\np.topic-title {\n    font-size: 1.1em;\n    font-weight: bold;\n    margin-top: 10px;\n}\n\n/* -- admonitions ----------------------------------------------------------- */\n\ndiv.admonition {\n    margin-top: 10px;\n    margin-bottom: 10px;\n    padding: 7px;\n}\n\ndiv.admonition dt {\n    font-weight: bold;\n}\n\np.admonition-title {\n    margin: 0px 10px 5px 0px;\n    font-weight: bold;\n}\n\ndiv.body p.centered {\n    text-align: center;\n    margin-top: 25px;\n}\n\n/* -- content of sidebars/topics/admonitions -------------------------------- */\n\ndiv.sidebar > :last-child,\naside.sidebar > :last-child,\ndiv.topic > :last-child,\ndiv.admonition > :last-child {\n    margin-bottom: 0;\n}\n\ndiv.sidebar::after,\naside.sidebar::after,\ndiv.topic::after,\ndiv.admonition::after,\nblockquote::after {\n    display: block;\n    content: '';\n    clear: both;\n}\n\n/* -- tables ---------------------------------------------------------------- */\n\ntable.docutils {\n    margin-top: 10px;\n    margin-bottom: 10px;\n    border: 0;\n    border-collapse: collapse;\n}\n\ntable.align-center {\n    margin-left: auto;\n    margin-right: auto;\n}\n\ntable.align-default {\n    margin-left: auto;\n    margin-right: auto;\n}\n\ntable caption span.caption-number {\n    font-style: italic;\n}\n\ntable caption span.caption-text {\n}\n\ntable.docutils td, table.docutils th {\n    padding: 1px 8px 1px 5px;\n    border-top: 0;\n    border-left: 0;\n    border-right: 0;\n    border-bottom: 1px solid #aaa;\n}\n\ntable.footnote td, table.footnote th {\n    border: 0 !important;\n}\n\nth {\n    text-align: left;\n    padding-right: 5px;\n}\n\ntable.citation {\n    border-left: solid 1px gray;\n    margin-left: 1px;\n}\n\ntable.citation td {\n    border-bottom: none;\n}\n\nth > :first-child,\ntd > :first-child {\n    margin-top: 0px;\n}\n\nth > :last-child,\ntd > :last-child {\n    margin-bottom: 0px;\n}\n\n/* -- figures --------------------------------------------------------------- */\n\ndiv.figure, figure {\n    margin: 0.5em;\n    padding: 0.5em;\n}\n\ndiv.figure p.caption, figcaption {\n    padding: 0.3em;\n}\n\ndiv.figure p.caption span.caption-number,\nfigcaption span.caption-number {\n    font-style: italic;\n}\n\ndiv.figure p.caption span.caption-text,\nfigcaption span.caption-text {\n}\n\n/* -- field list styles ----------------------------------------------------- */\n\ntable.field-list td, table.field-list th {\n    border: 0 !important;\n}\n\n.field-list ul {\n    margin: 0;\n    padding-left: 1em;\n}\n\n.field-list p {\n    margin: 0;\n}\n\n.field-name {\n    -moz-hyphens: manual;\n    -ms-hyphens: manual;\n    -webkit-hyphens: manual;\n    hyphens: manual;\n}\n\n/* -- hlist styles ---------------------------------------------------------- */\n\ntable.hlist {\n    margin: 1em 0;\n}\n\ntable.hlist td {\n    vertical-align: top;\n}\n\n/* -- object description styles --------------------------------------------- */\n\n.sig {\n\tfont-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;\n}\n\n.sig-name, code.descname {\n    background-color: transparent;\n    font-weight: bold;\n}\n\n.sig-name {\n\tfont-size: 1.1em;\n}\n\ncode.descname {\n    font-size: 1.2em;\n}\n\n.sig-prename, code.descclassname {\n    background-color: transparent;\n}\n\n.optional {\n    font-size: 1.3em;\n}\n\n.sig-paren {\n    font-size: larger;\n}\n\n.sig-param.n {\n\tfont-style: italic;\n}\n\n/* C++ specific styling */\n\n.sig-inline.c-texpr,\n.sig-inline.cpp-texpr {\n\tfont-family: unset;\n}\n\n.sig.c   .k, .sig.c   .kt,\n.sig.cpp .k, .sig.cpp .kt {\n\tcolor: #0033B3;\n}\n\n.sig.c   .m,\n.sig.cpp .m {\n\tcolor: #1750EB;\n}\n\n.sig.c   .s, .sig.c   .sc,\n.sig.cpp .s, .sig.cpp .sc {\n\tcolor: #067D17;\n}\n\n\n/* -- other body styles ----------------------------------------------------- */\n\nol.arabic {\n    list-style: decimal;\n}\n\nol.loweralpha {\n    list-style: lower-alpha;\n}\n\nol.upperalpha {\n    list-style: upper-alpha;\n}\n\nol.lowerroman {\n    list-style: lower-roman;\n}\n\nol.upperroman {\n    list-style: upper-roman;\n}\n\n:not(li) > ol > li:first-child > :first-child,\n:not(li) > ul > li:first-child > :first-child {\n    margin-top: 0px;\n}\n\n:not(li) > ol > li:last-child > :last-child,\n:not(li) > ul > li:last-child > :last-child {\n    margin-bottom: 0px;\n}\n\nol.simple ol p,\nol.simple ul p,\nul.simple ol p,\nul.simple ul p {\n    margin-top: 0;\n}\n\nol.simple > li:not(:first-child) > p,\nul.simple > li:not(:first-child) > p {\n    margin-top: 0;\n}\n\nol.simple p,\nul.simple p {\n    margin-bottom: 0;\n}\n\ndl.footnote > dt,\ndl.citation > dt {\n    float: left;\n    margin-right: 0.5em;\n}\n\ndl.footnote > dd,\ndl.citation > dd {\n    margin-bottom: 0em;\n}\n\ndl.footnote > dd:after,\ndl.citation > dd:after {\n    content: \"\";\n    clear: both;\n}\n\ndl.field-list {\n    display: grid;\n    grid-template-columns: fit-content(30%) auto;\n}\n\ndl.field-list > dt {\n    font-weight: bold;\n    word-break: break-word;\n    padding-left: 0.5em;\n    padding-right: 5px;\n}\n\ndl.field-list > dt:after {\n    content: \":\";\n}\n\ndl.field-list > dd {\n    padding-left: 0.5em;\n    margin-top: 0em;\n    margin-left: 0em;\n    margin-bottom: 0em;\n}\n\ndl {\n    margin-bottom: 15px;\n}\n\ndd > :first-child {\n    margin-top: 0px;\n}\n\ndd ul, dd table {\n    margin-bottom: 10px;\n}\n\ndd {\n    margin-top: 3px;\n    margin-bottom: 10px;\n    margin-left: 30px;\n}\n\ndl > dd:last-child,\ndl > dd:last-child > :last-child {\n    margin-bottom: 0;\n}\n\ndt:target, span.highlighted {\n    background-color: #fbe54e;\n}\n\nrect.highlighted {\n    fill: #fbe54e;\n}\n\ndl.glossary dt {\n    font-weight: bold;\n    font-size: 1.1em;\n}\n\n.versionmodified {\n    font-style: italic;\n}\n\n.system-message {\n    background-color: #fda;\n    padding: 5px;\n    border: 3px solid red;\n}\n\n.footnote:target  {\n    background-color: #ffa;\n}\n\n.line-block {\n    display: block;\n    margin-top: 1em;\n    margin-bottom: 1em;\n}\n\n.line-block .line-block {\n    margin-top: 0;\n    margin-bottom: 0;\n    margin-left: 1.5em;\n}\n\n.guilabel, .menuselection {\n    font-family: sans-serif;\n}\n\n.accelerator {\n    text-decoration: underline;\n}\n\n.classifier {\n    font-style: oblique;\n}\n\n.classifier:before {\n    font-style: normal;\n    margin: 0.5em;\n    content: \":\";\n}\n\nabbr, acronym {\n    border-bottom: dotted 1px;\n    cursor: help;\n}\n\n/* -- code displays --------------------------------------------------------- */\n\npre {\n    overflow: auto;\n    overflow-y: hidden;  /* fixes display issues on Chrome browsers */\n}\n\npre, div[class*=\"highlight-\"] {\n    clear: both;\n}\n\nspan.pre {\n    -moz-hyphens: none;\n    -ms-hyphens: none;\n    -webkit-hyphens: none;\n    hyphens: none;\n}\n\ndiv[class*=\"highlight-\"] {\n    margin: 1em 0;\n}\n\ntd.linenos pre {\n    border: 0;\n    background-color: transparent;\n    color: #aaa;\n}\n\ntable.highlighttable {\n    display: block;\n}\n\ntable.highlighttable tbody {\n    display: block;\n}\n\ntable.highlighttable tr {\n    display: flex;\n}\n\ntable.highlighttable td {\n    margin: 0;\n    padding: 0;\n}\n\ntable.highlighttable td.linenos {\n    padding-right: 0.5em;\n}\n\ntable.highlighttable td.code {\n    flex: 1;\n    overflow: hidden;\n}\n\n.highlight .hll {\n    display: block;\n}\n\ndiv.highlight pre,\ntable.highlighttable pre {\n    margin: 0;\n}\n\ndiv.code-block-caption + div {\n    margin-top: 0;\n}\n\ndiv.code-block-caption {\n    margin-top: 1em;\n    padding: 2px 5px;\n    font-size: small;\n}\n\ndiv.code-block-caption code {\n    background-color: transparent;\n}\n\ntable.highlighttable td.linenos,\nspan.linenos,\ndiv.doctest > div.highlight span.gp {  /* gp: Generic.Prompt */\n  user-select: none;\n  -webkit-user-select: text; /* Safari fallback only */\n  -webkit-user-select: none; /* Chrome/Safari */\n  -moz-user-select: none; /* Firefox */\n  -ms-user-select: none; /* IE10+ */\n}\n\ndiv.code-block-caption span.caption-number {\n    padding: 0.1em 0.3em;\n    font-style: italic;\n}\n\ndiv.code-block-caption span.caption-text {\n}\n\ndiv.literal-block-wrapper {\n    margin: 1em 0;\n}\n\ncode.xref, a code {\n    background-color: transparent;\n    font-weight: bold;\n}\n\nh1 code, h2 code, h3 code, h4 code, h5 code, h6 code {\n    background-color: transparent;\n}\n\n.viewcode-link {\n    float: right;\n}\n\n.viewcode-back {\n    float: right;\n    font-family: sans-serif;\n}\n\ndiv.viewcode-block:target {\n    margin: -1px -10px;\n    padding: 0 10px;\n}\n\n/* -- math display ---------------------------------------------------------- */\n\nimg.math {\n    vertical-align: middle;\n}\n\ndiv.body div.math p {\n    text-align: center;\n}\n\nspan.eqno {\n    float: right;\n}\n\nspan.eqno a.headerlink {\n    position: absolute;\n    z-index: 1;\n}\n\ndiv.math:hover a.headerlink {\n    visibility: visible;\n}\n\n/* -- printout stylesheet --------------------------------------------------- */\n\n@media print {\n    div.document,\n    div.documentwrapper,\n    div.bodywrapper {\n        margin: 0 !important;\n        width: 100%;\n    }\n\n    div.sphinxsidebar,\n    div.related,\n    div.footer,\n    #top-link {\n        display: none;\n    }\n}"
  },
  {
    "path": "docs/_static/css/badge_only.css",
    "content": ".fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:\"\"}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format(\"embedded-opentype\"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format(\"woff2\"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format(\"woff\"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format(\"truetype\"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format(\"svg\")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:\"\\f02d\"}.fa-caret-down:before,.icon-caret-down:before{content:\"\\f0d7\"}.fa-caret-up:before,.icon-caret-up:before{content:\"\\f0d8\"}.fa-caret-left:before,.icon-caret-left:before{content:\"\\f0d9\"}.fa-caret-right:before,.icon-caret-right:before{content:\"\\f0da\"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:\"\";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}"
  },
  {
    "path": "docs/_static/css/theme.css",
    "content": "html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:\"\";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^=\"#\"]:after,a[href^=\"javascript:\"]:after{content:\"\"}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a,.wy-menu-vertical li.current>a span.toctree-expand:before,.wy-menu-vertical li.on a,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li span.toctree-expand:before,.wy-nav-top a,.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:\"\"}.clearfix:after{clear:both}/*!\n *  Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome\n *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format(\"embedded-opentype\"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format(\"woff2\"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format(\"woff\"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format(\"truetype\"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format(\"svg\");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li span.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p.caption .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a span.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a span.fa-pull-left.toctree-expand,.wy-menu-vertical li span.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p.caption .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a span.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a span.fa-pull-right.toctree-expand,.wy-menu-vertical li span.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p.caption .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a span.pull-left.toctree-expand,.wy-menu-vertical li.on a span.pull-left.toctree-expand,.wy-menu-vertical li span.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p.caption .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a span.pull-right.toctree-expand,.wy-menu-vertical li.on a span.pull-right.toctree-expand,.wy-menu-vertical li span.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)\";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)\";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)\";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)\";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:\"\"}.fa-music:before{content:\"\"}.fa-search:before,.icon-search:before{content:\"\"}.fa-envelope-o:before{content:\"\"}.fa-heart:before{content:\"\"}.fa-star:before{content:\"\"}.fa-star-o:before{content:\"\"}.fa-user:before{content:\"\"}.fa-film:before{content:\"\"}.fa-th-large:before{content:\"\"}.fa-th:before{content:\"\"}.fa-th-list:before{content:\"\"}.fa-check:before{content:\"\"}.fa-close:before,.fa-remove:before,.fa-times:before{content:\"\"}.fa-search-plus:before{content:\"\"}.fa-search-minus:before{content:\"\"}.fa-power-off:before{content:\"\"}.fa-signal:before{content:\"\"}.fa-cog:before,.fa-gear:before{content:\"\"}.fa-trash-o:before{content:\"\"}.fa-home:before,.icon-home:before{content:\"\"}.fa-file-o:before{content:\"\"}.fa-clock-o:before{content:\"\"}.fa-road:before{content:\"\"}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:\"\"}.fa-arrow-circle-o-down:before{content:\"\"}.fa-arrow-circle-o-up:before{content:\"\"}.fa-inbox:before{content:\"\"}.fa-play-circle-o:before{content:\"\"}.fa-repeat:before,.fa-rotate-right:before{content:\"\"}.fa-refresh:before{content:\"\"}.fa-list-alt:before{content:\"\"}.fa-lock:before{content:\"\"}.fa-flag:before{content:\"\"}.fa-headphones:before{content:\"\"}.fa-volume-off:before{content:\"\"}.fa-volume-down:before{content:\"\"}.fa-volume-up:before{content:\"\"}.fa-qrcode:before{content:\"\"}.fa-barcode:before{content:\"\"}.fa-tag:before{content:\"\"}.fa-tags:before{content:\"\"}.fa-book:before,.icon-book:before{content:\"\"}.fa-bookmark:before{content:\"\"}.fa-print:before{content:\"\"}.fa-camera:before{content:\"\"}.fa-font:before{content:\"\"}.fa-bold:before{content:\"\"}.fa-italic:before{content:\"\"}.fa-text-height:before{content:\"\"}.fa-text-width:before{content:\"\"}.fa-align-left:before{content:\"\"}.fa-align-center:before{content:\"\"}.fa-align-right:before{content:\"\"}.fa-align-justify:before{content:\"\"}.fa-list:before{content:\"\"}.fa-dedent:before,.fa-outdent:before{content:\"\"}.fa-indent:before{content:\"\"}.fa-video-camera:before{content:\"\"}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:\"\"}.fa-pencil:before{content:\"\"}.fa-map-marker:before{content:\"\"}.fa-adjust:before{content:\"\"}.fa-tint:before{content:\"\"}.fa-edit:before,.fa-pencil-square-o:before{content:\"\"}.fa-share-square-o:before{content:\"\"}.fa-check-square-o:before{content:\"\"}.fa-arrows:before{content:\"\"}.fa-step-backward:before{content:\"\"}.fa-fast-backward:before{content:\"\"}.fa-backward:before{content:\"\"}.fa-play:before{content:\"\"}.fa-pause:before{content:\"\"}.fa-stop:before{content:\"\"}.fa-forward:before{content:\"\"}.fa-fast-forward:before{content:\"\"}.fa-step-forward:before{content:\"\"}.fa-eject:before{content:\"\"}.fa-chevron-left:before{content:\"\"}.fa-chevron-right:before{content:\"\"}.fa-plus-circle:before{content:\"\"}.fa-minus-circle:before{content:\"\"}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:\"\"}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:\"\"}.fa-question-circle:before{content:\"\"}.fa-info-circle:before{content:\"\"}.fa-crosshairs:before{content:\"\"}.fa-times-circle-o:before{content:\"\"}.fa-check-circle-o:before{content:\"\"}.fa-ban:before{content:\"\"}.fa-arrow-left:before{content:\"\"}.fa-arrow-right:before{content:\"\"}.fa-arrow-up:before{content:\"\"}.fa-arrow-down:before{content:\"\"}.fa-mail-forward:before,.fa-share:before{content:\"\"}.fa-expand:before{content:\"\"}.fa-compress:before{content:\"\"}.fa-plus:before{content:\"\"}.fa-minus:before{content:\"\"}.fa-asterisk:before{content:\"\"}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:\"\"}.fa-gift:before{content:\"\"}.fa-leaf:before{content:\"\"}.fa-fire:before,.icon-fire:before{content:\"\"}.fa-eye:before{content:\"\"}.fa-eye-slash:before{content:\"\"}.fa-exclamation-triangle:before,.fa-warning:before{content:\"\"}.fa-plane:before{content:\"\"}.fa-calendar:before{content:\"\"}.fa-random:before{content:\"\"}.fa-comment:before{content:\"\"}.fa-magnet:before{content:\"\"}.fa-chevron-up:before{content:\"\"}.fa-chevron-down:before{content:\"\"}.fa-retweet:before{content:\"\"}.fa-shopping-cart:before{content:\"\"}.fa-folder:before{content:\"\"}.fa-folder-open:before{content:\"\"}.fa-arrows-v:before{content:\"\"}.fa-arrows-h:before{content:\"\"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:\"\"}.fa-twitter-square:before{content:\"\"}.fa-facebook-square:before{content:\"\"}.fa-camera-retro:before{content:\"\"}.fa-key:before{content:\"\"}.fa-cogs:before,.fa-gears:before{content:\"\"}.fa-comments:before{content:\"\"}.fa-thumbs-o-up:before{content:\"\"}.fa-thumbs-o-down:before{content:\"\"}.fa-star-half:before{content:\"\"}.fa-heart-o:before{content:\"\"}.fa-sign-out:before{content:\"\"}.fa-linkedin-square:before{content:\"\"}.fa-thumb-tack:before{content:\"\"}.fa-external-link:before{content:\"\"}.fa-sign-in:before{content:\"\"}.fa-trophy:before{content:\"\"}.fa-github-square:before{content:\"\"}.fa-upload:before{content:\"\"}.fa-lemon-o:before{content:\"\"}.fa-phone:before{content:\"\"}.fa-square-o:before{content:\"\"}.fa-bookmark-o:before{content:\"\"}.fa-phone-square:before{content:\"\"}.fa-twitter:before{content:\"\"}.fa-facebook-f:before,.fa-facebook:before{content:\"\"}.fa-github:before,.icon-github:before{content:\"\"}.fa-unlock:before{content:\"\"}.fa-credit-card:before{content:\"\"}.fa-feed:before,.fa-rss:before{content:\"\"}.fa-hdd-o:before{content:\"\"}.fa-bullhorn:before{content:\"\"}.fa-bell:before{content:\"\"}.fa-certificate:before{content:\"\"}.fa-hand-o-right:before{content:\"\"}.fa-hand-o-left:before{content:\"\"}.fa-hand-o-up:before{content:\"\"}.fa-hand-o-down:before{content:\"\"}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:\"\"}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:\"\"}.fa-arrow-circle-up:before{content:\"\"}.fa-arrow-circle-down:before{content:\"\"}.fa-globe:before{content:\"\"}.fa-wrench:before{content:\"\"}.fa-tasks:before{content:\"\"}.fa-filter:before{content:\"\"}.fa-briefcase:before{content:\"\"}.fa-arrows-alt:before{content:\"\"}.fa-group:before,.fa-users:before{content:\"\"}.fa-chain:before,.fa-link:before,.icon-link:before{content:\"\"}.fa-cloud:before{content:\"\"}.fa-flask:before{content:\"\"}.fa-cut:before,.fa-scissors:before{content:\"\"}.fa-copy:before,.fa-files-o:before{content:\"\"}.fa-paperclip:before{content:\"\"}.fa-floppy-o:before,.fa-save:before{content:\"\"}.fa-square:before{content:\"\"}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:\"\"}.fa-list-ul:before{content:\"\"}.fa-list-ol:before{content:\"\"}.fa-strikethrough:before{content:\"\"}.fa-underline:before{content:\"\"}.fa-table:before{content:\"\"}.fa-magic:before{content:\"\"}.fa-truck:before{content:\"\"}.fa-pinterest:before{content:\"\"}.fa-pinterest-square:before{content:\"\"}.fa-google-plus-square:before{content:\"\"}.fa-google-plus:before{content:\"\"}.fa-money:before{content:\"\"}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:\"\"}.fa-caret-up:before{content:\"\"}.fa-caret-left:before{content:\"\"}.fa-caret-right:before{content:\"\"}.fa-columns:before{content:\"\"}.fa-sort:before,.fa-unsorted:before{content:\"\"}.fa-sort-desc:before,.fa-sort-down:before{content:\"\"}.fa-sort-asc:before,.fa-sort-up:before{content:\"\"}.fa-envelope:before{content:\"\"}.fa-linkedin:before{content:\"\"}.fa-rotate-left:before,.fa-undo:before{content:\"\"}.fa-gavel:before,.fa-legal:before{content:\"\"}.fa-dashboard:before,.fa-tachometer:before{content:\"\"}.fa-comment-o:before{content:\"\"}.fa-comments-o:before{content:\"\"}.fa-bolt:before,.fa-flash:before{content:\"\"}.fa-sitemap:before{content:\"\"}.fa-umbrella:before{content:\"\"}.fa-clipboard:before,.fa-paste:before{content:\"\"}.fa-lightbulb-o:before{content:\"\"}.fa-exchange:before{content:\"\"}.fa-cloud-download:before{content:\"\"}.fa-cloud-upload:before{content:\"\"}.fa-user-md:before{content:\"\"}.fa-stethoscope:before{content:\"\"}.fa-suitcase:before{content:\"\"}.fa-bell-o:before{content:\"\"}.fa-coffee:before{content:\"\"}.fa-cutlery:before{content:\"\"}.fa-file-text-o:before{content:\"\"}.fa-building-o:before{content:\"\"}.fa-hospital-o:before{content:\"\"}.fa-ambulance:before{content:\"\"}.fa-medkit:before{content:\"\"}.fa-fighter-jet:before{content:\"\"}.fa-beer:before{content:\"\"}.fa-h-square:before{content:\"\"}.fa-plus-square:before{content:\"\"}.fa-angle-double-left:before{content:\"\"}.fa-angle-double-right:before{content:\"\"}.fa-angle-double-up:before{content:\"\"}.fa-angle-double-down:before{content:\"\"}.fa-angle-left:before{content:\"\"}.fa-angle-right:before{content:\"\"}.fa-angle-up:before{content:\"\"}.fa-angle-down:before{content:\"\"}.fa-desktop:before{content:\"\"}.fa-laptop:before{content:\"\"}.fa-tablet:before{content:\"\"}.fa-mobile-phone:before,.fa-mobile:before{content:\"\"}.fa-circle-o:before{content:\"\"}.fa-quote-left:before{content:\"\"}.fa-quote-right:before{content:\"\"}.fa-spinner:before{content:\"\"}.fa-circle:before{content:\"\"}.fa-mail-reply:before,.fa-reply:before{content:\"\"}.fa-github-alt:before{content:\"\"}.fa-folder-o:before{content:\"\"}.fa-folder-open-o:before{content:\"\"}.fa-smile-o:before{content:\"\"}.fa-frown-o:before{content:\"\"}.fa-meh-o:before{content:\"\"}.fa-gamepad:before{content:\"\"}.fa-keyboard-o:before{content:\"\"}.fa-flag-o:before{content:\"\"}.fa-flag-checkered:before{content:\"\"}.fa-terminal:before{content:\"\"}.fa-code:before{content:\"\"}.fa-mail-reply-all:before,.fa-reply-all:before{content:\"\"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:\"\"}.fa-location-arrow:before{content:\"\"}.fa-crop:before{content:\"\"}.fa-code-fork:before{content:\"\"}.fa-chain-broken:before,.fa-unlink:before{content:\"\"}.fa-question:before{content:\"\"}.fa-info:before{content:\"\"}.fa-exclamation:before{content:\"\"}.fa-superscript:before{content:\"\"}.fa-subscript:before{content:\"\"}.fa-eraser:before{content:\"\"}.fa-puzzle-piece:before{content:\"\"}.fa-microphone:before{content:\"\"}.fa-microphone-slash:before{content:\"\"}.fa-shield:before{content:\"\"}.fa-calendar-o:before{content:\"\"}.fa-fire-extinguisher:before{content:\"\"}.fa-rocket:before{content:\"\"}.fa-maxcdn:before{content:\"\"}.fa-chevron-circle-left:before{content:\"\"}.fa-chevron-circle-right:before{content:\"\"}.fa-chevron-circle-up:before{content:\"\"}.fa-chevron-circle-down:before{content:\"\"}.fa-html5:before{content:\"\"}.fa-css3:before{content:\"\"}.fa-anchor:before{content:\"\"}.fa-unlock-alt:before{content:\"\"}.fa-bullseye:before{content:\"\"}.fa-ellipsis-h:before{content:\"\"}.fa-ellipsis-v:before{content:\"\"}.fa-rss-square:before{content:\"\"}.fa-play-circle:before{content:\"\"}.fa-ticket:before{content:\"\"}.fa-minus-square:before{content:\"\"}.fa-minus-square-o:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before{content:\"\"}.fa-level-up:before{content:\"\"}.fa-level-down:before{content:\"\"}.fa-check-square:before{content:\"\"}.fa-pencil-square:before{content:\"\"}.fa-external-link-square:before{content:\"\"}.fa-share-square:before{content:\"\"}.fa-compass:before{content:\"\"}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:\"\"}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:\"\"}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:\"\"}.fa-eur:before,.fa-euro:before{content:\"\"}.fa-gbp:before{content:\"\"}.fa-dollar:before,.fa-usd:before{content:\"\"}.fa-inr:before,.fa-rupee:before{content:\"\"}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:\"\"}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:\"\"}.fa-krw:before,.fa-won:before{content:\"\"}.fa-bitcoin:before,.fa-btc:before{content:\"\"}.fa-file:before{content:\"\"}.fa-file-text:before{content:\"\"}.fa-sort-alpha-asc:before{content:\"\"}.fa-sort-alpha-desc:before{content:\"\"}.fa-sort-amount-asc:before{content:\"\"}.fa-sort-amount-desc:before{content:\"\"}.fa-sort-numeric-asc:before{content:\"\"}.fa-sort-numeric-desc:before{content:\"\"}.fa-thumbs-up:before{content:\"\"}.fa-thumbs-down:before{content:\"\"}.fa-youtube-square:before{content:\"\"}.fa-youtube:before{content:\"\"}.fa-xing:before{content:\"\"}.fa-xing-square:before{content:\"\"}.fa-youtube-play:before{content:\"\"}.fa-dropbox:before{content:\"\"}.fa-stack-overflow:before{content:\"\"}.fa-instagram:before{content:\"\"}.fa-flickr:before{content:\"\"}.fa-adn:before{content:\"\"}.fa-bitbucket:before,.icon-bitbucket:before{content:\"\"}.fa-bitbucket-square:before{content:\"\"}.fa-tumblr:before{content:\"\"}.fa-tumblr-square:before{content:\"\"}.fa-long-arrow-down:before{content:\"\"}.fa-long-arrow-up:before{content:\"\"}.fa-long-arrow-left:before{content:\"\"}.fa-long-arrow-right:before{content:\"\"}.fa-apple:before{content:\"\"}.fa-windows:before{content:\"\"}.fa-android:before{content:\"\"}.fa-linux:before{content:\"\"}.fa-dribbble:before{content:\"\"}.fa-skype:before{content:\"\"}.fa-foursquare:before{content:\"\"}.fa-trello:before{content:\"\"}.fa-female:before{content:\"\"}.fa-male:before{content:\"\"}.fa-gittip:before,.fa-gratipay:before{content:\"\"}.fa-sun-o:before{content:\"\"}.fa-moon-o:before{content:\"\"}.fa-archive:before{content:\"\"}.fa-bug:before{content:\"\"}.fa-vk:before{content:\"\"}.fa-weibo:before{content:\"\"}.fa-renren:before{content:\"\"}.fa-pagelines:before{content:\"\"}.fa-stack-exchange:before{content:\"\"}.fa-arrow-circle-o-right:before{content:\"\"}.fa-arrow-circle-o-left:before{content:\"\"}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:\"\"}.fa-dot-circle-o:before{content:\"\"}.fa-wheelchair:before{content:\"\"}.fa-vimeo-square:before{content:\"\"}.fa-try:before,.fa-turkish-lira:before{content:\"\"}.fa-plus-square-o:before,.wy-menu-vertical li span.toctree-expand:before{content:\"\"}.fa-space-shuttle:before{content:\"\"}.fa-slack:before{content:\"\"}.fa-envelope-square:before{content:\"\"}.fa-wordpress:before{content:\"\"}.fa-openid:before{content:\"\"}.fa-bank:before,.fa-institution:before,.fa-university:before{content:\"\"}.fa-graduation-cap:before,.fa-mortar-board:before{content:\"\"}.fa-yahoo:before{content:\"\"}.fa-google:before{content:\"\"}.fa-reddit:before{content:\"\"}.fa-reddit-square:before{content:\"\"}.fa-stumbleupon-circle:before{content:\"\"}.fa-stumbleupon:before{content:\"\"}.fa-delicious:before{content:\"\"}.fa-digg:before{content:\"\"}.fa-pied-piper-pp:before{content:\"\"}.fa-pied-piper-alt:before{content:\"\"}.fa-drupal:before{content:\"\"}.fa-joomla:before{content:\"\"}.fa-language:before{content:\"\"}.fa-fax:before{content:\"\"}.fa-building:before{content:\"\"}.fa-child:before{content:\"\"}.fa-paw:before{content:\"\"}.fa-spoon:before{content:\"\"}.fa-cube:before{content:\"\"}.fa-cubes:before{content:\"\"}.fa-behance:before{content:\"\"}.fa-behance-square:before{content:\"\"}.fa-steam:before{content:\"\"}.fa-steam-square:before{content:\"\"}.fa-recycle:before{content:\"\"}.fa-automobile:before,.fa-car:before{content:\"\"}.fa-cab:before,.fa-taxi:before{content:\"\"}.fa-tree:before{content:\"\"}.fa-spotify:before{content:\"\"}.fa-deviantart:before{content:\"\"}.fa-soundcloud:before{content:\"\"}.fa-database:before{content:\"\"}.fa-file-pdf-o:before{content:\"\"}.fa-file-word-o:before{content:\"\"}.fa-file-excel-o:before{content:\"\"}.fa-file-powerpoint-o:before{content:\"\"}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:\"\"}.fa-file-archive-o:before,.fa-file-zip-o:before{content:\"\"}.fa-file-audio-o:before,.fa-file-sound-o:before{content:\"\"}.fa-file-movie-o:before,.fa-file-video-o:before{content:\"\"}.fa-file-code-o:before{content:\"\"}.fa-vine:before{content:\"\"}.fa-codepen:before{content:\"\"}.fa-jsfiddle:before{content:\"\"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:\"\"}.fa-circle-o-notch:before{content:\"\"}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:\"\"}.fa-empire:before,.fa-ge:before{content:\"\"}.fa-git-square:before{content:\"\"}.fa-git:before{content:\"\"}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:\"\"}.fa-tencent-weibo:before{content:\"\"}.fa-qq:before{content:\"\"}.fa-wechat:before,.fa-weixin:before{content:\"\"}.fa-paper-plane:before,.fa-send:before{content:\"\"}.fa-paper-plane-o:before,.fa-send-o:before{content:\"\"}.fa-history:before{content:\"\"}.fa-circle-thin:before{content:\"\"}.fa-header:before{content:\"\"}.fa-paragraph:before{content:\"\"}.fa-sliders:before{content:\"\"}.fa-share-alt:before{content:\"\"}.fa-share-alt-square:before{content:\"\"}.fa-bomb:before{content:\"\"}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:\"\"}.fa-tty:before{content:\"\"}.fa-binoculars:before{content:\"\"}.fa-plug:before{content:\"\"}.fa-slideshare:before{content:\"\"}.fa-twitch:before{content:\"\"}.fa-yelp:before{content:\"\"}.fa-newspaper-o:before{content:\"\"}.fa-wifi:before{content:\"\"}.fa-calculator:before{content:\"\"}.fa-paypal:before{content:\"\"}.fa-google-wallet:before{content:\"\"}.fa-cc-visa:before{content:\"\"}.fa-cc-mastercard:before{content:\"\"}.fa-cc-discover:before{content:\"\"}.fa-cc-amex:before{content:\"\"}.fa-cc-paypal:before{content:\"\"}.fa-cc-stripe:before{content:\"\"}.fa-bell-slash:before{content:\"\"}.fa-bell-slash-o:before{content:\"\"}.fa-trash:before{content:\"\"}.fa-copyright:before{content:\"\"}.fa-at:before{content:\"\"}.fa-eyedropper:before{content:\"\"}.fa-paint-brush:before{content:\"\"}.fa-birthday-cake:before{content:\"\"}.fa-area-chart:before{content:\"\"}.fa-pie-chart:before{content:\"\"}.fa-line-chart:before{content:\"\"}.fa-lastfm:before{content:\"\"}.fa-lastfm-square:before{content:\"\"}.fa-toggle-off:before{content:\"\"}.fa-toggle-on:before{content:\"\"}.fa-bicycle:before{content:\"\"}.fa-bus:before{content:\"\"}.fa-ioxhost:before{content:\"\"}.fa-angellist:before{content:\"\"}.fa-cc:before{content:\"\"}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:\"\"}.fa-meanpath:before{content:\"\"}.fa-buysellads:before{content:\"\"}.fa-connectdevelop:before{content:\"\"}.fa-dashcube:before{content:\"\"}.fa-forumbee:before{content:\"\"}.fa-leanpub:before{content:\"\"}.fa-sellsy:before{content:\"\"}.fa-shirtsinbulk:before{content:\"\"}.fa-simplybuilt:before{content:\"\"}.fa-skyatlas:before{content:\"\"}.fa-cart-plus:before{content:\"\"}.fa-cart-arrow-down:before{content:\"\"}.fa-diamond:before{content:\"\"}.fa-ship:before{content:\"\"}.fa-user-secret:before{content:\"\"}.fa-motorcycle:before{content:\"\"}.fa-street-view:before{content:\"\"}.fa-heartbeat:before{content:\"\"}.fa-venus:before{content:\"\"}.fa-mars:before{content:\"\"}.fa-mercury:before{content:\"\"}.fa-intersex:before,.fa-transgender:before{content:\"\"}.fa-transgender-alt:before{content:\"\"}.fa-venus-double:before{content:\"\"}.fa-mars-double:before{content:\"\"}.fa-venus-mars:before{content:\"\"}.fa-mars-stroke:before{content:\"\"}.fa-mars-stroke-v:before{content:\"\"}.fa-mars-stroke-h:before{content:\"\"}.fa-neuter:before{content:\"\"}.fa-genderless:before{content:\"\"}.fa-facebook-official:before{content:\"\"}.fa-pinterest-p:before{content:\"\"}.fa-whatsapp:before{content:\"\"}.fa-server:before{content:\"\"}.fa-user-plus:before{content:\"\"}.fa-user-times:before{content:\"\"}.fa-bed:before,.fa-hotel:before{content:\"\"}.fa-viacoin:before{content:\"\"}.fa-train:before{content:\"\"}.fa-subway:before{content:\"\"}.fa-medium:before{content:\"\"}.fa-y-combinator:before,.fa-yc:before{content:\"\"}.fa-optin-monster:before{content:\"\"}.fa-opencart:before{content:\"\"}.fa-expeditedssl:before{content:\"\"}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:\"\"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:\"\"}.fa-battery-2:before,.fa-battery-half:before{content:\"\"}.fa-battery-1:before,.fa-battery-quarter:before{content:\"\"}.fa-battery-0:before,.fa-battery-empty:before{content:\"\"}.fa-mouse-pointer:before{content:\"\"}.fa-i-cursor:before{content:\"\"}.fa-object-group:before{content:\"\"}.fa-object-ungroup:before{content:\"\"}.fa-sticky-note:before{content:\"\"}.fa-sticky-note-o:before{content:\"\"}.fa-cc-jcb:before{content:\"\"}.fa-cc-diners-club:before{content:\"\"}.fa-clone:before{content:\"\"}.fa-balance-scale:before{content:\"\"}.fa-hourglass-o:before{content:\"\"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:\"\"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:\"\"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:\"\"}.fa-hourglass:before{content:\"\"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:\"\"}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:\"\"}.fa-hand-scissors-o:before{content:\"\"}.fa-hand-lizard-o:before{content:\"\"}.fa-hand-spock-o:before{content:\"\"}.fa-hand-pointer-o:before{content:\"\"}.fa-hand-peace-o:before{content:\"\"}.fa-trademark:before{content:\"\"}.fa-registered:before{content:\"\"}.fa-creative-commons:before{content:\"\"}.fa-gg:before{content:\"\"}.fa-gg-circle:before{content:\"\"}.fa-tripadvisor:before{content:\"\"}.fa-odnoklassniki:before{content:\"\"}.fa-odnoklassniki-square:before{content:\"\"}.fa-get-pocket:before{content:\"\"}.fa-wikipedia-w:before{content:\"\"}.fa-safari:before{content:\"\"}.fa-chrome:before{content:\"\"}.fa-firefox:before{content:\"\"}.fa-opera:before{content:\"\"}.fa-internet-explorer:before{content:\"\"}.fa-television:before,.fa-tv:before{content:\"\"}.fa-contao:before{content:\"\"}.fa-500px:before{content:\"\"}.fa-amazon:before{content:\"\"}.fa-calendar-plus-o:before{content:\"\"}.fa-calendar-minus-o:before{content:\"\"}.fa-calendar-times-o:before{content:\"\"}.fa-calendar-check-o:before{content:\"\"}.fa-industry:before{content:\"\"}.fa-map-pin:before{content:\"\"}.fa-map-signs:before{content:\"\"}.fa-map-o:before{content:\"\"}.fa-map:before{content:\"\"}.fa-commenting:before{content:\"\"}.fa-commenting-o:before{content:\"\"}.fa-houzz:before{content:\"\"}.fa-vimeo:before{content:\"\"}.fa-black-tie:before{content:\"\"}.fa-fonticons:before{content:\"\"}.fa-reddit-alien:before{content:\"\"}.fa-edge:before{content:\"\"}.fa-credit-card-alt:before{content:\"\"}.fa-codiepie:before{content:\"\"}.fa-modx:before{content:\"\"}.fa-fort-awesome:before{content:\"\"}.fa-usb:before{content:\"\"}.fa-product-hunt:before{content:\"\"}.fa-mixcloud:before{content:\"\"}.fa-scribd:before{content:\"\"}.fa-pause-circle:before{content:\"\"}.fa-pause-circle-o:before{content:\"\"}.fa-stop-circle:before{content:\"\"}.fa-stop-circle-o:before{content:\"\"}.fa-shopping-bag:before{content:\"\"}.fa-shopping-basket:before{content:\"\"}.fa-hashtag:before{content:\"\"}.fa-bluetooth:before{content:\"\"}.fa-bluetooth-b:before{content:\"\"}.fa-percent:before{content:\"\"}.fa-gitlab:before,.icon-gitlab:before{content:\"\"}.fa-wpbeginner:before{content:\"\"}.fa-wpforms:before{content:\"\"}.fa-envira:before{content:\"\"}.fa-universal-access:before{content:\"\"}.fa-wheelchair-alt:before{content:\"\"}.fa-question-circle-o:before{content:\"\"}.fa-blind:before{content:\"\"}.fa-audio-description:before{content:\"\"}.fa-volume-control-phone:before{content:\"\"}.fa-braille:before{content:\"\"}.fa-assistive-listening-systems:before{content:\"\"}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:\"\"}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:\"\"}.fa-glide:before{content:\"\"}.fa-glide-g:before{content:\"\"}.fa-sign-language:before,.fa-signing:before{content:\"\"}.fa-low-vision:before{content:\"\"}.fa-viadeo:before{content:\"\"}.fa-viadeo-square:before{content:\"\"}.fa-snapchat:before{content:\"\"}.fa-snapchat-ghost:before{content:\"\"}.fa-snapchat-square:before{content:\"\"}.fa-pied-piper:before{content:\"\"}.fa-first-order:before{content:\"\"}.fa-yoast:before{content:\"\"}.fa-themeisle:before{content:\"\"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:\"\"}.fa-fa:before,.fa-font-awesome:before{content:\"\"}.fa-handshake-o:before{content:\"\"}.fa-envelope-open:before{content:\"\"}.fa-envelope-open-o:before{content:\"\"}.fa-linode:before{content:\"\"}.fa-address-book:before{content:\"\"}.fa-address-book-o:before{content:\"\"}.fa-address-card:before,.fa-vcard:before{content:\"\"}.fa-address-card-o:before,.fa-vcard-o:before{content:\"\"}.fa-user-circle:before{content:\"\"}.fa-user-circle-o:before{content:\"\"}.fa-user-o:before{content:\"\"}.fa-id-badge:before{content:\"\"}.fa-drivers-license:before,.fa-id-card:before{content:\"\"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:\"\"}.fa-quora:before{content:\"\"}.fa-free-code-camp:before{content:\"\"}.fa-telegram:before{content:\"\"}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:\"\"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:\"\"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:\"\"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:\"\"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:\"\"}.fa-shower:before{content:\"\"}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:\"\"}.fa-podcast:before{content:\"\"}.fa-window-maximize:before{content:\"\"}.fa-window-minimize:before{content:\"\"}.fa-window-restore:before{content:\"\"}.fa-times-rectangle:before,.fa-window-close:before{content:\"\"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:\"\"}.fa-bandcamp:before{content:\"\"}.fa-grav:before{content:\"\"}.fa-etsy:before{content:\"\"}.fa-imdb:before{content:\"\"}.fa-ravelry:before{content:\"\"}.fa-eercast:before{content:\"\"}.fa-microchip:before{content:\"\"}.fa-snowflake-o:before{content:\"\"}.fa-superpowers:before{content:\"\"}.fa-wpexplorer:before{content:\"\"}.fa-meetup:before{content:\"\"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li span.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li span.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li a span.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li span.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p.caption .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a span.toctree-expand,.btn .wy-menu-vertical li.on a span.toctree-expand,.btn .wy-menu-vertical li span.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p.caption .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a span.toctree-expand,.nav .wy-menu-vertical li.on a span.toctree-expand,.nav .wy-menu-vertical li span.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p.caption .btn .headerlink,.rst-content p.caption .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn span.toctree-expand,.wy-menu-vertical li.current>a .btn span.toctree-expand,.wy-menu-vertical li.current>a .nav span.toctree-expand,.wy-menu-vertical li .nav span.toctree-expand,.wy-menu-vertical li.on a .btn span.toctree-expand,.wy-menu-vertical li.on a .nav span.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p.caption .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li span.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p.caption .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li span.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p.caption .btn .fa-large.headerlink,.rst-content p.caption .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn span.fa-large.toctree-expand,.wy-menu-vertical li .nav span.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p.caption .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li span.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p.caption .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li span.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p.caption .btn .fa-spin.headerlink,.rst-content p.caption .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn span.fa-spin.toctree-expand,.wy-menu-vertical li .nav span.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p.caption .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li span.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p.caption .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li span.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p.caption .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li span.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p.caption .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini span.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:\"\"}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:\" \";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:\"\"}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:\" *\";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:\"\";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol li,.rst-content ol.arabic li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content ol.arabic li p:last-child,.rst-content ol.arabic li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol li ul li,.rst-content ol.arabic li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:\"\"}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs li{display:inline-block}.wy-breadcrumbs li.wy-breadcrumbs-aside{float:right}.wy-breadcrumbs li a{display:inline-block;padding:5px}.wy-breadcrumbs li a:first-child{padding-left:0}.rst-content .wy-breadcrumbs li tt,.wy-breadcrumbs li .rst-content tt,.wy-breadcrumbs li code{padding:5px;border:none;background:none}.rst-content .wy-breadcrumbs li tt.literal,.wy-breadcrumbs li .rst-content tt.literal,.wy-breadcrumbs li code.literal{color:#404040}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:\"\"}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li span.toctree-expand{display:block;float:left;margin-left:-1.2em;font-size:.8em;line-height:1.6em;color:#4d4d4d}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover span.toctree-expand,.wy-menu-vertical li.on a:hover span.toctree-expand{color:grey}.wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand{display:block;font-size:.8em;line-height:1.6em;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover span.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 span.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 span.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover span.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active span.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:\"\"}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:\"\"}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:\"\"}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:\"\"}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p.caption .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p.caption .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version span.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content img{max-width:100%;height:auto}.rst-content div.figure{margin-bottom:24px}.rst-content div.figure p.caption{font-style:italic}.rst-content div.figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:\"\\f08e\";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp{user-select:none;pointer-events:none}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink{visibility:hidden;font-size:14px}.rst-content .code-block-caption .headerlink:after,.rst-content .toctree-wrapper>p.caption .headerlink:after,.rst-content dl dt .headerlink:after,.rst-content h1 .headerlink:after,.rst-content h2 .headerlink:after,.rst-content h3 .headerlink:after,.rst-content h4 .headerlink:after,.rst-content h5 .headerlink:after,.rst-content h6 .headerlink:after,.rst-content p.caption .headerlink:after,.rst-content table>caption .headerlink:after{content:\"\\f0c1\";font-family:FontAwesome}.rst-content .code-block-caption:hover .headerlink:after,.rst-content .toctree-wrapper>p.caption:hover .headerlink:after,.rst-content dl dt:hover .headerlink:after,.rst-content h1:hover .headerlink:after,.rst-content h2:hover .headerlink:after,.rst-content h3:hover .headerlink:after,.rst-content h4:hover .headerlink:after,.rst-content h5:hover .headerlink:after,.rst-content h6:hover .headerlink:after,.rst-content p.caption:hover .headerlink:after,.rst-content table>caption:hover .headerlink:after{visibility:visible}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .hlist{width:100%}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl dt span.classifier:before{content:\" : \"}html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.field-list>dt:after,html.writer-html5 .rst-content dl.footnote>dt:after{content:\":\"}html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.footnote>dt>span.brackets{margin-right:.5rem}html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:\"[\"}html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:\"]\"}html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{font-style:italic}html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.footnote>dd p,html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{font-size:inherit;line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.field-list)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl:not(.field-list)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.field-list)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl:not(.field-list)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code,html.writer-html4 .rst-content dl:not(.docutils) tt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel{border:1px solid #7fbbe3;background:#e7f2fa;font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format(\"woff2\"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format(\"woff\");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format(\"woff2\"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format(\"woff\");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format(\"woff2\"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format(\"woff\");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format(\"woff2\"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format(\"woff\");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format(\"woff2\"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format(\"woff\");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format(\"woff2\"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format(\"woff\");font-display:block}"
  },
  {
    "path": "docs/_static/custom.css",
    "content": "/* This file intentionally left blank. */\n"
  },
  {
    "path": "docs/_static/doctools.js",
    "content": "/*\n * doctools.js\n * ~~~~~~~~~~~\n *\n * Sphinx JavaScript utilities for all documentation.\n *\n * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.\n * :license: BSD, see LICENSE for details.\n *\n */\n\n/**\n * select a different prefix for underscore\n */\n$u = _.noConflict();\n\n/**\n * make the code below compatible with browsers without\n * an installed firebug like debugger\nif (!window.console || !console.firebug) {\n  var names = [\"log\", \"debug\", \"info\", \"warn\", \"error\", \"assert\", \"dir\",\n    \"dirxml\", \"group\", \"groupEnd\", \"time\", \"timeEnd\", \"count\", \"trace\",\n    \"profile\", \"profileEnd\"];\n  window.console = {};\n  for (var i = 0; i < names.length; ++i)\n    window.console[names[i]] = function() {};\n}\n */\n\n/**\n * small helper function to urldecode strings\n *\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL\n */\njQuery.urldecode = function(x) {\n  if (!x) {\n    return x\n  }\n  return decodeURIComponent(x.replace(/\\+/g, ' '));\n};\n\n/**\n * small helper function to urlencode strings\n */\njQuery.urlencode = encodeURIComponent;\n\n/**\n * This function returns the parsed url parameters of the\n * current request. Multiple values per key are supported,\n * it will always return arrays of strings for the value parts.\n */\njQuery.getQueryParameters = function(s) {\n  if (typeof s === 'undefined')\n    s = document.location.search;\n  var parts = s.substr(s.indexOf('?') + 1).split('&');\n  var result = {};\n  for (var i = 0; i < parts.length; i++) {\n    var tmp = parts[i].split('=', 2);\n    var key = jQuery.urldecode(tmp[0]);\n    var value = jQuery.urldecode(tmp[1]);\n    if (key in result)\n      result[key].push(value);\n    else\n      result[key] = [value];\n  }\n  return result;\n};\n\n/**\n * highlight a given string on a jquery object by wrapping it in\n * span elements with the given class name.\n */\njQuery.fn.highlightText = function(text, className) {\n  function highlight(node, addItems) {\n    if (node.nodeType === 3) {\n      var val = node.nodeValue;\n      var pos = val.toLowerCase().indexOf(text);\n      if (pos >= 0 &&\n          !jQuery(node.parentNode).hasClass(className) &&\n          !jQuery(node.parentNode).hasClass(\"nohighlight\")) {\n        var span;\n        var isInSVG = jQuery(node).closest(\"body, svg, foreignObject\").is(\"svg\");\n        if (isInSVG) {\n          span = document.createElementNS(\"http://www.w3.org/2000/svg\", \"tspan\");\n        } else {\n          span = document.createElement(\"span\");\n          span.className = className;\n        }\n        span.appendChild(document.createTextNode(val.substr(pos, text.length)));\n        node.parentNode.insertBefore(span, node.parentNode.insertBefore(\n          document.createTextNode(val.substr(pos + text.length)),\n          node.nextSibling));\n        node.nodeValue = val.substr(0, pos);\n        if (isInSVG) {\n          var rect = document.createElementNS(\"http://www.w3.org/2000/svg\", \"rect\");\n          var bbox = node.parentElement.getBBox();\n          rect.x.baseVal.value = bbox.x;\n          rect.y.baseVal.value = bbox.y;\n          rect.width.baseVal.value = bbox.width;\n          rect.height.baseVal.value = bbox.height;\n          rect.setAttribute('class', className);\n          addItems.push({\n              \"parent\": node.parentNode,\n              \"target\": rect});\n        }\n      }\n    }\n    else if (!jQuery(node).is(\"button, select, textarea\")) {\n      jQuery.each(node.childNodes, function() {\n        highlight(this, addItems);\n      });\n    }\n  }\n  var addItems = [];\n  var result = this.each(function() {\n    highlight(this, addItems);\n  });\n  for (var i = 0; i < addItems.length; ++i) {\n    jQuery(addItems[i].parent).before(addItems[i].target);\n  }\n  return result;\n};\n\n/*\n * backward compatibility for jQuery.browser\n * This will be supported until firefox bug is fixed.\n */\nif (!jQuery.browser) {\n  jQuery.uaMatch = function(ua) {\n    ua = ua.toLowerCase();\n\n    var match = /(chrome)[ \\/]([\\w.]+)/.exec(ua) ||\n      /(webkit)[ \\/]([\\w.]+)/.exec(ua) ||\n      /(opera)(?:.*version|)[ \\/]([\\w.]+)/.exec(ua) ||\n      /(msie) ([\\w.]+)/.exec(ua) ||\n      ua.indexOf(\"compatible\") < 0 && /(mozilla)(?:.*? rv:([\\w.]+)|)/.exec(ua) ||\n      [];\n\n    return {\n      browser: match[ 1 ] || \"\",\n      version: match[ 2 ] || \"0\"\n    };\n  };\n  jQuery.browser = {};\n  jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;\n}\n\n/**\n * Small JavaScript module for the documentation.\n */\nvar Documentation = {\n\n  init : function() {\n    this.fixFirefoxAnchorBug();\n    this.highlightSearchWords();\n    this.initIndexTable();\n    if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) {\n      this.initOnKeyListeners();\n    }\n  },\n\n  /**\n   * i18n support\n   */\n  TRANSLATIONS : {},\n  PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; },\n  LOCALE : 'unknown',\n\n  // gettext and ngettext don't access this so that the functions\n  // can safely bound to a different name (_ = Documentation.gettext)\n  gettext : function(string) {\n    var translated = Documentation.TRANSLATIONS[string];\n    if (typeof translated === 'undefined')\n      return string;\n    return (typeof translated === 'string') ? translated : translated[0];\n  },\n\n  ngettext : function(singular, plural, n) {\n    var translated = Documentation.TRANSLATIONS[singular];\n    if (typeof translated === 'undefined')\n      return (n == 1) ? singular : plural;\n    return translated[Documentation.PLURALEXPR(n)];\n  },\n\n  addTranslations : function(catalog) {\n    for (var key in catalog.messages)\n      this.TRANSLATIONS[key] = catalog.messages[key];\n    this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');\n    this.LOCALE = catalog.locale;\n  },\n\n  /**\n   * add context elements like header anchor links\n   */\n  addContextElements : function() {\n    $('div[id] > :header:first').each(function() {\n      $('<a class=\"headerlink\">\\u00B6</a>').\n      attr('href', '#' + this.id).\n      attr('title', _('Permalink to this headline')).\n      appendTo(this);\n    });\n    $('dt[id]').each(function() {\n      $('<a class=\"headerlink\">\\u00B6</a>').\n      attr('href', '#' + this.id).\n      attr('title', _('Permalink to this definition')).\n      appendTo(this);\n    });\n  },\n\n  /**\n   * workaround a firefox stupidity\n   * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075\n   */\n  fixFirefoxAnchorBug : function() {\n    if (document.location.hash && $.browser.mozilla)\n      window.setTimeout(function() {\n        document.location.href += '';\n      }, 10);\n  },\n\n  /**\n   * highlight the search words provided in the url in the text\n   */\n  highlightSearchWords : function() {\n    var params = $.getQueryParameters();\n    var terms = (params.highlight) ? params.highlight[0].split(/\\s+/) : [];\n    if (terms.length) {\n      var body = $('div.body');\n      if (!body.length) {\n        body = $('body');\n      }\n      window.setTimeout(function() {\n        $.each(terms, function() {\n          body.highlightText(this.toLowerCase(), 'highlighted');\n        });\n      }, 10);\n      $('<p class=\"highlight-link\"><a href=\"javascript:Documentation.' +\n        'hideSearchWords()\">' + _('Hide Search Matches') + '</a></p>')\n          .appendTo($('#searchbox'));\n    }\n  },\n\n  /**\n   * init the domain index toggle buttons\n   */\n  initIndexTable : function() {\n    var togglers = $('img.toggler').click(function() {\n      var src = $(this).attr('src');\n      var idnum = $(this).attr('id').substr(7);\n      $('tr.cg-' + idnum).toggle();\n      if (src.substr(-9) === 'minus.png')\n        $(this).attr('src', src.substr(0, src.length-9) + 'plus.png');\n      else\n        $(this).attr('src', src.substr(0, src.length-8) + 'minus.png');\n    }).css('display', '');\n    if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {\n        togglers.click();\n    }\n  },\n\n  /**\n   * helper function to hide the search marks again\n   */\n  hideSearchWords : function() {\n    $('#searchbox .highlight-link').fadeOut(300);\n    $('span.highlighted').removeClass('highlighted');\n  },\n\n  /**\n   * make the url absolute\n   */\n  makeURL : function(relativeURL) {\n    return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;\n  },\n\n  /**\n   * get the current relative url\n   */\n  getCurrentURL : function() {\n    var path = document.location.pathname;\n    var parts = path.split(/\\//);\n    $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\\//), function() {\n      if (this === '..')\n        parts.pop();\n    });\n    var url = parts.join('/');\n    return path.substring(url.lastIndexOf('/') + 1, path.length - 1);\n  },\n\n  initOnKeyListeners: function() {\n    $(document).keydown(function(event) {\n      var activeElementType = document.activeElement.tagName;\n      // don't navigate when in search box, textarea, dropdown or button\n      if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT'\n          && activeElementType !== 'BUTTON' && !event.altKey && !event.ctrlKey && !event.metaKey\n          && !event.shiftKey) {\n        switch (event.keyCode) {\n          case 37: // left\n            var prevHref = $('link[rel=\"prev\"]').prop('href');\n            if (prevHref) {\n              window.location.href = prevHref;\n              return false;\n            }\n          case 39: // right\n            var nextHref = $('link[rel=\"next\"]').prop('href');\n            if (nextHref) {\n              window.location.href = nextHref;\n              return false;\n            }\n        }\n      }\n    });\n  }\n};\n\n// quick alias for translations\n_ = Documentation.gettext;\n\n$(document).ready(function() {\n  Documentation.init();\n});\n"
  },
  {
    "path": "docs/_static/documentation_options.js",
    "content": "var DOCUMENTATION_OPTIONS = {\n    URL_ROOT: document.getElementById(\"documentation_options\").getAttribute('data-url_root'),\n    VERSION: '0.5.1',\n    LANGUAGE: 'None',\n    COLLAPSE_INDEX: false,\n    BUILDER: 'html',\n    FILE_SUFFIX: '.html',\n    LINK_SUFFIX: '.html',\n    HAS_SOURCE: true,\n    SOURCELINK_SUFFIX: '.txt',\n    NAVIGATION_WITH_KEYS: false\n};"
  },
  {
    "path": "docs/_static/jquery-3.4.1.js",
    "content": "/*!\n * jQuery JavaScript Library v3.4.1\n * https://jquery.com/\n *\n * Includes Sizzle.js\n * https://sizzlejs.com/\n *\n * Copyright JS Foundation and other contributors\n * Released under the MIT license\n * https://jquery.org/license\n *\n * Date: 2019-05-01T21:04Z\n */\n( function( global, factory ) {\n\n\t\"use strict\";\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\n\t\t// For CommonJS and CommonJS-like environments where a proper `window`\n\t\t// is present, execute the factory and get jQuery.\n\t\t// For environments that do not have a `window` with a `document`\n\t\t// (such as Node.js), expose a factory as module.exports.\n\t\t// This accentuates the need for the creation of a real `window`.\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info.\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n} )( typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1\n// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode\n// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common\n// enough that all such attempts are guarded in a try block.\n\"use strict\";\n\nvar arr = [];\n\nvar document = window.document;\n\nvar getProto = Object.getPrototypeOf;\n\nvar slice = arr.slice;\n\nvar concat = arr.concat;\n\nvar push = arr.push;\n\nvar indexOf = arr.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar fnToString = hasOwn.toString;\n\nvar ObjectFunctionString = fnToString.call( Object );\n\nvar support = {};\n\nvar isFunction = function isFunction( obj ) {\n\n      // Support: Chrome <=57, Firefox <=52\n      // In some browsers, typeof returns \"function\" for HTML <object> elements\n      // (i.e., `typeof document.createElement( \"object\" ) === \"function\"`).\n      // We don't want to classify *any* DOM node as a function.\n      return typeof obj === \"function\" && typeof obj.nodeType !== \"number\";\n  };\n\n\nvar isWindow = function isWindow( obj ) {\n\t\treturn obj != null && obj === obj.window;\n\t};\n\n\n\n\n\tvar preservedScriptAttributes = {\n\t\ttype: true,\n\t\tsrc: true,\n\t\tnonce: true,\n\t\tnoModule: true\n\t};\n\n\tfunction DOMEval( code, node, doc ) {\n\t\tdoc = doc || document;\n\n\t\tvar i, val,\n\t\t\tscript = doc.createElement( \"script\" );\n\n\t\tscript.text = code;\n\t\tif ( node ) {\n\t\t\tfor ( i in preservedScriptAttributes ) {\n\n\t\t\t\t// Support: Firefox 64+, Edge 18+\n\t\t\t\t// Some browsers don't support the \"nonce\" property on scripts.\n\t\t\t\t// On the other hand, just using `getAttribute` is not enough as\n\t\t\t\t// the `nonce` attribute is reset to an empty string whenever it\n\t\t\t\t// becomes browsing-context connected.\n\t\t\t\t// See https://github.com/whatwg/html/issues/2369\n\t\t\t\t// See https://html.spec.whatwg.org/#nonce-attributes\n\t\t\t\t// The `node.getAttribute` check was added for the sake of\n\t\t\t\t// `jQuery.globalEval` so that it can fake a nonce-containing node\n\t\t\t\t// via an object.\n\t\t\t\tval = node[ i ] || node.getAttribute && node.getAttribute( i );\n\t\t\t\tif ( val ) {\n\t\t\t\t\tscript.setAttribute( i, val );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tdoc.head.appendChild( script ).parentNode.removeChild( script );\n\t}\n\n\nfunction toType( obj ) {\n\tif ( obj == null ) {\n\t\treturn obj + \"\";\n\t}\n\n\t// Support: Android <=2.3 only (functionish RegExp)\n\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\tclass2type[ toString.call( obj ) ] || \"object\" :\n\t\ttypeof obj;\n}\n/* global Symbol */\n// Defining this global in .eslintrc.json would create a danger of using the global\n// unguarded in another place, it seems safer to define global only for this module\n\n\n\nvar\n\tversion = \"3.4.1\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t},\n\n\t// Support: Android <=4.0 only\n\t// Make sure we trim BOM and NBSP\n\trtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g;\n\njQuery.fn = jQuery.prototype = {\n\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\n\t\t// Return all the elements in a clean array\n\t\tif ( num == null ) {\n\t\t\treturn slice.call( this );\n\t\t}\n\n\t\t// Return just the one element from the set\n\t\treturn num < 0 ? this[ num + this.length ] : this[ num ];\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\teach: function( callback ) {\n\t\treturn jQuery.each( this, callback );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map( this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t} ) );\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor();\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: arr.sort,\n\tsplice: arr.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[ 0 ] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// Skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !isFunction( target ) ) {\n\t\ttarget = {};\n\t}\n\n\t// Extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\n\t\t// Only deal with non-null/undefined values\n\t\tif ( ( options = arguments[ i ] ) != null ) {\n\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent Object.prototype pollution\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( name === \"__proto__\" || target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject( copy ) ||\n\t\t\t\t\t( copyIsArray = Array.isArray( copy ) ) ) ) {\n\t\t\t\t\tsrc = target[ name ];\n\n\t\t\t\t\t// Ensure proper type for the source value\n\t\t\t\t\tif ( copyIsArray && !Array.isArray( src ) ) {\n\t\t\t\t\t\tclone = [];\n\t\t\t\t\t} else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {\n\t\t\t\t\t\tclone = {};\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src;\n\t\t\t\t\t}\n\t\t\t\t\tcopyIsArray = false;\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend( {\n\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\tisPlainObject: function( obj ) {\n\t\tvar proto, Ctor;\n\n\t\t// Detect obvious negatives\n\t\t// Use toString instead of jQuery.type to catch host objects\n\t\tif ( !obj || toString.call( obj ) !== \"[object Object]\" ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tproto = getProto( obj );\n\n\t\t// Objects with no prototype (e.g., `Object.create( null )`) are plain\n\t\tif ( !proto ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Objects with prototype are plain iff they were constructed by a global Object function\n\t\tCtor = hasOwn.call( proto, \"constructor\" ) && proto.constructor;\n\t\treturn typeof Ctor === \"function\" && fnToString.call( Ctor ) === ObjectFunctionString;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\t// Evaluates a script in a global context\n\tglobalEval: function( code, options ) {\n\t\tDOMEval( code, { nonce: options && options.nonce } );\n\t},\n\n\teach: function( obj, callback ) {\n\t\tvar length, i = 0;\n\n\t\tif ( isArrayLike( obj ) ) {\n\t\t\tlength = obj.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor ( i in obj ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// Support: Android <=4.0 only\n\ttrim: function( text ) {\n\t\treturn text == null ?\n\t\t\t\"\" :\n\t\t\t( text + \"\" ).replace( rtrim, \"\" );\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArrayLike( Object( arr ) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\treturn arr == null ? -1 : indexOf.call( arr, elem, i );\n\t},\n\n\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t// push.apply(_, arraylike) throws on ancient WebKit\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\tfor ( ; j < len; j++ ) {\n\t\t\tfirst[ i++ ] = second[ j ];\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar length, value,\n\t\t\ti = 0,\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArrayLike( elems ) ) {\n\t\t\tlength = elems.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn concat.apply( [], ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n} );\n\nif ( typeof Symbol === \"function\" ) {\n\tjQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];\n}\n\n// Populate the class2type map\njQuery.each( \"Boolean Number String Function Array Date RegExp Object Error Symbol\".split( \" \" ),\nfunction( i, name ) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n} );\n\nfunction isArrayLike( obj ) {\n\n\t// Support: real iOS 8.2 only (not reproducible in simulator)\n\t// `in` check used to prevent JIT error (gh-2145)\n\t// hasOwn isn't used here due to false negatives\n\t// regarding Nodelist length in IE\n\tvar length = !!obj && \"length\" in obj && obj.length,\n\t\ttype = toType( obj );\n\n\tif ( isFunction( obj ) || isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v2.3.4\n * https://sizzlejs.com/\n *\n * Copyright JS Foundation and other contributors\n * Released under the MIT license\n * https://js.foundation/\n *\n * Date: 2019-04-08\n */\n(function( window ) {\n\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + 1 * new Date(),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tnonnativeSelectorCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// Instance methods\n\thasOwn = ({}).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpush_native = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\t// Use a stripped-down indexOf as it's faster than native\n\t// https://jsperf.com/thor-indexof-vs-for/5\n\tindexOf = function( list, elem ) {\n\t\tvar i = 0,\n\t\t\tlen = list.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( list[i] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\n\t// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n\tidentifier = \"(?:\\\\\\\\.|[\\\\w-]|[^\\0-\\\\xa0])+\",\n\n\t// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + identifier + \")(?:\" + whitespace +\n\t\t// Operator (capture 2)\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\t\t// \"Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]\"\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" + whitespace +\n\t\t\"*\\\\]\",\n\n\tpseudos = \":(\" + identifier + \")(?:\\\\((\" +\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\t\t// 2. simple (capture 6)\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\t\t// 3. anything else (capture 2)\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + \"+\", \"g\" ),\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace + \"*\" ),\n\trdescend = new RegExp( whitespace + \"|>\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + identifier + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + identifier + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + identifier + \"|[*])\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + whitespace +\n\t\t\t\"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n\t\t\t\"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" +\n\t\t\twhitespace + \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trhtml = /HTML$/i,\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\n\t// CSS escapes\n\t// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\([\\\\da-f]{1,6}\" + whitespace + \"?|(\" + whitespace + \")|.)\", \"ig\" ),\n\tfunescape = function( _, escaped, escapedWhitespace ) {\n\t\tvar high = \"0x\" + escaped - 0x10000;\n\t\t// NaN means non-codepoint\n\t\t// Support: Firefox<24\n\t\t// Workaround erroneous numeric interpretation of +\"0x\"\n\t\treturn high !== high || escapedWhitespace ?\n\t\t\tescaped :\n\t\t\thigh < 0 ?\n\t\t\t\t// BMP codepoint\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\t// Supplemental Plane codepoint (surrogate pair)\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// CSS string/identifier serialization\n\t// https://drafts.csswg.org/cssom/#common-serializing-idioms\n\trcssescape = /([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\0-\\x1f\\x7f-\\uFFFF\\w-]/g,\n\tfcssescape = function( ch, asCodePoint ) {\n\t\tif ( asCodePoint ) {\n\n\t\t\t// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER\n\t\t\tif ( ch === \"\\0\" ) {\n\t\t\t\treturn \"\\uFFFD\";\n\t\t\t}\n\n\t\t\t// Control characters and (dependent upon position) numbers get escaped as code points\n\t\t\treturn ch.slice( 0, -1 ) + \"\\\\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + \" \";\n\t\t}\n\n\t\t// Other potentially-special ASCII characters get backslash-escaped\n\t\treturn \"\\\\\" + ch;\n\t},\n\n\t// Used for iframes\n\t// See setDocument()\n\t// Removing the function wrapper causes a \"Permission Denied\"\n\t// error in IE\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t},\n\n\tinDisabledFieldset = addCombinator(\n\t\tfunction( elem ) {\n\t\t\treturn elem.disabled === true && elem.nodeName.toLowerCase() === \"fieldset\";\n\t\t},\n\t\t{ dir: \"parentNode\", next: \"legend\" }\n\t);\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t(arr = slice.call( preferredDoc.childNodes )),\n\t\tpreferredDoc.childNodes\n\t);\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpush_native.apply( target, slice.call(els) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( (target[j++] = els[i++]) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar m, i, elem, nid, match, groups, newSelector,\n\t\tnewContext = context && context.ownerDocument,\n\n\t\t// nodeType defaults to 9, since context defaults to document\n\t\tnodeType = context ? context.nodeType : 9;\n\n\tresults = results || [];\n\n\t// Return early from calls with invalid selector or context\n\tif ( typeof selector !== \"string\" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\t// Try to shortcut find operations (as opposed to filters) in HTML documents\n\tif ( !seed ) {\n\n\t\tif ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {\n\t\t\tsetDocument( context );\n\t\t}\n\t\tcontext = context || document;\n\n\t\tif ( documentIsHTML ) {\n\n\t\t\t// If the selector is sufficiently simple, try using a \"get*By*\" DOM method\n\t\t\t// (excepting DocumentFragment context, where the methods don't exist)\n\t\t\tif ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {\n\n\t\t\t\t// ID selector\n\t\t\t\tif ( (m = match[1]) ) {\n\n\t\t\t\t\t// Document context\n\t\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\t\tif ( (elem = context.getElementById( m )) ) {\n\n\t\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t// Element context\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\tif ( newContext && (elem = newContext.getElementById( m )) &&\n\t\t\t\t\t\t\tcontains( context, elem ) &&\n\t\t\t\t\t\t\telem.id === m ) {\n\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t// Type selector\n\t\t\t\t} else if ( match[2] ) {\n\t\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\t\treturn results;\n\n\t\t\t\t// Class selector\n\t\t\t\t} else if ( (m = match[3]) && support.getElementsByClassName &&\n\t\t\t\t\tcontext.getElementsByClassName ) {\n\n\t\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\t\treturn results;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Take advantage of querySelectorAll\n\t\t\tif ( support.qsa &&\n\t\t\t\t!nonnativeSelectorCache[ selector + \" \" ] &&\n\t\t\t\t(!rbuggyQSA || !rbuggyQSA.test( selector )) &&\n\n\t\t\t\t// Support: IE 8 only\n\t\t\t\t// Exclude object elements\n\t\t\t\t(nodeType !== 1 || context.nodeName.toLowerCase() !== \"object\") ) {\n\n\t\t\t\tnewSelector = selector;\n\t\t\t\tnewContext = context;\n\n\t\t\t\t// qSA considers elements outside a scoping root when evaluating child or\n\t\t\t\t// descendant combinators, which is not what we want.\n\t\t\t\t// In such cases, we work around the behavior by prefixing every selector in the\n\t\t\t\t// list with an ID selector referencing the scope context.\n\t\t\t\t// Thanks to Andrew Dupont for this technique.\n\t\t\t\tif ( nodeType === 1 && rdescend.test( selector ) ) {\n\n\t\t\t\t\t// Capture the context ID, setting it first if necessary\n\t\t\t\t\tif ( (nid = context.getAttribute( \"id\" )) ) {\n\t\t\t\t\t\tnid = nid.replace( rcssescape, fcssescape );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcontext.setAttribute( \"id\", (nid = expando) );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prefix every selector in the list\n\t\t\t\t\tgroups = tokenize( selector );\n\t\t\t\t\ti = groups.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tgroups[i] = \"#\" + nid + \" \" + toSelector( groups[i] );\n\t\t\t\t\t}\n\t\t\t\t\tnewSelector = groups.join( \",\" );\n\n\t\t\t\t\t// Expand context for sibling selectors\n\t\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) ||\n\t\t\t\t\t\tcontext;\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t);\n\t\t\t\t\treturn results;\n\t\t\t\t} catch ( qsaError ) {\n\t\t\t\t\tnonnativeSelectorCache( selector, true );\n\t\t\t\t} finally {\n\t\t\t\t\tif ( nid === expando ) {\n\t\t\t\t\t\tcontext.removeAttribute( \"id\" );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {function(string, object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn (cache[ key + \" \" ] = value);\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created element and returns a boolean result\n */\nfunction assert( fn ) {\n\tvar el = document.createElement(\"fieldset\");\n\n\ttry {\n\t\treturn !!fn( el );\n\t} catch (e) {\n\t\treturn false;\n\t} finally {\n\t\t// Remove from its parent by default\n\t\tif ( el.parentNode ) {\n\t\t\tel.parentNode.removeChild( el );\n\t\t}\n\t\t// release memory in IE\n\t\tel = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split(\"|\"),\n\t\ti = arr.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[i] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\ta.sourceIndex - b.sourceIndex;\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( (cur = cur.nextSibling) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn (name === \"input\" || name === \"button\") && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for :enabled/:disabled\n * @param {Boolean} disabled true for :disabled; false for :enabled\n */\nfunction createDisabledPseudo( disabled ) {\n\n\t// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable\n\treturn function( elem ) {\n\n\t\t// Only certain elements can match :enabled or :disabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled\n\t\tif ( \"form\" in elem ) {\n\n\t\t\t// Check for inherited disabledness on relevant non-disabled elements:\n\t\t\t// * listed form-associated elements in a disabled fieldset\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#category-listed\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled\n\t\t\t// * option elements in a disabled optgroup\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled\n\t\t\t// All such elements have a \"form\" property.\n\t\t\tif ( elem.parentNode && elem.disabled === false ) {\n\n\t\t\t\t// Option elements defer to a parent optgroup if present\n\t\t\t\tif ( \"label\" in elem ) {\n\t\t\t\t\tif ( \"label\" in elem.parentNode ) {\n\t\t\t\t\t\treturn elem.parentNode.disabled === disabled;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn elem.disabled === disabled;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Support: IE 6 - 11\n\t\t\t\t// Use the isDisabled shortcut property to check for disabled fieldset ancestors\n\t\t\t\treturn elem.isDisabled === disabled ||\n\n\t\t\t\t\t// Where there is no isDisabled, check manually\n\t\t\t\t\t/* jshint -W018 */\n\t\t\t\t\telem.isDisabled !== !disabled &&\n\t\t\t\t\t\tinDisabledFieldset( elem ) === disabled;\n\t\t\t}\n\n\t\t\treturn elem.disabled === disabled;\n\n\t\t// Try to winnow out elements that can't be disabled before trusting the disabled property.\n\t\t// Some victims get caught in our net (label, legend, menu, track), but it shouldn't\n\t\t// even exist on them, let alone have a boolean value.\n\t\t} else if ( \"label\" in elem ) {\n\t\t\treturn elem.disabled === disabled;\n\t\t}\n\n\t\t// Remaining elements are neither :enabled nor :disabled\n\t\treturn false;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction(function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction(function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ (j = matchIndexes[i]) ] ) {\n\t\t\t\t\tseed[j] = !(matches[j] = seed[j]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== \"undefined\" && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\tvar namespace = elem.namespaceURI,\n\t\tdocElem = (elem.ownerDocument || elem).documentElement;\n\n\t// Support: IE <=8\n\t// Assume HTML when documentElement doesn't yet exist, such as inside loading iframes\n\t// https://bugs.jquery.com/ticket/4833\n\treturn !rhtml.test( namespace || docElem && docElem.nodeName || \"HTML\" );\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare, subWindow,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// Return early if doc is invalid or already selected\n\tif ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Update global variables\n\tdocument = doc;\n\tdocElem = document.documentElement;\n\tdocumentIsHTML = !isXML( document );\n\n\t// Support: IE 9-11, Edge\n\t// Accessing iframe documents after unload throws \"permission denied\" errors (jQuery #13936)\n\tif ( preferredDoc !== document &&\n\t\t(subWindow = document.defaultView) && subWindow.top !== subWindow ) {\n\n\t\t// Support: IE 11, Edge\n\t\tif ( subWindow.addEventListener ) {\n\t\t\tsubWindow.addEventListener( \"unload\", unloadHandler, false );\n\n\t\t// Support: IE 9 - 10 only\n\t\t} else if ( subWindow.attachEvent ) {\n\t\t\tsubWindow.attachEvent( \"onunload\", unloadHandler );\n\t\t}\n\t}\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties\n\t// (excepting IE8 booleans)\n\tsupport.attributes = assert(function( el ) {\n\t\tel.className = \"i\";\n\t\treturn !el.getAttribute(\"className\");\n\t});\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert(function( el ) {\n\t\tel.appendChild( document.createComment(\"\") );\n\t\treturn !el.getElementsByTagName(\"*\").length;\n\t});\n\n\t// Support: IE<9\n\tsupport.getElementsByClassName = rnative.test( document.getElementsByClassName );\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programmatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert(function( el ) {\n\t\tdocElem.appendChild( el ).id = expando;\n\t\treturn !document.getElementsByName || !document.getElementsByName( expando ).length;\n\t});\n\n\t// ID filter and find\n\tif ( support.getById ) {\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute(\"id\") === attrId;\n\t\t\t};\n\t\t};\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar elem = context.getElementById( id );\n\t\t\t\treturn elem ? [ elem ] : [];\n\t\t\t}\n\t\t};\n\t} else {\n\t\tExpr.filter[\"ID\"] =  function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" &&\n\t\t\t\t\telem.getAttributeNode(\"id\");\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\n\t\t// Support: IE 6 - 7 only\n\t\t// getElementById is not reliable as a find shortcut\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar node, i, elems,\n\t\t\t\t\telem = context.getElementById( id );\n\n\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t// Verify the id attribute\n\t\t\t\t\tnode = elem.getAttributeNode(\"id\");\n\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t}\n\n\t\t\t\t\t// Fall back on getElementsByName\n\t\t\t\t\telems = context.getElementsByName( id );\n\t\t\t\t\ti = 0;\n\t\t\t\t\twhile ( (elem = elems[i++]) ) {\n\t\t\t\t\t\tnode = elem.getAttributeNode(\"id\");\n\t\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn [];\n\t\t\t}\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[\"TAG\"] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t\t// DocumentFragment nodes don't have gEBTN\n\t\t\t} else if ( support.qsa ) {\n\t\t\t\treturn context.querySelectorAll( tag );\n\t\t\t}\n\t\t} :\n\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\t\t\t\t// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( (elem = results[i++]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[\"CLASS\"] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( typeof context.getElementsByClassName !== \"undefined\" && documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See https://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( (support.qsa = rnative.test( document.querySelectorAll )) ) {\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert(function( el ) {\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// https://bugs.jquery.com/ticket/12359\n\t\t\tdocElem.appendChild( el ).innerHTML = \"<a id='\" + expando + \"'></a>\" +\n\t\t\t\t\"<select id='\" + expando + \"-\\r\\\\' msallowcapture=''>\" +\n\t\t\t\t\"<option selected=''></option></select>\";\n\n\t\t\t// Support: IE8, Opera 11-12.16\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\t// The test attribute must be unknown in Opera but \"safe\" for WinRT\n\t\t\t// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\t\t\tif ( el.querySelectorAll(\"[msallowcapture^='']\").length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !el.querySelectorAll(\"[selected]\").length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+\n\t\t\tif ( !el.querySelectorAll( \"[id~=\" + expando + \"-]\" ).length ) {\n\t\t\t\trbuggyQSA.push(\"~=\");\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !el.querySelectorAll(\":checked\").length ) {\n\t\t\t\trbuggyQSA.push(\":checked\");\n\t\t\t}\n\n\t\t\t// Support: Safari 8+, iOS 8+\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t\t// In-page `selector#id sibling-combinator selector` fails\n\t\t\tif ( !el.querySelectorAll( \"a#\" + expando + \"+*\" ).length ) {\n\t\t\t\trbuggyQSA.push(\".#.+[+~]\");\n\t\t\t}\n\t\t});\n\n\t\tassert(function( el ) {\n\t\t\tel.innerHTML = \"<a href='' disabled='disabled'></a>\" +\n\t\t\t\t\"<select disabled='disabled'><option/></select>\";\n\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = document.createElement(\"input\");\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tel.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( el.querySelectorAll(\"[name=d]\").length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( el.querySelectorAll(\":enabled\").length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Support: IE9-11+\n\t\t\t// IE's :disabled selector does not pick up the children of disabled fieldsets\n\t\t\tdocElem.appendChild( el ).disabled = true;\n\t\t\tif ( el.querySelectorAll(\":disabled\").length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tel.querySelectorAll(\"*,:x\");\n\t\t\trbuggyQSA.push(\",.*:\");\n\t\t});\n\t}\n\n\tif ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector) )) ) {\n\n\t\tassert(function( el ) {\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( el, \"*\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( el, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t});\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join(\"|\") );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join(\"|\") );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully self-exclusive\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t));\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( (b = b.parentNode) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\tcompare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\tif ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\t\t\treturn a === document ? -1 :\n\t\t\t\tb === document ? 1 :\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[i] === bp[i] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[i], bp[i] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\tap[i] === preferredDoc ? -1 :\n\t\t\tbp[i] === preferredDoc ? 1 :\n\t\t\t0;\n\t};\n\n\treturn document;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t!nonnativeSelectorCache[ expr + \" \" ] &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\t\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t\t// fragment in IE 9\n\t\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tnonnativeSelectorCache( expr, true );\n\t\t}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\t// Set document vars if needed\n\tif ( ( context.ownerDocument || context ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t(val = elem.getAttributeNode(name)) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.escape = function( sel ) {\n\treturn (sel + \"\").replace( rcssescape, fcssescape );\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( (elem = results[i++]) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( (node = elem[i++]) ) {\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[1] = match[1].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[3] = ( match[3] || match[4] || match[5] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[3] = \" \" + match[3] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[1] = match[1].toLowerCase();\n\n\t\t\tif ( match[1].slice( 0, 3 ) === \"nth\" ) {\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[3] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === \"even\" || match[3] === \"odd\" ) );\n\t\t\t\tmatch[5] = +( ( match[7] + match[8] ) || match[3] === \"odd\" );\n\n\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[3] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[6] && match[2];\n\n\t\t\tif ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[3] ) {\n\t\t\t\tmatch[2] = match[4] || match[5] || \"\";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t(excess = tokenize( unquoted, true )) &&\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t(excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[0] = match[0].slice( 0, excess );\n\t\t\t\tmatch[2] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() { return true; } :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t(pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n\t\t\t\tclassCache( className, function( elem ) {\n\t\t\t\t\treturn pattern.test( typeof elem.className === \"string\" && elem.className || typeof elem.getAttribute !== \"undefined\" && elem.getAttribute(\"class\") || \"\" );\n\t\t\t\t});\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result.replace( rwhitespace, \" \" ) + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tvar cache, uniqueCache, outerCache, node, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType,\n\t\t\t\t\t\tdiff = false;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( (node = node[ dir ]) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) {\n\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\n\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\tnode = parent;\n\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\tdiff = nodeIndex && cache[ 2 ];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\t\tdiff = nodeIndex;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// xml :nth-child(...)\n\t\t\t\t\t\t\t// or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t\tif ( diff === false ) {\n\t\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t\tif ( ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) &&\n\t\t\t\t\t\t\t\t\t\t++diff ) {\n\n\t\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction(function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf( seed, matched[i] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[i] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction(function( selector ) {\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction(function( seed, matches, context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = unmatched[i]) ) {\n\t\t\t\t\t\t\tseed[i] = !(matches[i] = elem);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}) :\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tinput[0] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\t\t\t\t\t// Don't keep the element (issue #299)\n\t\t\t\t\tinput[0] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t}),\n\n\t\t\"has\": markFunction(function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t}),\n\n\t\t\"contains\": markFunction(function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t}),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test(lang || \"\") ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( (elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute(\"xml:lang\") || elem.getAttribute(\"lang\")) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( (elem = elem.parentNode) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t}),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": createDisabledPseudo( false ),\n\t\t\"disabled\": createDisabledPseudo( true ),\n\n\t\t\"checked\": function( elem ) {\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t//   but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[\"empty\"]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo(function() {\n\t\t\treturn [ 0 ];\n\t\t}),\n\n\t\t\"last\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t}),\n\n\t\t\"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t}),\n\n\t\t\"even\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ?\n\t\t\t\targument + length :\n\t\t\t\targument > length ?\n\t\t\t\t\tlength :\n\t\t\t\t\targument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t})\n\t}\n};\n\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || (match = rcomma.exec( soFar )) ) {\n\t\t\tif ( match ) {\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[0].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( (tokens = []) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( (match = rcombinators.exec( soFar )) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push({\n\t\t\t\tvalue: matched,\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[0].replace( rtrim, \" \" )\n\t\t\t});\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n\t\t\t\t(match = preFilters[ type ]( match ))) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push({\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t});\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[i].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tskip = combinator.next,\n\t\tkey = skip || dir,\n\t\tcheckNonElements = base && key === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, uniqueCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || (elem[ expando ] = {});\n\n\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\tuniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});\n\n\t\t\t\t\t\tif ( skip && skip === elem.nodeName.toLowerCase() ) {\n\t\t\t\t\t\t\telem = elem[ dir ] || elem;\n\t\t\t\t\t\t} else if ( (oldCache = uniqueCache[ key ]) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn (newCache[ 2 ] = oldCache[ 2 ]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\tuniqueCache[ key ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[i]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[0];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[i], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (elem = unmatched[i]) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction(function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( (elem = temp[i]) ) {\n\t\t\t\t\tmatcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = matcherOut[i]) ) {\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( (matcherIn[i] = elem) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, (matcherOut = []), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( (elem = matcherOut[i]) &&\n\t\t\t\t\t\t(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {\n\n\t\t\t\t\t\tseed[temp] = !(results[temp] = elem);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[0].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[\" \"],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\tvar ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t(checkContext = context).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\t\t\t// Avoid hanging onto element (issue #299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n\t\t\tmatchers = [ addCombinator(elementMatcher( matchers ), matcher) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[j].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\t\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\t\ttokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" })\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[\"TAG\"]( \"*\", outermost ),\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\t\t\t\toutermostContext = context === document || context || outermost;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: <number>) matching elements by id\n\t\t\tfor ( ; i !== len && (elem = elems[i]) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\tif ( !context && elem.ownerDocument !== document ) {\n\t\t\t\t\t\tsetDocument( elem );\n\t\t\t\t\t\txml = !documentIsHTML;\n\t\t\t\t\t}\n\t\t\t\t\twhile ( (matcher = elementMatchers[j++]) ) {\n\t\t\t\t\t\tif ( matcher( elem, context || document, xml) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( (elem = !matcher && elem) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// `i` is now the count of elements visited above, and adding it to `matchedCount`\n\t\t\t// makes the latter nonnegative.\n\t\t\tmatchedCount += i;\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\t// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`\n\t\t\t// equals `i`), unless we didn't visit _any_ elements in the above loop because we have\n\t\t\t// no element matchers and no seed.\n\t\t\t// Incrementing an initially-string \"0\" `i` allows `i` to remain a string only in that\n\t\t\t// case, which will result in a \"00\" `matchedCount` that differs from `i` but is also\n\t\t\t// numerically zero.\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (matcher = setMatchers[j++]) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !(unmatched[i] || setMatched[i]) ) {\n\t\t\t\t\t\t\t\tsetMatched[i] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[i] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\n/**\n * A low-level selection function that works with Sizzle's compiled\n *  selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n *  selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( (selector = compiled.selector || selector) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is only one selector in the list and no seed\n\t// (the latter of which guarantees us context)\n\tif ( match.length === 1 ) {\n\n\t\t// Reduce context if the leading compound selector is an ID\n\t\ttokens = match[0] = match[0].slice( 0 );\n\t\tif ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n\t\t\t\tcontext.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) {\n\n\t\t\tcontext = ( Expr.find[\"ID\"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr[\"needsContext\"].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[i];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ (type = token.type) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( (find = Expr.find[ type ]) ) {\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( (seed = find(\n\t\t\t\t\ttoken.matches[0].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context\n\t\t\t\t)) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\t!context || rsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split(\"\").sort( sortOrder ).join(\"\") === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert(function( el ) {\n\t// Should return 1, but returns 4 (following)\n\treturn el.compareDocumentPosition( document.createElement(\"fieldset\") ) & 1;\n});\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert(function( el ) {\n\tel.innerHTML = \"<a href='#'></a>\";\n\treturn el.firstChild.getAttribute(\"href\") === \"#\" ;\n}) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert(function( el ) {\n\tel.innerHTML = \"<input/>\";\n\tel.firstChild.setAttribute( \"value\", \"\" );\n\treturn el.firstChild.getAttribute( \"value\" ) === \"\";\n}) ) {\n\taddHandle( \"value\", function( elem, name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert(function( el ) {\n\treturn el.getAttribute(\"disabled\") == null;\n}) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t\t(val = elem.getAttributeNode( name )) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\tnull;\n\t\t}\n\t});\n}\n\nreturn Sizzle;\n\n})( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\n\n// Deprecated\njQuery.expr[ \":\" ] = jQuery.expr.pseudos;\njQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\njQuery.escapeSelector = Sizzle.escape;\n\n\n\n\nvar dir = function( elem, dir, until ) {\n\tvar matched = [],\n\t\ttruncate = until !== undefined;\n\n\twhile ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {\n\t\tif ( elem.nodeType === 1 ) {\n\t\t\tif ( truncate && jQuery( elem ).is( until ) ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmatched.push( elem );\n\t\t}\n\t}\n\treturn matched;\n};\n\n\nvar siblings = function( n, elem ) {\n\tvar matched = [];\n\n\tfor ( ; n; n = n.nextSibling ) {\n\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\tmatched.push( n );\n\t\t}\n\t}\n\n\treturn matched;\n};\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\n\n\nfunction nodeName( elem, name ) {\n\n  return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\n};\nvar rsingleTag = ( /^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i );\n\n\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t} );\n\t}\n\n\t// Single element\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t} );\n\t}\n\n\t// Arraylike of elements (jQuery, arguments, Array)\n\tif ( typeof qualifier !== \"string\" ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( indexOf.call( qualifier, elem ) > -1 ) !== not;\n\t\t} );\n\t}\n\n\t// Filtered directly for both simple and complex selectors\n\treturn jQuery.filter( qualifier, elements, not );\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\tif ( elems.length === 1 && elem.nodeType === 1 ) {\n\t\treturn jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];\n\t}\n\n\treturn jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\treturn elem.nodeType === 1;\n\t} ) );\n};\n\njQuery.fn.extend( {\n\tfind: function( selector ) {\n\t\tvar i, ret,\n\t\t\tlen = this.length,\n\t\t\tself = this;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter( function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} ) );\n\t\t}\n\n\t\tret = this.pushStack( [] );\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\treturn len > 1 ? jQuery.uniqueSort( ret ) : ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], false ) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], true ) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n} );\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\t// Shortcut simple #id case for speed\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/,\n\n\tinit = jQuery.fn.init = function( selector, context, root ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Method init() accepts an alternate rootjQuery\n\t\t// so migrate can support jQuery.sub (gh-2101)\n\t\troot = root || rootjQuery;\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector[ 0 ] === \"<\" &&\n\t\t\t\tselector[ selector.length - 1 ] === \">\" &&\n\t\t\t\tselector.length >= 3 ) {\n\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && ( match[ 1 ] || !context ) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[ 1 ] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[ 0 ] : context;\n\n\t\t\t\t\t// Option to run scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[ 1 ],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[ 2 ] );\n\n\t\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t\t// Inject the element directly into the jQuery object\n\t\t\t\t\t\tthis[ 0 ] = elem;\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || root ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis[ 0 ] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( isFunction( selector ) ) {\n\t\t\treturn root.ready !== undefined ?\n\t\t\t\troot.ready( selector ) :\n\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\n\t// Methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.fn.extend( {\n\thas: function( target ) {\n\t\tvar targets = jQuery( target, this ),\n\t\t\tl = targets.length;\n\n\t\treturn this.filter( function() {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[ i ] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\ttargets = typeof selectors !== \"string\" && jQuery( selectors );\n\n\t\t// Positional selectors never match, since there's no _selection_ context\n\t\tif ( !rneedsContext.test( selectors ) ) {\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tfor ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {\n\n\t\t\t\t\t// Always skip document fragments\n\t\t\t\t\tif ( cur.nodeType < 11 && ( targets ?\n\t\t\t\t\t\ttargets.index( cur ) > -1 :\n\n\t\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\t\tjQuery.find.matchesSelector( cur, selectors ) ) ) {\n\n\t\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within the set\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// Index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn indexOf.call( jQuery( elem ), this[ 0 ] );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn indexOf.call( this,\n\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[ 0 ] : elem\n\t\t);\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.uniqueSort(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter( selector )\n\t\t);\n\t}\n} );\n\nfunction sibling( cur, dir ) {\n\twhile ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}\n\treturn cur;\n}\n\njQuery.each( {\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn siblings( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn siblings( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\tif ( typeof elem.contentDocument !== \"undefined\" ) {\n\t\t\treturn elem.contentDocument;\n\t\t}\n\n\t\t// Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only\n\t\t// Treat the template element as a regular one in browsers that\n\t\t// don't support it.\n\t\tif ( nodeName( elem, \"template\" ) ) {\n\t\t\telem = elem.content || elem;\n\t\t}\n\n\t\treturn jQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar matched = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tmatched = jQuery.filter( selector, matched );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tjQuery.uniqueSort( matched );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tmatched.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched );\n\t};\n} );\nvar rnothtmlwhite = ( /[^\\x20\\t\\r\\n\\f]+/g );\n\n\n\n// Convert String-formatted options into Object-formatted ones\nfunction createOptions( options ) {\n\tvar object = {};\n\tjQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t} );\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\tcreateOptions( options ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\n\t\t// Last fire value for non-forgettable lists\n\t\tmemory,\n\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\n\t\t// Flag to prevent firing\n\t\tlocked,\n\n\t\t// Actual callback list\n\t\tlist = [],\n\n\t\t// Queue of execution data for repeatable lists\n\t\tqueue = [],\n\n\t\t// Index of currently firing callback (modified by add/remove as needed)\n\t\tfiringIndex = -1,\n\n\t\t// Fire callbacks\n\t\tfire = function() {\n\n\t\t\t// Enforce single-firing\n\t\t\tlocked = locked || options.once;\n\n\t\t\t// Execute callbacks for all pending executions,\n\t\t\t// respecting firingIndex overrides and runtime changes\n\t\t\tfired = firing = true;\n\t\t\tfor ( ; queue.length; firingIndex = -1 ) {\n\t\t\t\tmemory = queue.shift();\n\t\t\t\twhile ( ++firingIndex < list.length ) {\n\n\t\t\t\t\t// Run callback and check for early termination\n\t\t\t\t\tif ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&\n\t\t\t\t\t\toptions.stopOnFalse ) {\n\n\t\t\t\t\t\t// Jump to end and forget the data so .add doesn't re-fire\n\t\t\t\t\t\tfiringIndex = list.length;\n\t\t\t\t\t\tmemory = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Forget the data if we're done with it\n\t\t\tif ( !options.memory ) {\n\t\t\t\tmemory = false;\n\t\t\t}\n\n\t\t\tfiring = false;\n\n\t\t\t// Clean up if we're done firing for good\n\t\t\tif ( locked ) {\n\n\t\t\t\t// Keep an empty list if we have data for future add calls\n\t\t\t\tif ( memory ) {\n\t\t\t\t\tlist = [];\n\n\t\t\t\t// Otherwise, this object is spent\n\t\t\t\t} else {\n\t\t\t\t\tlist = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t// Actual Callbacks object\n\t\tself = {\n\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\n\t\t\t\t\t// If we have memory from a past run, we should fire after adding\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfiringIndex = list.length - 1;\n\t\t\t\t\t\tqueue.push( memory );\n\t\t\t\t\t}\n\n\t\t\t\t\t( function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tif ( isFunction( arg ) ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && toType( arg ) !== \"string\" ) {\n\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t} )( arguments );\n\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\tvar index;\n\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\tlist.splice( index, 1 );\n\n\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ?\n\t\t\t\t\tjQuery.inArray( fn, list ) > -1 :\n\t\t\t\t\tlist.length > 0;\n\t\t\t},\n\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Disable .fire and .add\n\t\t\t// Abort any current/pending executions\n\t\t\t// Clear all callbacks and values\n\t\t\tdisable: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tlist = memory = \"\";\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\n\t\t\t// Disable .fire\n\t\t\t// Also disable .add unless we have memory (since it would have no effect)\n\t\t\t// Abort any pending executions\n\t\t\tlock: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tif ( !memory && !firing ) {\n\t\t\t\t\tlist = memory = \"\";\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tlocked: function() {\n\t\t\t\treturn !!locked;\n\t\t\t},\n\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( !locked ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tqueue.push( args );\n\t\t\t\t\tif ( !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\nfunction Identity( v ) {\n\treturn v;\n}\nfunction Thrower( ex ) {\n\tthrow ex;\n}\n\nfunction adoptValue( value, resolve, reject, noValue ) {\n\tvar method;\n\n\ttry {\n\n\t\t// Check for promise aspect first to privilege synchronous behavior\n\t\tif ( value && isFunction( ( method = value.promise ) ) ) {\n\t\t\tmethod.call( value ).done( resolve ).fail( reject );\n\n\t\t// Other thenables\n\t\t} else if ( value && isFunction( ( method = value.then ) ) ) {\n\t\t\tmethod.call( value, resolve, reject );\n\n\t\t// Other non-thenables\n\t\t} else {\n\n\t\t\t// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:\n\t\t\t// * false: [ value ].slice( 0 ) => resolve( value )\n\t\t\t// * true: [ value ].slice( 1 ) => resolve()\n\t\t\tresolve.apply( undefined, [ value ].slice( noValue ) );\n\t\t}\n\n\t// For Promises/A+, convert exceptions into rejections\n\t// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in\n\t// Deferred#then to conditionally suppress rejection.\n\t} catch ( value ) {\n\n\t\t// Support: Android 4.0 only\n\t\t// Strict mode functions invoked without .call/.apply get global-object context\n\t\treject.apply( undefined, [ value ] );\n\t}\n}\n\njQuery.extend( {\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\n\t\t\t\t// action, add listener, callbacks,\n\t\t\t\t// ... .then handlers, argument index, [final state]\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks( \"memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"memory\" ), 2 ],\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 0, \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 1, \"rejected\" ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\t\"catch\": function( fn ) {\n\t\t\t\t\treturn promise.then( null, fn );\n\t\t\t\t},\n\n\t\t\t\t// Keep pipe for back-compat\n\t\t\t\tpipe: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( i, tuple ) {\n\n\t\t\t\t\t\t\t// Map tuples (progress, done, fail) to arguments (done, fail, progress)\n\t\t\t\t\t\t\tvar fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];\n\n\t\t\t\t\t\t\t// deferred.progress(function() { bind to newDefer or newDefer.notify })\n\t\t\t\t\t\t\t// deferred.done(function() { bind to newDefer or newDefer.resolve })\n\t\t\t\t\t\t\t// deferred.fail(function() { bind to newDefer or newDefer.reject })\n\t\t\t\t\t\t\tdeferred[ tuple[ 1 ] ]( function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify )\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ](\n\t\t\t\t\t\t\t\t\t\tthis,\n\t\t\t\t\t\t\t\t\t\tfn ? [ returned ] : arguments\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} );\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\t\t\t\tthen: function( onFulfilled, onRejected, onProgress ) {\n\t\t\t\t\tvar maxDepth = 0;\n\t\t\t\t\tfunction resolve( depth, deferred, handler, special ) {\n\t\t\t\t\t\treturn function() {\n\t\t\t\t\t\t\tvar that = this,\n\t\t\t\t\t\t\t\targs = arguments,\n\t\t\t\t\t\t\t\tmightThrow = function() {\n\t\t\t\t\t\t\t\t\tvar returned, then;\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.3\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-59\n\t\t\t\t\t\t\t\t\t// Ignore double-resolution attempts\n\t\t\t\t\t\t\t\t\tif ( depth < maxDepth ) {\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturned = handler.apply( that, args );\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.1\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-48\n\t\t\t\t\t\t\t\t\tif ( returned === deferred.promise() ) {\n\t\t\t\t\t\t\t\t\t\tthrow new TypeError( \"Thenable self-resolution\" );\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ sections 2.3.3.1, 3.5\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-54\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-75\n\t\t\t\t\t\t\t\t\t// Retrieve `then` only once\n\t\t\t\t\t\t\t\t\tthen = returned &&\n\n\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.4\n\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-64\n\t\t\t\t\t\t\t\t\t\t// Only check objects and functions for thenability\n\t\t\t\t\t\t\t\t\t\t( typeof returned === \"object\" ||\n\t\t\t\t\t\t\t\t\t\t\ttypeof returned === \"function\" ) &&\n\t\t\t\t\t\t\t\t\t\treturned.then;\n\n\t\t\t\t\t\t\t\t\t// Handle a returned thenable\n\t\t\t\t\t\t\t\t\tif ( isFunction( then ) ) {\n\n\t\t\t\t\t\t\t\t\t\t// Special processors (notify) just wait for resolution\n\t\t\t\t\t\t\t\t\t\tif ( special ) {\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special )\n\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t// Normal processors (resolve) also hook into progress\n\t\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t\t// ...and disregard older resolution values\n\t\t\t\t\t\t\t\t\t\t\tmaxDepth++;\n\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity,\n\t\t\t\t\t\t\t\t\t\t\t\t\tdeferred.notifyWith )\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Handle all other returned values\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\tif ( handler !== Identity ) {\n\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\targs = [ returned ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t// Process the value(s)\n\t\t\t\t\t\t\t\t\t\t// Default process is resolve\n\t\t\t\t\t\t\t\t\t\t( special || deferred.resolveWith )( that, args );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\n\t\t\t\t\t\t\t\t// Only normal processors (resolve) catch and reject exceptions\n\t\t\t\t\t\t\t\tprocess = special ?\n\t\t\t\t\t\t\t\t\tmightThrow :\n\t\t\t\t\t\t\t\t\tfunction() {\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tmightThrow();\n\t\t\t\t\t\t\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t\t\t\t\t\t\tif ( jQuery.Deferred.exceptionHook ) {\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery.Deferred.exceptionHook( e,\n\t\t\t\t\t\t\t\t\t\t\t\t\tprocess.stackTrace );\n\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.4.1\n\t\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-61\n\t\t\t\t\t\t\t\t\t\t\t// Ignore post-resolution exceptions\n\t\t\t\t\t\t\t\t\t\t\tif ( depth + 1 >= maxDepth ) {\n\n\t\t\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\t\t\tif ( handler !== Thrower ) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\t\t\targs = [ e ];\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t\tdeferred.rejectWith( that, args );\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.1\n\t\t\t\t\t\t\t// https://promisesaplus.com/#point-57\n\t\t\t\t\t\t\t// Re-resolve promises immediately to dodge false rejection from\n\t\t\t\t\t\t\t// subsequent errors\n\t\t\t\t\t\t\tif ( depth ) {\n\t\t\t\t\t\t\t\tprocess();\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// Call an optional hook to record the stack, in case of exception\n\t\t\t\t\t\t\t\t// since it's otherwise lost when execution goes async\n\t\t\t\t\t\t\t\tif ( jQuery.Deferred.getStackHook ) {\n\t\t\t\t\t\t\t\t\tprocess.stackTrace = jQuery.Deferred.getStackHook();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\twindow.setTimeout( process );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\n\t\t\t\t\t\t// progress_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 0 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onProgress ) ?\n\t\t\t\t\t\t\t\t\tonProgress :\n\t\t\t\t\t\t\t\t\tIdentity,\n\t\t\t\t\t\t\t\tnewDefer.notifyWith\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// fulfilled_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 1 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onFulfilled ) ?\n\t\t\t\t\t\t\t\t\tonFulfilled :\n\t\t\t\t\t\t\t\t\tIdentity\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// rejected_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 2 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onRejected ) ?\n\t\t\t\t\t\t\t\t\tonRejected :\n\t\t\t\t\t\t\t\t\tThrower\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 5 ];\n\n\t\t\t// promise.progress = list.add\n\t\t\t// promise.done = list.add\n\t\t\t// promise.fail = list.add\n\t\t\tpromise[ tuple[ 1 ] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(\n\t\t\t\t\tfunction() {\n\n\t\t\t\t\t\t// state = \"resolved\" (i.e., fulfilled)\n\t\t\t\t\t\t// state = \"rejected\"\n\t\t\t\t\t\tstate = stateString;\n\t\t\t\t\t},\n\n\t\t\t\t\t// rejected_callbacks.disable\n\t\t\t\t\t// fulfilled_callbacks.disable\n\t\t\t\t\ttuples[ 3 - i ][ 2 ].disable,\n\n\t\t\t\t\t// rejected_handlers.disable\n\t\t\t\t\t// fulfilled_handlers.disable\n\t\t\t\t\ttuples[ 3 - i ][ 3 ].disable,\n\n\t\t\t\t\t// progress_callbacks.lock\n\t\t\t\t\ttuples[ 0 ][ 2 ].lock,\n\n\t\t\t\t\t// progress_handlers.lock\n\t\t\t\t\ttuples[ 0 ][ 3 ].lock\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// progress_handlers.fire\n\t\t\t// fulfilled_handlers.fire\n\t\t\t// rejected_handlers.fire\n\t\t\tlist.add( tuple[ 3 ].fire );\n\n\t\t\t// deferred.notify = function() { deferred.notifyWith(...) }\n\t\t\t// deferred.resolve = function() { deferred.resolveWith(...) }\n\t\t\t// deferred.reject = function() { deferred.rejectWith(...) }\n\t\t\tdeferred[ tuple[ 0 ] ] = function() {\n\t\t\t\tdeferred[ tuple[ 0 ] + \"With\" ]( this === deferred ? undefined : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\n\t\t\t// deferred.notifyWith = list.fireWith\n\t\t\t// deferred.resolveWith = list.fireWith\n\t\t\t// deferred.rejectWith = list.fireWith\n\t\t\tdeferred[ tuple[ 0 ] + \"With\" ] = list.fireWith;\n\t\t} );\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( singleValue ) {\n\t\tvar\n\n\t\t\t// count of uncompleted subordinates\n\t\t\tremaining = arguments.length,\n\n\t\t\t// count of unprocessed arguments\n\t\t\ti = remaining,\n\n\t\t\t// subordinate fulfillment data\n\t\t\tresolveContexts = Array( i ),\n\t\t\tresolveValues = slice.call( arguments ),\n\n\t\t\t// the master Deferred\n\t\t\tmaster = jQuery.Deferred(),\n\n\t\t\t// subordinate callback factory\n\t\t\tupdateFunc = function( i ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tresolveContexts[ i ] = this;\n\t\t\t\t\tresolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( !( --remaining ) ) {\n\t\t\t\t\t\tmaster.resolveWith( resolveContexts, resolveValues );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t};\n\n\t\t// Single- and empty arguments are adopted like Promise.resolve\n\t\tif ( remaining <= 1 ) {\n\t\t\tadoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,\n\t\t\t\t!remaining );\n\n\t\t\t// Use .then() to unwrap secondary thenables (cf. gh-3000)\n\t\t\tif ( master.state() === \"pending\" ||\n\t\t\t\tisFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {\n\n\t\t\t\treturn master.then();\n\t\t\t}\n\t\t}\n\n\t\t// Multiple arguments are aggregated like Promise.all array elements\n\t\twhile ( i-- ) {\n\t\t\tadoptValue( resolveValues[ i ], updateFunc( i ), master.reject );\n\t\t}\n\n\t\treturn master.promise();\n\t}\n} );\n\n\n// These usually indicate a programmer mistake during development,\n// warn about them ASAP rather than swallowing them by default.\nvar rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;\n\njQuery.Deferred.exceptionHook = function( error, stack ) {\n\n\t// Support: IE 8 - 9 only\n\t// Console exists when dev tools are open, which can happen at any time\n\tif ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {\n\t\twindow.console.warn( \"jQuery.Deferred exception: \" + error.message, error.stack, stack );\n\t}\n};\n\n\n\n\njQuery.readyException = function( error ) {\n\twindow.setTimeout( function() {\n\t\tthrow error;\n\t} );\n};\n\n\n\n\n// The deferred used on DOM ready\nvar readyList = jQuery.Deferred();\n\njQuery.fn.ready = function( fn ) {\n\n\treadyList\n\t\t.then( fn )\n\n\t\t// Wrap jQuery.readyException in a function so that the lookup\n\t\t// happens at the time of error handling instead of callback\n\t\t// registration.\n\t\t.catch( function( error ) {\n\t\t\tjQuery.readyException( error );\n\t\t} );\n\n\treturn this;\n};\n\njQuery.extend( {\n\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\t}\n} );\n\njQuery.ready.then = readyList.then;\n\n// The ready event handler and self cleanup method\nfunction completed() {\n\tdocument.removeEventListener( \"DOMContentLoaded\", completed );\n\twindow.removeEventListener( \"load\", completed );\n\tjQuery.ready();\n}\n\n// Catch cases where $(document).ready() is called\n// after the browser event has already occurred.\n// Support: IE <=9 - 10 only\n// Older IE sometimes signals \"interactive\" too soon\nif ( document.readyState === \"complete\" ||\n\t( document.readyState !== \"loading\" && !document.documentElement.doScroll ) ) {\n\n\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\twindow.setTimeout( jQuery.ready );\n\n} else {\n\n\t// Use the handy event callback\n\tdocument.addEventListener( \"DOMContentLoaded\", completed );\n\n\t// A fallback to window.onload, that will always work\n\twindow.addEventListener( \"load\", completed );\n}\n\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlen = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( toType( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\taccess( elems, fn, i, key[ i ], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\tfn(\n\t\t\t\t\telems[ i ], key, raw ?\n\t\t\t\t\tvalue :\n\t\t\t\t\tvalue.call( elems[ i ], i, fn( elems[ i ], key ) )\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( chainable ) {\n\t\treturn elems;\n\t}\n\n\t// Gets\n\tif ( bulk ) {\n\t\treturn fn.call( elems );\n\t}\n\n\treturn len ? fn( elems[ 0 ], key ) : emptyGet;\n};\n\n\n// Matches dashed string for camelizing\nvar rmsPrefix = /^-ms-/,\n\trdashAlpha = /-([a-z])/g;\n\n// Used by camelCase as callback to replace()\nfunction fcamelCase( all, letter ) {\n\treturn letter.toUpperCase();\n}\n\n// Convert dashed to camelCase; used by the css and data modules\n// Support: IE <=9 - 11, Edge 12 - 15\n// Microsoft forgot to hump their vendor prefix (#9572)\nfunction camelCase( string ) {\n\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n}\nvar acceptData = function( owner ) {\n\n\t// Accepts only:\n\t//  - Node\n\t//    - Node.ELEMENT_NODE\n\t//    - Node.DOCUMENT_NODE\n\t//  - Object\n\t//    - Any\n\treturn owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );\n};\n\n\n\n\nfunction Data() {\n\tthis.expando = jQuery.expando + Data.uid++;\n}\n\nData.uid = 1;\n\nData.prototype = {\n\n\tcache: function( owner ) {\n\n\t\t// Check if the owner object already has a cache\n\t\tvar value = owner[ this.expando ];\n\n\t\t// If not, create one\n\t\tif ( !value ) {\n\t\t\tvalue = {};\n\n\t\t\t// We can accept data for non-element nodes in modern browsers,\n\t\t\t// but we should not, see #8335.\n\t\t\t// Always return an empty object.\n\t\t\tif ( acceptData( owner ) ) {\n\n\t\t\t\t// If it is a node unlikely to be stringify-ed or looped over\n\t\t\t\t// use plain assignment\n\t\t\t\tif ( owner.nodeType ) {\n\t\t\t\t\towner[ this.expando ] = value;\n\n\t\t\t\t// Otherwise secure it in a non-enumerable property\n\t\t\t\t// configurable must be true to allow the property to be\n\t\t\t\t// deleted when data is removed\n\t\t\t\t} else {\n\t\t\t\t\tObject.defineProperty( owner, this.expando, {\n\t\t\t\t\t\tvalue: value,\n\t\t\t\t\t\tconfigurable: true\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn value;\n\t},\n\tset: function( owner, data, value ) {\n\t\tvar prop,\n\t\t\tcache = this.cache( owner );\n\n\t\t// Handle: [ owner, key, value ] args\n\t\t// Always use camelCase key (gh-2257)\n\t\tif ( typeof data === \"string\" ) {\n\t\t\tcache[ camelCase( data ) ] = value;\n\n\t\t// Handle: [ owner, { properties } ] args\n\t\t} else {\n\n\t\t\t// Copy the properties one-by-one to the cache object\n\t\t\tfor ( prop in data ) {\n\t\t\t\tcache[ camelCase( prop ) ] = data[ prop ];\n\t\t\t}\n\t\t}\n\t\treturn cache;\n\t},\n\tget: function( owner, key ) {\n\t\treturn key === undefined ?\n\t\t\tthis.cache( owner ) :\n\n\t\t\t// Always use camelCase key (gh-2257)\n\t\t\towner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];\n\t},\n\taccess: function( owner, key, value ) {\n\n\t\t// In cases where either:\n\t\t//\n\t\t//   1. No key was specified\n\t\t//   2. A string key was specified, but no value provided\n\t\t//\n\t\t// Take the \"read\" path and allow the get method to determine\n\t\t// which value to return, respectively either:\n\t\t//\n\t\t//   1. The entire cache object\n\t\t//   2. The data stored at the key\n\t\t//\n\t\tif ( key === undefined ||\n\t\t\t\t( ( key && typeof key === \"string\" ) && value === undefined ) ) {\n\n\t\t\treturn this.get( owner, key );\n\t\t}\n\n\t\t// When the key is not a string, or both a key and value\n\t\t// are specified, set or extend (existing objects) with either:\n\t\t//\n\t\t//   1. An object of properties\n\t\t//   2. A key and value\n\t\t//\n\t\tthis.set( owner, key, value );\n\n\t\t// Since the \"set\" path can have two possible entry points\n\t\t// return the expected data based on which path was taken[*]\n\t\treturn value !== undefined ? value : key;\n\t},\n\tremove: function( owner, key ) {\n\t\tvar i,\n\t\t\tcache = owner[ this.expando ];\n\n\t\tif ( cache === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key !== undefined ) {\n\n\t\t\t// Support array or space separated string of keys\n\t\t\tif ( Array.isArray( key ) ) {\n\n\t\t\t\t// If key is an array of keys...\n\t\t\t\t// We always set camelCase keys, so remove that.\n\t\t\t\tkey = key.map( camelCase );\n\t\t\t} else {\n\t\t\t\tkey = camelCase( key );\n\n\t\t\t\t// If a key with the spaces exists, use it.\n\t\t\t\t// Otherwise, create an array by matching non-whitespace\n\t\t\t\tkey = key in cache ?\n\t\t\t\t\t[ key ] :\n\t\t\t\t\t( key.match( rnothtmlwhite ) || [] );\n\t\t\t}\n\n\t\t\ti = key.length;\n\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete cache[ key[ i ] ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if there's no more data\n\t\tif ( key === undefined || jQuery.isEmptyObject( cache ) ) {\n\n\t\t\t// Support: Chrome <=35 - 45\n\t\t\t// Webkit & Blink performance suffers when deleting properties\n\t\t\t// from DOM nodes, so set to undefined instead\n\t\t\t// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)\n\t\t\tif ( owner.nodeType ) {\n\t\t\t\towner[ this.expando ] = undefined;\n\t\t\t} else {\n\t\t\t\tdelete owner[ this.expando ];\n\t\t\t}\n\t\t}\n\t},\n\thasData: function( owner ) {\n\t\tvar cache = owner[ this.expando ];\n\t\treturn cache !== undefined && !jQuery.isEmptyObject( cache );\n\t}\n};\nvar dataPriv = new Data();\n\nvar dataUser = new Data();\n\n\n\n//\tImplementation Summary\n//\n//\t1. Enforce API surface and semantic compatibility with 1.9.x branch\n//\t2. Improve the module's maintainability by reducing the storage\n//\t\tpaths to a single mechanism.\n//\t3. Use the same single mechanism to support \"private\" and \"user\" data.\n//\t4. _Never_ expose \"private\" data to user code (TODO: Drop _data, _removeData)\n//\t5. Avoid exposing implementation details on user objects (eg. expando properties)\n//\t6. Provide a clear path for implementation upgrade to WeakMap in 2014\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /[A-Z]/g;\n\nfunction getData( data ) {\n\tif ( data === \"true\" ) {\n\t\treturn true;\n\t}\n\n\tif ( data === \"false\" ) {\n\t\treturn false;\n\t}\n\n\tif ( data === \"null\" ) {\n\t\treturn null;\n\t}\n\n\t// Only convert to a number if it doesn't change the string\n\tif ( data === +data + \"\" ) {\n\t\treturn +data;\n\t}\n\n\tif ( rbrace.test( data ) ) {\n\t\treturn JSON.parse( data );\n\t}\n\n\treturn data;\n}\n\nfunction dataAttr( elem, key, data ) {\n\tvar name;\n\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\t\tname = \"data-\" + key.replace( rmultiDash, \"-$&\" ).toLowerCase();\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = getData( data );\n\t\t\t} catch ( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tdataUser.set( elem, key, data );\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\treturn data;\n}\n\njQuery.extend( {\n\thasData: function( elem ) {\n\t\treturn dataUser.hasData( elem ) || dataPriv.hasData( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn dataUser.access( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\tdataUser.remove( elem, name );\n\t},\n\n\t// TODO: Now that all calls to _data and _removeData have been replaced\n\t// with direct calls to dataPriv methods, these can be deprecated.\n\t_data: function( elem, name, data ) {\n\t\treturn dataPriv.access( elem, name, data );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\tdataPriv.remove( elem, name );\n\t}\n} );\n\njQuery.fn.extend( {\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[ 0 ],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = dataUser.get( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !dataPriv.get( elem, \"hasDataAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE 11 only\n\t\t\t\t\t\t// The attrs elements can be null (#14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = camelCase( name.slice( 5 ) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdataPriv.set( elem, \"hasDataAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each( function() {\n\t\t\t\tdataUser.set( this, key );\n\t\t\t} );\n\t\t}\n\n\t\treturn access( this, function( value ) {\n\t\t\tvar data;\n\n\t\t\t// The calling jQuery object (element matches) is not empty\n\t\t\t// (and therefore has an element appears at this[ 0 ]) and the\n\t\t\t// `value` parameter was not undefined. An empty jQuery object\n\t\t\t// will result in `undefined` for elem = this[ 0 ] which will\n\t\t\t// throw an exception if an attempt to read a data cache is made.\n\t\t\tif ( elem && value === undefined ) {\n\n\t\t\t\t// Attempt to get data from the cache\n\t\t\t\t// The key will always be camelCased in Data\n\t\t\t\tdata = dataUser.get( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// Attempt to \"discover\" the data in\n\t\t\t\t// HTML5 custom data-* attrs\n\t\t\t\tdata = dataAttr( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// We tried really hard, but the data doesn't exist.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Set the data...\n\t\t\tthis.each( function() {\n\n\t\t\t\t// We always store the camelCased key\n\t\t\t\tdataUser.set( this, key, value );\n\t\t\t} );\n\t\t}, null, value, arguments.length > 1, null, true );\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each( function() {\n\t\t\tdataUser.remove( this, key );\n\t\t} );\n\t}\n} );\n\n\njQuery.extend( {\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = dataPriv.get( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || Array.isArray( data ) ) {\n\t\t\t\t\tqueue = dataPriv.access( elem, type, jQuery.makeArray( data ) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// Clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// Not public - generate a queueHooks object, or return the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn dataPriv.get( elem, key ) || dataPriv.access( elem, key, {\n\t\t\tempty: jQuery.Callbacks( \"once memory\" ).add( function() {\n\t\t\t\tdataPriv.remove( elem, [ type + \"queue\", key ] );\n\t\t\t} )\n\t\t} );\n\t}\n} );\n\njQuery.fn.extend( {\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[ 0 ], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each( function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// Ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[ 0 ] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t} );\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t} );\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = dataPriv.get( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n} );\nvar pnum = ( /[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/ ).source;\n\nvar rcssNum = new RegExp( \"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\" );\n\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar documentElement = document.documentElement;\n\n\n\n\tvar isAttached = function( elem ) {\n\t\t\treturn jQuery.contains( elem.ownerDocument, elem );\n\t\t},\n\t\tcomposed = { composed: true };\n\n\t// Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only\n\t// Check attachment across shadow DOM boundaries when possible (gh-3504)\n\t// Support: iOS 10.0-10.2 only\n\t// Early iOS 10 versions support `attachShadow` but not `getRootNode`,\n\t// leading to errors. We need to check for `getRootNode`.\n\tif ( documentElement.getRootNode ) {\n\t\tisAttached = function( elem ) {\n\t\t\treturn jQuery.contains( elem.ownerDocument, elem ) ||\n\t\t\t\telem.getRootNode( composed ) === elem.ownerDocument;\n\t\t};\n\t}\nvar isHiddenWithinTree = function( elem, el ) {\n\n\t\t// isHiddenWithinTree might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\n\t\t// Inline style trumps all\n\t\treturn elem.style.display === \"none\" ||\n\t\t\telem.style.display === \"\" &&\n\n\t\t\t// Otherwise, check computed style\n\t\t\t// Support: Firefox <=43 - 45\n\t\t\t// Disconnected elements can have computed display: none, so first confirm that elem is\n\t\t\t// in the document.\n\t\t\tisAttached( elem ) &&\n\n\t\t\tjQuery.css( elem, \"display\" ) === \"none\";\n\t};\n\nvar swap = function( elem, options, callback, args ) {\n\tvar ret, name,\n\t\told = {};\n\n\t// Remember the old values, and insert the new ones\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.apply( elem, args || [] );\n\n\t// Revert the old values\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\n\n\nfunction adjustCSS( elem, prop, valueParts, tween ) {\n\tvar adjusted, scale,\n\t\tmaxIterations = 20,\n\t\tcurrentValue = tween ?\n\t\t\tfunction() {\n\t\t\t\treturn tween.cur();\n\t\t\t} :\n\t\t\tfunction() {\n\t\t\t\treturn jQuery.css( elem, prop, \"\" );\n\t\t\t},\n\t\tinitial = currentValue(),\n\t\tunit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n\t\t// Starting value computation is required for potential unit mismatches\n\t\tinitialInUnit = elem.nodeType &&\n\t\t\t( jQuery.cssNumber[ prop ] || unit !== \"px\" && +initial ) &&\n\t\t\trcssNum.exec( jQuery.css( elem, prop ) );\n\n\tif ( initialInUnit && initialInUnit[ 3 ] !== unit ) {\n\n\t\t// Support: Firefox <=54\n\t\t// Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)\n\t\tinitial = initial / 2;\n\n\t\t// Trust units reported by jQuery.css\n\t\tunit = unit || initialInUnit[ 3 ];\n\n\t\t// Iteratively approximate from a nonzero starting point\n\t\tinitialInUnit = +initial || 1;\n\n\t\twhile ( maxIterations-- ) {\n\n\t\t\t// Evaluate and update our best guess (doubling guesses that zero out).\n\t\t\t// Finish if the scale equals or crosses 1 (making the old*new product non-positive).\n\t\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\t\t\tif ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {\n\t\t\t\tmaxIterations = 0;\n\t\t\t}\n\t\t\tinitialInUnit = initialInUnit / scale;\n\n\t\t}\n\n\t\tinitialInUnit = initialInUnit * 2;\n\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\n\t\t// Make sure we update the tween properties later on\n\t\tvalueParts = valueParts || [];\n\t}\n\n\tif ( valueParts ) {\n\t\tinitialInUnit = +initialInUnit || +initial || 0;\n\n\t\t// Apply relative offset (+=/-=) if specified\n\t\tadjusted = valueParts[ 1 ] ?\n\t\t\tinitialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :\n\t\t\t+valueParts[ 2 ];\n\t\tif ( tween ) {\n\t\t\ttween.unit = unit;\n\t\t\ttween.start = initialInUnit;\n\t\t\ttween.end = adjusted;\n\t\t}\n\t}\n\treturn adjusted;\n}\n\n\nvar defaultDisplayMap = {};\n\nfunction getDefaultDisplay( elem ) {\n\tvar temp,\n\t\tdoc = elem.ownerDocument,\n\t\tnodeName = elem.nodeName,\n\t\tdisplay = defaultDisplayMap[ nodeName ];\n\n\tif ( display ) {\n\t\treturn display;\n\t}\n\n\ttemp = doc.body.appendChild( doc.createElement( nodeName ) );\n\tdisplay = jQuery.css( temp, \"display\" );\n\n\ttemp.parentNode.removeChild( temp );\n\n\tif ( display === \"none\" ) {\n\t\tdisplay = \"block\";\n\t}\n\tdefaultDisplayMap[ nodeName ] = display;\n\n\treturn display;\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\t// Determine new display value for elements that need to change\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\n\t\t\t// Since we force visibility upon cascade-hidden elements, an immediate (and slow)\n\t\t\t// check is required in this first loop unless we have a nonempty display value (either\n\t\t\t// inline or about-to-be-restored)\n\t\t\tif ( display === \"none\" ) {\n\t\t\t\tvalues[ index ] = dataPriv.get( elem, \"display\" ) || null;\n\t\t\t\tif ( !values[ index ] ) {\n\t\t\t\t\telem.style.display = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( elem.style.display === \"\" && isHiddenWithinTree( elem ) ) {\n\t\t\t\tvalues[ index ] = getDefaultDisplay( elem );\n\t\t\t}\n\t\t} else {\n\t\t\tif ( display !== \"none\" ) {\n\t\t\t\tvalues[ index ] = \"none\";\n\n\t\t\t\t// Remember what we're overwriting\n\t\t\t\tdataPriv.set( elem, \"display\", display );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of the elements in a second loop to avoid constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\tif ( values[ index ] != null ) {\n\t\t\telements[ index ].style.display = values[ index ];\n\t\t}\n\t}\n\n\treturn elements;\n}\n\njQuery.fn.extend( {\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tif ( isHiddenWithinTree( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t} );\n\t}\n} );\nvar rcheckableType = ( /^(?:checkbox|radio)$/i );\n\nvar rtagName = ( /<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)/i );\n\nvar rscriptType = ( /^$|^module$|\\/(?:java|ecma)script/i );\n\n\n\n// We have to close these tags to support XHTML (#13200)\nvar wrapMap = {\n\n\t// Support: IE <=9 only\n\toption: [ 1, \"<select multiple='multiple'>\", \"</select>\" ],\n\n\t// XHTML parsers do not magically insert elements in the\n\t// same way that tag soup parsers do. So we cannot shorten\n\t// this by omitting <tbody> or other required elements.\n\tthead: [ 1, \"<table>\", \"</table>\" ],\n\tcol: [ 2, \"<table><colgroup>\", \"</colgroup></table>\" ],\n\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\n\t_default: [ 0, \"\", \"\" ]\n};\n\n// Support: IE <=9 only\nwrapMap.optgroup = wrapMap.option;\n\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n\nfunction getAll( context, tag ) {\n\n\t// Support: IE <=9 - 11 only\n\t// Use typeof to avoid zero-argument method invocation on host objects (#15151)\n\tvar ret;\n\n\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\tret = context.getElementsByTagName( tag || \"*\" );\n\n\t} else if ( typeof context.querySelectorAll !== \"undefined\" ) {\n\t\tret = context.querySelectorAll( tag || \"*\" );\n\n\t} else {\n\t\tret = [];\n\t}\n\n\tif ( tag === undefined || tag && nodeName( context, tag ) ) {\n\t\treturn jQuery.merge( [ context ], ret );\n\t}\n\n\treturn ret;\n}\n\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar i = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\tdataPriv.set(\n\t\t\telems[ i ],\n\t\t\t\"globalEval\",\n\t\t\t!refElements || dataPriv.get( refElements[ i ], \"globalEval\" )\n\t\t);\n\t}\n}\n\n\nvar rhtml = /<|&#?\\w+;/;\n\nfunction buildFragment( elems, context, scripts, selection, ignored ) {\n\tvar elem, tmp, tag, wrap, attached, j,\n\t\tfragment = context.createDocumentFragment(),\n\t\tnodes = [],\n\t\ti = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\telem = elems[ i ];\n\n\t\tif ( elem || elem === 0 ) {\n\n\t\t\t// Add nodes directly\n\t\t\tif ( toType( elem ) === \"object\" ) {\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t// Convert non-html into a text node\n\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t// Convert html into DOM nodes\n\t\t\t} else {\n\t\t\t\ttmp = tmp || fragment.appendChild( context.createElement( \"div\" ) );\n\n\t\t\t\t// Deserialize a standard representation\n\t\t\t\ttag = ( rtagName.exec( elem ) || [ \"\", \"\" ] )[ 1 ].toLowerCase();\n\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\t\t\t\ttmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];\n\n\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\tj = wrap[ 0 ];\n\t\t\t\twhile ( j-- ) {\n\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t}\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t// Remember the top-level container\n\t\t\t\ttmp = fragment.firstChild;\n\n\t\t\t\t// Ensure the created nodes are orphaned (#12392)\n\t\t\t\ttmp.textContent = \"\";\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove wrapper from fragment\n\tfragment.textContent = \"\";\n\n\ti = 0;\n\twhile ( ( elem = nodes[ i++ ] ) ) {\n\n\t\t// Skip elements already in the context collection (trac-4087)\n\t\tif ( selection && jQuery.inArray( elem, selection ) > -1 ) {\n\t\t\tif ( ignored ) {\n\t\t\t\tignored.push( elem );\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tattached = isAttached( elem );\n\n\t\t// Append to fragment\n\t\ttmp = getAll( fragment.appendChild( elem ), \"script\" );\n\n\t\t// Preserve script evaluation history\n\t\tif ( attached ) {\n\t\t\tsetGlobalEval( tmp );\n\t\t}\n\n\t\t// Capture executables\n\t\tif ( scripts ) {\n\t\t\tj = 0;\n\t\t\twhile ( ( elem = tmp[ j++ ] ) ) {\n\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\tscripts.push( elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fragment;\n}\n\n\n( function() {\n\tvar fragment = document.createDocumentFragment(),\n\t\tdiv = fragment.appendChild( document.createElement( \"div\" ) ),\n\t\tinput = document.createElement( \"input\" );\n\n\t// Support: Android 4.0 - 4.3 only\n\t// Check state lost if the name is set (#11217)\n\t// Support: Windows Web Apps (WWA)\n\t// `name` and `type` must use .setAttribute for WWA (#14901)\n\tinput.setAttribute( \"type\", \"radio\" );\n\tinput.setAttribute( \"checked\", \"checked\" );\n\tinput.setAttribute( \"name\", \"t\" );\n\n\tdiv.appendChild( input );\n\n\t// Support: Android <=4.1 only\n\t// Older WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE <=11 only\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\tdiv.innerHTML = \"<textarea>x</textarea>\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n} )();\n\n\nvar\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\n// Support: IE <=9 - 11+\n// focus() and blur() are asynchronous, except when they are no-op.\n// So expect focus to be synchronous when the element is already active,\n// and blur to be synchronous when the element is not already active.\n// (focus and blur are always synchronous in other supported browsers,\n// this just defines when we can count on it).\nfunction expectSync( elem, type ) {\n\treturn ( elem === safeActiveElement() ) === ( type === \"focus\" );\n}\n\n// Support: IE <=9 only\n// Accessing document.activeElement can throw unexpectedly\n// https://bugs.jquery.com/ticket/13393\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\nfunction on( elem, types, selector, data, fn, one ) {\n\tvar origFn, type;\n\n\t// Types can be a map of types/handlers\n\tif ( typeof types === \"object\" ) {\n\n\t\t// ( types-Object, selector, data )\n\t\tif ( typeof selector !== \"string\" ) {\n\n\t\t\t// ( types-Object, data )\n\t\t\tdata = data || selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tfor ( type in types ) {\n\t\t\ton( elem, type, selector, data, types[ type ], one );\n\t\t}\n\t\treturn elem;\n\t}\n\n\tif ( data == null && fn == null ) {\n\n\t\t// ( types, fn )\n\t\tfn = selector;\n\t\tdata = selector = undefined;\n\t} else if ( fn == null ) {\n\t\tif ( typeof selector === \"string\" ) {\n\n\t\t\t// ( types, selector, fn )\n\t\t\tfn = data;\n\t\t\tdata = undefined;\n\t\t} else {\n\n\t\t\t// ( types, data, fn )\n\t\t\tfn = data;\n\t\t\tdata = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t}\n\tif ( fn === false ) {\n\t\tfn = returnFalse;\n\t} else if ( !fn ) {\n\t\treturn elem;\n\t}\n\n\tif ( one === 1 ) {\n\t\torigFn = fn;\n\t\tfn = function( event ) {\n\n\t\t\t// Can use an empty set, since event contains the info\n\t\t\tjQuery().off( event );\n\t\t\treturn origFn.apply( this, arguments );\n\t\t};\n\n\t\t// Use same guid so caller can remove using origFn\n\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t}\n\treturn elem.each( function() {\n\t\tjQuery.event.add( this, types, fn, data, selector );\n\t} );\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\n\t\tvar handleObjIn, eventHandle, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.get( elem );\n\n\t\t// Don't attach events to noData or text/comment nodes (but allow plain objects)\n\t\tif ( !elemData ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Ensure that invalid selectors throw exceptions at attach time\n\t\t// Evaluate against documentElement in case elem is a non-element node (e.g., document)\n\t\tif ( selector ) {\n\t\t\tjQuery.find.matchesSelector( documentElement, selector );\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !( events = elemData.events ) ) {\n\t\t\tevents = elemData.events = {};\n\t\t}\n\t\tif ( !( eventHandle = elemData.handle ) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== \"undefined\" && jQuery.event.triggered !== e.type ?\n\t\t\t\t\tjQuery.event.dispatch.apply( elem, arguments ) : undefined;\n\t\t\t};\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend( {\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join( \".\" )\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !( handlers = events[ type ] ) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener if the special events handler returns false\n\t\t\t\tif ( !special.setup ||\n\t\t\t\t\tspecial.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\n\t\tvar j, origCount, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.hasData( elem ) && dataPriv.get( elem );\n\n\t\tif ( !elemData || !( events = elemData.events ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[ 2 ] &&\n\t\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector ||\n\t\t\t\t\t\tselector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown ||\n\t\t\t\t\tspecial.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove data and the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdataPriv.remove( elem, \"handle events\" );\n\t\t}\n\t},\n\n\tdispatch: function( nativeEvent ) {\n\n\t\t// Make a writable jQuery.Event from the native event object\n\t\tvar event = jQuery.event.fix( nativeEvent );\n\n\t\tvar i, j, ret, matched, handleObj, handlerQueue,\n\t\t\targs = new Array( arguments.length ),\n\t\t\thandlers = ( dataPriv.get( this, \"events\" ) || {} )[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[ 0 ] = event;\n\n\t\tfor ( i = 1; i < arguments.length; i++ ) {\n\t\t\targs[ i ] = arguments[ i ];\n\t\t}\n\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( ( handleObj = matched.handlers[ j++ ] ) &&\n\t\t\t\t!event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// If the event is namespaced, then each handler is only invoked if it is\n\t\t\t\t// specially universal or its namespaces are a superset of the event's.\n\t\t\t\tif ( !event.rnamespace || handleObj.namespace === false ||\n\t\t\t\t\tevent.rnamespace.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||\n\t\t\t\t\t\thandleObj.handler ).apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( ( event.result = ret ) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar i, handleObj, sel, matchedHandlers, matchedSelectors,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\tif ( delegateCount &&\n\n\t\t\t// Support: IE <=9\n\t\t\t// Black-hole SVG <use> instance trees (trac-13180)\n\t\t\tcur.nodeType &&\n\n\t\t\t// Support: Firefox <=42\n\t\t\t// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)\n\t\t\t// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click\n\t\t\t// Support: IE 11 only\n\t\t\t// ...but not arrow key \"clicks\" of radio inputs, which can have `button` -1 (gh-2343)\n\t\t\t!( event.type === \"click\" && event.button >= 1 ) ) {\n\n\t\t\tfor ( ; cur !== this; cur = cur.parentNode || this ) {\n\n\t\t\t\t// Don't check non-elements (#13208)\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.nodeType === 1 && !( event.type === \"click\" && cur.disabled === true ) ) {\n\t\t\t\t\tmatchedHandlers = [];\n\t\t\t\t\tmatchedSelectors = {};\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatchedSelectors[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) > -1 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] ) {\n\t\t\t\t\t\t\tmatchedHandlers.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matchedHandlers.length ) {\n\t\t\t\t\t\thandlerQueue.push( { elem: cur, handlers: matchedHandlers } );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tcur = this;\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\taddProp: function( name, hook ) {\n\t\tObject.defineProperty( jQuery.Event.prototype, name, {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: true,\n\n\t\t\tget: isFunction( hook ) ?\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\t\treturn hook( this.originalEvent );\n\t\t\t\t\t}\n\t\t\t\t} :\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\t\treturn this.originalEvent[ name ];\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\tset: function( value ) {\n\t\t\t\tObject.defineProperty( this, name, {\n\t\t\t\t\tenumerable: true,\n\t\t\t\t\tconfigurable: true,\n\t\t\t\t\twritable: true,\n\t\t\t\t\tvalue: value\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t},\n\n\tfix: function( originalEvent ) {\n\t\treturn originalEvent[ jQuery.expando ] ?\n\t\t\toriginalEvent :\n\t\t\tnew jQuery.Event( originalEvent );\n\t},\n\n\tspecial: {\n\t\tload: {\n\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tclick: {\n\n\t\t\t// Utilize native event to ensure correct state for checkable inputs\n\t\t\tsetup: function( data ) {\n\n\t\t\t\t// For mutual compressibility with _default, replace `this` access with a local var.\n\t\t\t\t// `|| data` is dead code meant only to preserve the variable through minification.\n\t\t\t\tvar el = this || data;\n\n\t\t\t\t// Claim the first handler\n\t\t\t\tif ( rcheckableType.test( el.type ) &&\n\t\t\t\t\tel.click && nodeName( el, \"input\" ) ) {\n\n\t\t\t\t\t// dataPriv.set( el, \"click\", ... )\n\t\t\t\t\tleverageNative( el, \"click\", returnTrue );\n\t\t\t\t}\n\n\t\t\t\t// Return false to allow normal processing in the caller\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\ttrigger: function( data ) {\n\n\t\t\t\t// For mutual compressibility with _default, replace `this` access with a local var.\n\t\t\t\t// `|| data` is dead code meant only to preserve the variable through minification.\n\t\t\t\tvar el = this || data;\n\n\t\t\t\t// Force setup before triggering a click\n\t\t\t\tif ( rcheckableType.test( el.type ) &&\n\t\t\t\t\tel.click && nodeName( el, \"input\" ) ) {\n\n\t\t\t\t\tleverageNative( el, \"click\" );\n\t\t\t\t}\n\n\t\t\t\t// Return non-false to allow normal event-path propagation\n\t\t\t\treturn true;\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, suppress native .click() on links\n\t\t\t// Also prevent it if we're currently inside a leveraged native-event stack\n\t\t\t_default: function( event ) {\n\t\t\t\tvar target = event.target;\n\t\t\t\treturn rcheckableType.test( target.type ) &&\n\t\t\t\t\ttarget.click && nodeName( target, \"input\" ) &&\n\t\t\t\t\tdataPriv.get( target, \"click\" ) ||\n\t\t\t\t\tnodeName( target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Ensure the presence of an event listener that handles manually-triggered\n// synthetic events by interrupting progress until reinvoked in response to\n// *native* events that it fires directly, ensuring that state changes have\n// already occurred before other listeners are invoked.\nfunction leverageNative( el, type, expectSync ) {\n\n\t// Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add\n\tif ( !expectSync ) {\n\t\tif ( dataPriv.get( el, type ) === undefined ) {\n\t\t\tjQuery.event.add( el, type, returnTrue );\n\t\t}\n\t\treturn;\n\t}\n\n\t// Register the controller as a special universal handler for all event namespaces\n\tdataPriv.set( el, type, false );\n\tjQuery.event.add( el, type, {\n\t\tnamespace: false,\n\t\thandler: function( event ) {\n\t\t\tvar notAsync, result,\n\t\t\t\tsaved = dataPriv.get( this, type );\n\n\t\t\tif ( ( event.isTrigger & 1 ) && this[ type ] ) {\n\n\t\t\t\t// Interrupt processing of the outer synthetic .trigger()ed event\n\t\t\t\t// Saved data should be false in such cases, but might be a leftover capture object\n\t\t\t\t// from an async native handler (gh-4350)\n\t\t\t\tif ( !saved.length ) {\n\n\t\t\t\t\t// Store arguments for use when handling the inner native event\n\t\t\t\t\t// There will always be at least one argument (an event object), so this array\n\t\t\t\t\t// will not be confused with a leftover capture object.\n\t\t\t\t\tsaved = slice.call( arguments );\n\t\t\t\t\tdataPriv.set( this, type, saved );\n\n\t\t\t\t\t// Trigger the native event and capture its result\n\t\t\t\t\t// Support: IE <=9 - 11+\n\t\t\t\t\t// focus() and blur() are asynchronous\n\t\t\t\t\tnotAsync = expectSync( this, type );\n\t\t\t\t\tthis[ type ]();\n\t\t\t\t\tresult = dataPriv.get( this, type );\n\t\t\t\t\tif ( saved !== result || notAsync ) {\n\t\t\t\t\t\tdataPriv.set( this, type, false );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult = {};\n\t\t\t\t\t}\n\t\t\t\t\tif ( saved !== result ) {\n\n\t\t\t\t\t\t// Cancel the outer synthetic event\n\t\t\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\treturn result.value;\n\t\t\t\t\t}\n\n\t\t\t\t// If this is an inner synthetic event for an event with a bubbling surrogate\n\t\t\t\t// (focus or blur), assume that the surrogate already propagated from triggering the\n\t\t\t\t// native event and prevent that from happening again here.\n\t\t\t\t// This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the\n\t\t\t\t// bubbling surrogate propagates *after* the non-bubbling base), but that seems\n\t\t\t\t// less bad than duplication.\n\t\t\t\t} else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {\n\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t}\n\n\t\t\t// If this is a native event triggered above, everything is now in order\n\t\t\t// Fire an inner synthetic event with the original arguments\n\t\t\t} else if ( saved.length ) {\n\n\t\t\t\t// ...and capture the result\n\t\t\t\tdataPriv.set( this, type, {\n\t\t\t\t\tvalue: jQuery.event.trigger(\n\n\t\t\t\t\t\t// Support: IE <=9 - 11+\n\t\t\t\t\t\t// Extend with the prototype to reset the above stopImmediatePropagation()\n\t\t\t\t\t\tjQuery.extend( saved[ 0 ], jQuery.Event.prototype ),\n\t\t\t\t\t\tsaved.slice( 1 ),\n\t\t\t\t\t\tthis\n\t\t\t\t\t)\n\t\t\t\t} );\n\n\t\t\t\t// Abort handling of the native event\n\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t}\n\t\t}\n\t} );\n}\n\njQuery.removeEvent = function( elem, type, handle ) {\n\n\t// This \"if\" is needed for plain objects\n\tif ( elem.removeEventListener ) {\n\t\telem.removeEventListener( type, handle );\n\t}\n};\n\njQuery.Event = function( src, props ) {\n\n\t// Allow instantiation without the 'new' keyword\n\tif ( !( this instanceof jQuery.Event ) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\n\t\t\t\t// Support: Android <=2.3 only\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t\t// Create target properties\n\t\t// Support: Safari <=6 - 7 only\n\t\t// Target should not be a text node (#504, #13143)\n\t\tthis.target = ( src.target && src.target.nodeType === 3 ) ?\n\t\t\tsrc.target.parentNode :\n\t\t\tsrc.target;\n\n\t\tthis.currentTarget = src.currentTarget;\n\t\tthis.relatedTarget = src.relatedTarget;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || Date.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tconstructor: jQuery.Event,\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\tisSimulated: false,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.preventDefault();\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Includes all common event props including KeyEvent and MouseEvent specific props\njQuery.each( {\n\taltKey: true,\n\tbubbles: true,\n\tcancelable: true,\n\tchangedTouches: true,\n\tctrlKey: true,\n\tdetail: true,\n\teventPhase: true,\n\tmetaKey: true,\n\tpageX: true,\n\tpageY: true,\n\tshiftKey: true,\n\tview: true,\n\t\"char\": true,\n\tcode: true,\n\tcharCode: true,\n\tkey: true,\n\tkeyCode: true,\n\tbutton: true,\n\tbuttons: true,\n\tclientX: true,\n\tclientY: true,\n\toffsetX: true,\n\toffsetY: true,\n\tpointerId: true,\n\tpointerType: true,\n\tscreenX: true,\n\tscreenY: true,\n\ttargetTouches: true,\n\ttoElement: true,\n\ttouches: true,\n\n\twhich: function( event ) {\n\t\tvar button = event.button;\n\n\t\t// Add which for key events\n\t\tif ( event.which == null && rkeyEvent.test( event.type ) ) {\n\t\t\treturn event.charCode != null ? event.charCode : event.keyCode;\n\t\t}\n\n\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\tif ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {\n\t\t\tif ( button & 1 ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\tif ( button & 2 ) {\n\t\t\t\treturn 3;\n\t\t\t}\n\n\t\t\tif ( button & 4 ) {\n\t\t\t\treturn 2;\n\t\t\t}\n\n\t\t\treturn 0;\n\t\t}\n\n\t\treturn event.which;\n\t}\n}, jQuery.event.addProp );\n\njQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( type, delegateType ) {\n\tjQuery.event.special[ type ] = {\n\n\t\t// Utilize native event if possible so blur/focus sequence is correct\n\t\tsetup: function() {\n\n\t\t\t// Claim the first handler\n\t\t\t// dataPriv.set( this, \"focus\", ... )\n\t\t\t// dataPriv.set( this, \"blur\", ... )\n\t\t\tleverageNative( this, type, expectSync );\n\n\t\t\t// Return false to allow normal processing in the caller\n\t\t\treturn false;\n\t\t},\n\t\ttrigger: function() {\n\n\t\t\t// Force setup before trigger\n\t\t\tleverageNative( this, type );\n\n\t\t\t// Return non-false to allow normal event-path propagation\n\t\t\treturn true;\n\t\t},\n\n\t\tdelegateType: delegateType\n\t};\n} );\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\n// so that event delegation works in jQuery.\n// Do the same for pointerenter/pointerleave and pointerover/pointerout\n//\n// Support: Safari 7 only\n// Safari sends mouseenter too often; see:\n// https://bugs.chromium.org/p/chromium/issues/detail?id=470258\n// for the description of the bug (it existed in older Chrome versions as well).\njQuery.each( {\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mouseenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n} );\n\njQuery.fn.extend( {\n\n\ton: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn );\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\n\t\t\t// ( event )  dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ?\n\t\t\t\t\thandleObj.origType + \".\" + handleObj.namespace :\n\t\t\t\t\thandleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t} );\n\t}\n} );\n\n\nvar\n\n\t/* eslint-disable max-len */\n\n\t// See https://github.com/eslint/eslint/issues/3229\n\trxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)[^>]*)\\/>/gi,\n\n\t/* eslint-enable */\n\n\t// Support: IE <=10 - 11, Edge 12 - 13 only\n\t// In IE/Edge using regex groups here causes severe slowdowns.\n\t// See https://connect.microsoft.com/IE/feedback/details/1736512/\n\trnoInnerhtml = /<script|<style|<link/i,\n\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g;\n\n// Prefer a tbody over its parent table for containing new rows\nfunction manipulationTarget( elem, content ) {\n\tif ( nodeName( elem, \"table\" ) &&\n\t\tnodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ) {\n\n\t\treturn jQuery( elem ).children( \"tbody\" )[ 0 ] || elem;\n\t}\n\n\treturn elem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = ( elem.getAttribute( \"type\" ) !== null ) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tif ( ( elem.type || \"\" ).slice( 0, 5 ) === \"true/\" ) {\n\t\telem.type = elem.type.slice( 5 );\n\t} else {\n\t\telem.removeAttribute( \"type\" );\n\t}\n\n\treturn elem;\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\tvar i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;\n\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\t// 1. Copy private data: events, handlers, etc.\n\tif ( dataPriv.hasData( src ) ) {\n\t\tpdataOld = dataPriv.access( src );\n\t\tpdataCur = dataPriv.set( dest, pdataOld );\n\t\tevents = pdataOld.events;\n\n\t\tif ( events ) {\n\t\t\tdelete pdataCur.handle;\n\t\t\tpdataCur.events = {};\n\n\t\t\tfor ( type in events ) {\n\t\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// 2. Copy user data\n\tif ( dataUser.hasData( src ) ) {\n\t\tudataOld = dataUser.access( src );\n\t\tudataCur = jQuery.extend( {}, udataOld );\n\n\t\tdataUser.set( dest, udataCur );\n\t}\n}\n\n// Fix IE bugs, see support tests\nfunction fixInput( src, dest ) {\n\tvar nodeName = dest.nodeName.toLowerCase();\n\n\t// Fails to persist the checked state of a cloned checkbox or radio button.\n\tif ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\tdest.checked = src.checked;\n\n\t// Fails to return the selected option to the default selected state when cloning options\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\nfunction domManip( collection, args, callback, ignored ) {\n\n\t// Flatten any nested arrays\n\targs = concat.apply( [], args );\n\n\tvar fragment, first, scripts, hasScripts, node, doc,\n\t\ti = 0,\n\t\tl = collection.length,\n\t\tiNoClone = l - 1,\n\t\tvalue = args[ 0 ],\n\t\tvalueIsFunction = isFunction( value );\n\n\t// We can't cloneNode fragments that contain checked, in WebKit\n\tif ( valueIsFunction ||\n\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\treturn collection.each( function( index ) {\n\t\t\tvar self = collection.eq( index );\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\targs[ 0 ] = value.call( this, index, self.html() );\n\t\t\t}\n\t\t\tdomManip( self, args, callback, ignored );\n\t\t} );\n\t}\n\n\tif ( l ) {\n\t\tfragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );\n\t\tfirst = fragment.firstChild;\n\n\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\tfragment = first;\n\t\t}\n\n\t\t// Require either new content or an interest in ignored elements to invoke the callback\n\t\tif ( first || ignored ) {\n\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\thasScripts = scripts.length;\n\n\t\t\t// Use the original fragment for the last item\n\t\t\t// instead of the first because it can end up\n\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tnode = fragment;\n\n\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\tif ( hasScripts ) {\n\n\t\t\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcallback.call( collection[ i ], node, i );\n\t\t\t}\n\n\t\t\tif ( hasScripts ) {\n\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t// Reenable scripts\n\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t!dataPriv.access( node, \"globalEval\" ) &&\n\t\t\t\t\t\tjQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\tif ( node.src && ( node.type || \"\" ).toLowerCase()  !== \"module\" ) {\n\n\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\tif ( jQuery._evalUrl && !node.noModule ) {\n\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src, {\n\t\t\t\t\t\t\t\t\tnonce: node.nonce || node.getAttribute( \"nonce\" )\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tDOMEval( node.textContent.replace( rcleanScript, \"\" ), node, doc );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn collection;\n}\n\nfunction remove( elem, selector, keepData ) {\n\tvar node,\n\t\tnodes = selector ? jQuery.filter( selector, elem ) : elem,\n\t\ti = 0;\n\n\tfor ( ; ( node = nodes[ i ] ) != null; i++ ) {\n\t\tif ( !keepData && node.nodeType === 1 ) {\n\t\t\tjQuery.cleanData( getAll( node ) );\n\t\t}\n\n\t\tif ( node.parentNode ) {\n\t\t\tif ( keepData && isAttached( node ) ) {\n\t\t\t\tsetGlobalEval( getAll( node, \"script\" ) );\n\t\t\t}\n\t\t\tnode.parentNode.removeChild( node );\n\t\t}\n\t}\n\n\treturn elem;\n}\n\njQuery.extend( {\n\thtmlPrefilter: function( html ) {\n\t\treturn html.replace( rxhtmlTag, \"<$1></$2>\" );\n\t},\n\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar i, l, srcElements, destElements,\n\t\t\tclone = elem.cloneNode( true ),\n\t\t\tinPage = isAttached( elem );\n\n\t\t// Fix IE cloning issues\n\t\tif ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&\n\t\t\t\t!jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\tfixInput( srcElements[ i ], destElements[ i ] );\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\t\tcloneCopyEvent( srcElements[ i ], destElements[ i ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tcleanData: function( elems ) {\n\t\tvar data, elem, type,\n\t\t\tspecial = jQuery.event.special,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {\n\t\t\tif ( acceptData( elem ) ) {\n\t\t\t\tif ( ( data = elem[ dataPriv.expando ] ) ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataPriv.expando ] = undefined;\n\t\t\t\t}\n\t\t\t\tif ( elem[ dataUser.expando ] ) {\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataUser.expando ] = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n} );\n\njQuery.fn.extend( {\n\tdetach: function( selector ) {\n\t\treturn remove( this, selector, true );\n\t},\n\n\tremove: function( selector ) {\n\t\treturn remove( this, selector );\n\t},\n\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().each( function() {\n\t\t\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\t\t\tthis.textContent = value;\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t} );\n\t},\n\n\tprepend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t} );\n\t},\n\n\tbefore: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t} );\n\t},\n\n\tafter: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t} );\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = this[ i ] ) != null; i++ ) {\n\t\t\tif ( elem.nodeType === 1 ) {\n\n\t\t\t\t// Prevent memory leaks\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\n\t\t\t\t// Remove any remaining nodes\n\t\t\t\telem.textContent = \"\";\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map( function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t} );\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined && elem.nodeType === 1 ) {\n\t\t\t\treturn elem.innerHTML;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t!wrapMap[ ( rtagName.exec( value ) || [ \"\", \"\" ] )[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = jQuery.htmlPrefilter( value );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\t\telem = this[ i ] || {};\n\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch ( e ) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar ignored = [];\n\n\t\t// Make the changes, replacing each non-ignored context element with the new content\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tvar parent = this.parentNode;\n\n\t\t\tif ( jQuery.inArray( this, ignored ) < 0 ) {\n\t\t\t\tjQuery.cleanData( getAll( this ) );\n\t\t\t\tif ( parent ) {\n\t\t\t\t\tparent.replaceChild( elem, this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Force callback invocation\n\t\t}, ignored );\n\t}\n} );\n\njQuery.each( {\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1,\n\t\t\ti = 0;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone( true );\n\t\t\tjQuery( insert[ i ] )[ original ]( elems );\n\n\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t// .get() because push.apply(_, arraylike) throws on ancient WebKit\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n} );\nvar rnumnonpx = new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n\nvar getStyles = function( elem ) {\n\n\t\t// Support: IE <=11 only, Firefox <=30 (#15098, #14150)\n\t\t// IE throws on elements created in popups\n\t\t// FF meanwhile throws on frame elements through \"defaultView.getComputedStyle\"\n\t\tvar view = elem.ownerDocument.defaultView;\n\n\t\tif ( !view || !view.opener ) {\n\t\t\tview = window;\n\t\t}\n\n\t\treturn view.getComputedStyle( elem );\n\t};\n\nvar rboxStyle = new RegExp( cssExpand.join( \"|\" ), \"i\" );\n\n\n\n( function() {\n\n\t// Executing both pixelPosition & boxSizingReliable tests require only one layout\n\t// so they're executed at the same time to save the second computation.\n\tfunction computeStyleTests() {\n\n\t\t// This is a singleton, we need to execute it only once\n\t\tif ( !div ) {\n\t\t\treturn;\n\t\t}\n\n\t\tcontainer.style.cssText = \"position:absolute;left:-11111px;width:60px;\" +\n\t\t\t\"margin-top:1px;padding:0;border:0\";\n\t\tdiv.style.cssText =\n\t\t\t\"position:relative;display:block;box-sizing:border-box;overflow:scroll;\" +\n\t\t\t\"margin:auto;border:1px;padding:1px;\" +\n\t\t\t\"width:60%;top:1%\";\n\t\tdocumentElement.appendChild( container ).appendChild( div );\n\n\t\tvar divStyle = window.getComputedStyle( div );\n\t\tpixelPositionVal = divStyle.top !== \"1%\";\n\n\t\t// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44\n\t\treliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;\n\n\t\t// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3\n\t\t// Some styles come back with percentage values, even though they shouldn't\n\t\tdiv.style.right = \"60%\";\n\t\tpixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;\n\n\t\t// Support: IE 9 - 11 only\n\t\t// Detect misreporting of content dimensions for box-sizing:border-box elements\n\t\tboxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;\n\n\t\t// Support: IE 9 only\n\t\t// Detect overflow:scroll screwiness (gh-3699)\n\t\t// Support: Chrome <=64\n\t\t// Don't get tricked when zoom affects offsetWidth (gh-4029)\n\t\tdiv.style.position = \"absolute\";\n\t\tscrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12;\n\n\t\tdocumentElement.removeChild( container );\n\n\t\t// Nullify the div so it wouldn't be stored in the memory and\n\t\t// it will also be a sign that checks already performed\n\t\tdiv = null;\n\t}\n\n\tfunction roundPixelMeasures( measure ) {\n\t\treturn Math.round( parseFloat( measure ) );\n\t}\n\n\tvar pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,\n\t\treliableMarginLeftVal,\n\t\tcontainer = document.createElement( \"div\" ),\n\t\tdiv = document.createElement( \"div\" );\n\n\t// Finish early in limited (non-browser) environments\n\tif ( !div.style ) {\n\t\treturn;\n\t}\n\n\t// Support: IE <=9 - 11 only\n\t// Style of cloned element affects source element cloned (#8908)\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\tjQuery.extend( support, {\n\t\tboxSizingReliable: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn boxSizingReliableVal;\n\t\t},\n\t\tpixelBoxStyles: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelBoxStylesVal;\n\t\t},\n\t\tpixelPosition: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelPositionVal;\n\t\t},\n\t\treliableMarginLeft: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn reliableMarginLeftVal;\n\t\t},\n\t\tscrollboxSize: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn scrollboxSizeVal;\n\t\t}\n\t} );\n} )();\n\n\nfunction curCSS( elem, name, computed ) {\n\tvar width, minWidth, maxWidth, ret,\n\n\t\t// Support: Firefox 51+\n\t\t// Retrieving style before computed somehow\n\t\t// fixes an issue with getting wrong values\n\t\t// on detached elements\n\t\tstyle = elem.style;\n\n\tcomputed = computed || getStyles( elem );\n\n\t// getPropertyValue is needed for:\n\t//   .css('filter') (IE 9 only, #12537)\n\t//   .css('--customProperty) (#3144)\n\tif ( computed ) {\n\t\tret = computed.getPropertyValue( name ) || computed[ name ];\n\n\t\tif ( ret === \"\" && !isAttached( elem ) ) {\n\t\t\tret = jQuery.style( elem, name );\n\t\t}\n\n\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t// Android Browser returns percentage for some values,\n\t\t// but width seems to be reliably pixels.\n\t\t// This is against the CSSOM draft spec:\n\t\t// https://drafts.csswg.org/cssom/#resolved-values\n\t\tif ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\twidth = style.width;\n\t\t\tminWidth = style.minWidth;\n\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\tret = computed.width;\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.width = width;\n\t\t\tstyle.minWidth = minWidth;\n\t\t\tstyle.maxWidth = maxWidth;\n\t\t}\n\t}\n\n\treturn ret !== undefined ?\n\n\t\t// Support: IE <=9 - 11 only\n\t\t// IE returns zIndex value as an integer.\n\t\tret + \"\" :\n\t\tret;\n}\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\n\t// Define the hook, we'll check on the first run if it's really needed.\n\treturn {\n\t\tget: function() {\n\t\t\tif ( conditionFn() ) {\n\n\t\t\t\t// Hook not needed (or it's not possible to use it due\n\t\t\t\t// to missing dependency), remove it.\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Hook needed; redefine it so that the support test is not executed again.\n\t\t\treturn ( this.get = hookFn ).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\nvar cssPrefixes = [ \"Webkit\", \"Moz\", \"ms\" ],\n\temptyStyle = document.createElement( \"div\" ).style,\n\tvendorProps = {};\n\n// Return a vendor-prefixed property or undefined\nfunction vendorPropName( name ) {\n\n\t// Check for vendor prefixed names\n\tvar capName = name[ 0 ].toUpperCase() + name.slice( 1 ),\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in emptyStyle ) {\n\t\t\treturn name;\n\t\t}\n\t}\n}\n\n// Return a potentially-mapped jQuery.cssProps or vendor prefixed property\nfunction finalPropName( name ) {\n\tvar final = jQuery.cssProps[ name ] || vendorProps[ name ];\n\n\tif ( final ) {\n\t\treturn final;\n\t}\n\tif ( name in emptyStyle ) {\n\t\treturn name;\n\t}\n\treturn vendorProps[ name ] = vendorPropName( name ) || name;\n}\n\n\nvar\n\n\t// Swappable if display is none or starts with table\n\t// except \"table\", \"table-cell\", or \"table-caption\"\n\t// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trcustomProp = /^--/,\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: \"0\",\n\t\tfontWeight: \"400\"\n\t};\n\nfunction setPositiveNumber( elem, value, subtract ) {\n\n\t// Any relative (+/-) values have already been\n\t// normalized at this point\n\tvar matches = rcssNum.exec( value );\n\treturn matches ?\n\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {\n\tvar i = dimension === \"width\" ? 1 : 0,\n\t\textra = 0,\n\t\tdelta = 0;\n\n\t// Adjustment may not be necessary\n\tif ( box === ( isBorderBox ? \"border\" : \"content\" ) ) {\n\t\treturn 0;\n\t}\n\n\tfor ( ; i < 4; i += 2 ) {\n\n\t\t// Both box models exclude margin\n\t\tif ( box === \"margin\" ) {\n\t\t\tdelta += jQuery.css( elem, box + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\t// If we get here with a content-box, we're seeking \"padding\" or \"border\" or \"margin\"\n\t\tif ( !isBorderBox ) {\n\n\t\t\t// Add padding\n\t\t\tdelta += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// For \"border\" or \"margin\", add border\n\t\t\tif ( box !== \"padding\" ) {\n\t\t\t\tdelta += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\n\t\t\t// But still keep track of it otherwise\n\t\t\t} else {\n\t\t\t\textra += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\n\t\t// If we get here with a border-box (content + padding + border), we're seeking \"content\" or\n\t\t// \"padding\" or \"margin\"\n\t\t} else {\n\n\t\t\t// For \"content\", subtract padding\n\t\t\tif ( box === \"content\" ) {\n\t\t\t\tdelta -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// For \"content\" or \"padding\", subtract border\n\t\t\tif ( box !== \"margin\" ) {\n\t\t\t\tdelta -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Account for positive content-box scroll gutter when requested by providing computedVal\n\tif ( !isBorderBox && computedVal >= 0 ) {\n\n\t\t// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border\n\t\t// Assuming integer scroll gutter, subtract the rest and round down\n\t\tdelta += Math.max( 0, Math.ceil(\n\t\t\telem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\tcomputedVal -\n\t\t\tdelta -\n\t\t\textra -\n\t\t\t0.5\n\n\t\t// If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter\n\t\t// Use an explicit zero to avoid NaN (gh-3964)\n\t\t) ) || 0;\n\t}\n\n\treturn delta;\n}\n\nfunction getWidthOrHeight( elem, dimension, extra ) {\n\n\t// Start with computed style\n\tvar styles = getStyles( elem ),\n\n\t\t// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).\n\t\t// Fake content-box until we know it's needed to know the true value.\n\t\tboxSizingNeeded = !support.boxSizingReliable() || extra,\n\t\tisBorderBox = boxSizingNeeded &&\n\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\tvalueIsBorderBox = isBorderBox,\n\n\t\tval = curCSS( elem, dimension, styles ),\n\t\toffsetProp = \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );\n\n\t// Support: Firefox <=54\n\t// Return a confounding non-pixel value or feign ignorance, as appropriate.\n\tif ( rnumnonpx.test( val ) ) {\n\t\tif ( !extra ) {\n\t\t\treturn val;\n\t\t}\n\t\tval = \"auto\";\n\t}\n\n\n\t// Fall back to offsetWidth/offsetHeight when value is \"auto\"\n\t// This happens for inline elements with no explicit setting (gh-3571)\n\t// Support: Android <=4.1 - 4.3 only\n\t// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)\n\t// Support: IE 9-11 only\n\t// Also use offsetWidth/offsetHeight for when box sizing is unreliable\n\t// We use getClientRects() to check for hidden/disconnected.\n\t// In those cases, the computed value can be trusted to be border-box\n\tif ( ( !support.boxSizingReliable() && isBorderBox ||\n\t\tval === \"auto\" ||\n\t\t!parseFloat( val ) && jQuery.css( elem, \"display\", false, styles ) === \"inline\" ) &&\n\t\telem.getClientRects().length ) {\n\n\t\tisBorderBox = jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\n\t\t// Where available, offsetWidth/offsetHeight approximate border box dimensions.\n\t\t// Where not available (e.g., SVG), assume unreliable box-sizing and interpret the\n\t\t// retrieved value as a content box dimension.\n\t\tvalueIsBorderBox = offsetProp in elem;\n\t\tif ( valueIsBorderBox ) {\n\t\t\tval = elem[ offsetProp ];\n\t\t}\n\t}\n\n\t// Normalize \"\" and auto\n\tval = parseFloat( val ) || 0;\n\n\t// Adjust for the element's box model\n\treturn ( val +\n\t\tboxModelAdjustment(\n\t\t\telem,\n\t\t\tdimension,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles,\n\n\t\t\t// Provide the current computed size to request scroll gutter calculation (gh-3589)\n\t\t\tval\n\t\t)\n\t) + \"px\";\n}\n\njQuery.extend( {\n\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"animationIterationCount\": true,\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"flexGrow\": true,\n\t\t\"flexShrink\": true,\n\t\t\"fontWeight\": true,\n\t\t\"gridArea\": true,\n\t\t\"gridColumn\": true,\n\t\t\"gridColumnEnd\": true,\n\t\t\"gridColumnStart\": true,\n\t\t\"gridRow\": true,\n\t\t\"gridRowEnd\": true,\n\t\t\"gridRowStart\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name ),\n\t\t\tstyle = elem.style;\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to query the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Gets hook for the prefixed version, then unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// Convert \"+=\" or \"-=\" to relative numbers (#7345)\n\t\t\tif ( type === \"string\" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {\n\t\t\t\tvalue = adjustCSS( elem, name, ret );\n\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that null and NaN values aren't set (#7116)\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add the unit (except for certain CSS properties)\n\t\t\t// The isCustomProp check can be removed in jQuery 4.0 when we only auto-append\n\t\t\t// \"px\" to a few hardcoded values.\n\t\t\tif ( type === \"number\" && !isCustomProp ) {\n\t\t\t\tvalue += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? \"\" : \"px\" );\n\t\t\t}\n\n\t\t\t// background-* props affect original clone's values\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf( \"background\" ) === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !( \"set\" in hooks ) ||\n\t\t\t\t( value = hooks.set( elem, value, extra ) ) !== undefined ) {\n\n\t\t\t\tif ( isCustomProp ) {\n\t\t\t\t\tstyle.setProperty( name, value );\n\t\t\t\t} else {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks &&\n\t\t\t\t( ret = hooks.get( elem, false, extra ) ) !== undefined ) {\n\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar val, num, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name );\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to modify the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Try prefixed name followed by the unprefixed name\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t// Convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Make numeric if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || isFinite( num ) ? num || 0 : val;\n\t\t}\n\n\t\treturn val;\n\t}\n} );\n\njQuery.each( [ \"height\", \"width\" ], function( i, dimension ) {\n\tjQuery.cssHooks[ dimension ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\n\t\t\t\t// Certain elements can have dimension info if we invisibly show them\n\t\t\t\t// but it must have a current display style that would benefit\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, \"display\" ) ) &&\n\n\t\t\t\t\t// Support: Safari 8+\n\t\t\t\t\t// Table columns in Safari have non-zero offsetWidth & zero\n\t\t\t\t\t// getBoundingClientRect().width unless display is changed.\n\t\t\t\t\t// Support: IE <=11 only\n\t\t\t\t\t// Running getBoundingClientRect on a disconnected node\n\t\t\t\t\t// in IE throws an error.\n\t\t\t\t\t( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?\n\t\t\t\t\t\tswap( elem, cssShow, function() {\n\t\t\t\t\t\t\treturn getWidthOrHeight( elem, dimension, extra );\n\t\t\t\t\t\t} ) :\n\t\t\t\t\t\tgetWidthOrHeight( elem, dimension, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar matches,\n\t\t\t\tstyles = getStyles( elem ),\n\n\t\t\t\t// Only read styles.position if the test has a chance to fail\n\t\t\t\t// to avoid forcing a reflow.\n\t\t\t\tscrollboxSizeBuggy = !support.scrollboxSize() &&\n\t\t\t\t\tstyles.position === \"absolute\",\n\n\t\t\t\t// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)\n\t\t\t\tboxSizingNeeded = scrollboxSizeBuggy || extra,\n\t\t\t\tisBorderBox = boxSizingNeeded &&\n\t\t\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\tsubtract = extra ?\n\t\t\t\t\tboxModelAdjustment(\n\t\t\t\t\t\telem,\n\t\t\t\t\t\tdimension,\n\t\t\t\t\t\textra,\n\t\t\t\t\t\tisBorderBox,\n\t\t\t\t\t\tstyles\n\t\t\t\t\t) :\n\t\t\t\t\t0;\n\n\t\t\t// Account for unreliable border-box dimensions by comparing offset* to computed and\n\t\t\t// faking a content-box to get border and padding (gh-3699)\n\t\t\tif ( isBorderBox && scrollboxSizeBuggy ) {\n\t\t\t\tsubtract -= Math.ceil(\n\t\t\t\t\telem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\t\t\tparseFloat( styles[ dimension ] ) -\n\t\t\t\t\tboxModelAdjustment( elem, dimension, \"border\", false, styles ) -\n\t\t\t\t\t0.5\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Convert to pixels if value adjustment is needed\n\t\t\tif ( subtract && ( matches = rcssNum.exec( value ) ) &&\n\t\t\t\t( matches[ 3 ] || \"px\" ) !== \"px\" ) {\n\n\t\t\t\telem.style[ dimension ] = value;\n\t\t\t\tvalue = jQuery.css( elem, dimension );\n\t\t\t}\n\n\t\t\treturn setPositiveNumber( elem, value, subtract );\n\t\t}\n\t};\n} );\n\njQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\treturn ( parseFloat( curCSS( elem, \"marginLeft\" ) ) ||\n\t\t\t\telem.getBoundingClientRect().left -\n\t\t\t\t\tswap( elem, { marginLeft: 0 }, function() {\n\t\t\t\t\t\treturn elem.getBoundingClientRect().left;\n\t\t\t\t\t} )\n\t\t\t\t) + \"px\";\n\t\t}\n\t}\n);\n\n// These hooks are used by animate to expand properties\njQuery.each( {\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// Assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split( \" \" ) : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( prefix !== \"margin\" ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n} );\n\njQuery.fn.extend( {\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( Array.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t}\n} );\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || jQuery.easing._default;\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\t// Use a property on the element directly when it is not a DOM element,\n\t\t\t// or when there is no matching style property that exists.\n\t\t\tif ( tween.elem.nodeType !== 1 ||\n\t\t\t\ttween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// Passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails.\n\t\t\t// Simple values such as \"10px\" are parsed to Float;\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as-is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\n\t\t\t// Use step hook for back compat.\n\t\t\t// Use cssHook if its there.\n\t\t\t// Use .style if available and use plain properties where available.\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.nodeType === 1 && (\n\t\t\t\t\tjQuery.cssHooks[ tween.prop ] ||\n\t\t\t\t\ttween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE <=9 only\n// Panic based approach to setting things on disconnected nodes\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t},\n\t_default: \"swing\"\n};\n\njQuery.fx = Tween.prototype.init;\n\n// Back compat <1.8 extension point\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, inProgress,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trrun = /queueHooks$/;\n\nfunction schedule() {\n\tif ( inProgress ) {\n\t\tif ( document.hidden === false && window.requestAnimationFrame ) {\n\t\t\twindow.requestAnimationFrame( schedule );\n\t\t} else {\n\t\t\twindow.setTimeout( schedule, jQuery.fx.interval );\n\t\t}\n\n\t\tjQuery.fx.tick();\n\t}\n}\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\twindow.setTimeout( function() {\n\t\tfxNow = undefined;\n\t} );\n\treturn ( fxNow = Date.now() );\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\ti = 0,\n\t\tattrs = { height: type };\n\n\t// If we include width, step value is 1 to do all cssExpand values,\n\t// otherwise step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {\n\n\t\t\t// We're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\tvar prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,\n\t\tisBox = \"width\" in props || \"height\" in props,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHiddenWithinTree( elem ),\n\t\tdataShow = dataPriv.get( elem, \"fxshow\" );\n\n\t// Queue-skipping animations hijack the fx hooks\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always( function() {\n\n\t\t\t// Ensure the complete handler is called before this completes\n\t\t\tanim.always( function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n\n\t// Detect show/hide animations\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.test( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\n\t\t\t\t// Pretend to be hidden if this is a \"show\" and\n\t\t\t\t// there is still data from a stopped show/hide\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\n\t\t\t\t// Ignore all other no-op show/hide data\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\t\t}\n\t}\n\n\t// Bail out if this is a no-op like .hide().hide()\n\tpropTween = !jQuery.isEmptyObject( props );\n\tif ( !propTween && jQuery.isEmptyObject( orig ) ) {\n\t\treturn;\n\t}\n\n\t// Restrict \"overflow\" and \"display\" styles during box animations\n\tif ( isBox && elem.nodeType === 1 ) {\n\n\t\t// Support: IE <=9 - 11, Edge 12 - 15\n\t\t// Record all 3 overflow attributes because IE does not infer the shorthand\n\t\t// from identically-valued overflowX and overflowY and Edge just mirrors\n\t\t// the overflowX value there.\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Identify a display type, preferring old show/hide data over the CSS cascade\n\t\trestoreDisplay = dataShow && dataShow.display;\n\t\tif ( restoreDisplay == null ) {\n\t\t\trestoreDisplay = dataPriv.get( elem, \"display\" );\n\t\t}\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\tif ( display === \"none\" ) {\n\t\t\tif ( restoreDisplay ) {\n\t\t\t\tdisplay = restoreDisplay;\n\t\t\t} else {\n\n\t\t\t\t// Get nonempty value(s) by temporarily forcing visibility\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t\trestoreDisplay = elem.style.display || restoreDisplay;\n\t\t\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\t\t\tshowHide( [ elem ] );\n\t\t\t}\n\t\t}\n\n\t\t// Animate inline elements as inline-block\n\t\tif ( display === \"inline\" || display === \"inline-block\" && restoreDisplay != null ) {\n\t\t\tif ( jQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\t\t// Restore the original display value at the end of pure show/hide animations\n\t\t\t\tif ( !propTween ) {\n\t\t\t\t\tanim.done( function() {\n\t\t\t\t\t\tstyle.display = restoreDisplay;\n\t\t\t\t\t} );\n\t\t\t\t\tif ( restoreDisplay == null ) {\n\t\t\t\t\t\tdisplay = style.display;\n\t\t\t\t\t\trestoreDisplay = display === \"none\" ? \"\" : display;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstyle.display = \"inline-block\";\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tanim.always( function() {\n\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t} );\n\t}\n\n\t// Implement show/hide animations\n\tpropTween = false;\n\tfor ( prop in orig ) {\n\n\t\t// General show/hide setup for this element animation\n\t\tif ( !propTween ) {\n\t\t\tif ( dataShow ) {\n\t\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\t\thidden = dataShow.hidden;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdataShow = dataPriv.access( elem, \"fxshow\", { display: restoreDisplay } );\n\t\t\t}\n\n\t\t\t// Store hidden/visible for toggle so `.stop().toggle()` \"reverses\"\n\t\t\tif ( toggle ) {\n\t\t\t\tdataShow.hidden = !hidden;\n\t\t\t}\n\n\t\t\t// Show elements before animating them\n\t\t\tif ( hidden ) {\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t}\n\n\t\t\t/* eslint-disable no-loop-func */\n\n\t\t\tanim.done( function() {\n\n\t\t\t/* eslint-enable no-loop-func */\n\n\t\t\t\t// The final step of a \"hide\" animation is actually hiding the element\n\t\t\t\tif ( !hidden ) {\n\t\t\t\t\tshowHide( [ elem ] );\n\t\t\t\t}\n\t\t\t\tdataPriv.remove( elem, \"fxshow\" );\n\t\t\t\tfor ( prop in orig ) {\n\t\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Per-property setup\n\t\tpropTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\t\tif ( !( prop in dataShow ) ) {\n\t\t\tdataShow[ prop ] = propTween.start;\n\t\t\tif ( hidden ) {\n\t\t\t\tpropTween.end = propTween.start;\n\t\t\t\tpropTween.start = 0;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( Array.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// Not quite $.extend, this won't overwrite existing keys.\n\t\t\t// Reusing 'index' because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = Animation.prefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\n\t\t\t// Don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t} ),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\n\t\t\t\t// Support: Android 2.3 only\n\t\t\t\t// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ] );\n\n\t\t\t// If there's more to do, yield\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t}\n\n\t\t\t// If this was an empty animation, synthesize a final progress notification\n\t\t\tif ( !length ) {\n\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t}\n\n\t\t\t// Resolve the animation and report its conclusion\n\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\treturn false;\n\t\t},\n\t\tanimation = deferred.promise( {\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, {\n\t\t\t\tspecialEasing: {},\n\t\t\t\teasing: jQuery.easing._default\n\t\t\t}, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\n\t\t\t\t\t// If we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// Resolve when we played the last frame; otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t} ),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length; index++ ) {\n\t\tresult = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\tif ( isFunction( result.stop ) ) {\n\t\t\t\tjQuery._queueHooks( animation.elem, animation.opts.queue ).stop =\n\t\t\t\t\tresult.stop.bind( result );\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\t// Attach callbacks from options\n\tanimation\n\t\t.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t} )\n\t);\n\n\treturn animation;\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n\ttweeners: {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value );\n\t\t\tadjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );\n\t\t\treturn tween;\n\t\t} ]\n\t},\n\n\ttweener: function( props, callback ) {\n\t\tif ( isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.match( rnothtmlwhite );\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\tAnimation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];\n\t\t\tAnimation.tweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilters: [ defaultPrefilter ],\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tAnimation.prefilters.unshift( callback );\n\t\t} else {\n\t\t\tAnimation.prefilters.push( callback );\n\t\t}\n\t}\n} );\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tisFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !isFunction( easing ) && easing\n\t};\n\n\t// Go to the end state if fx are off\n\tif ( jQuery.fx.off ) {\n\t\topt.duration = 0;\n\n\t} else {\n\t\tif ( typeof opt.duration !== \"number\" ) {\n\t\t\tif ( opt.duration in jQuery.fx.speeds ) {\n\t\t\t\topt.duration = jQuery.fx.speeds[ opt.duration ];\n\n\t\t\t} else {\n\t\t\t\topt.duration = jQuery.fx.speeds._default;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend( {\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// Show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHiddenWithinTree ).css( \"opacity\", 0 ).show()\n\n\t\t\t// Animate to the value specified\n\t\t\t.end().animate( { opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || dataPriv.get( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\t\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue && type !== false ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = dataPriv.get( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this &&\n\t\t\t\t\t( type == null || timers[ index ].queue === type ) ) {\n\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Start the next in the queue if the last step wasn't forced.\n\t\t\t// Timers currently will call their complete callbacks, which\n\t\t\t// will dequeue but only if they were gotoEnd.\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t} );\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tvar index,\n\t\t\t\tdata = dataPriv.get( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// Enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// Empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// Look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t} );\n\t}\n} );\n\njQuery.each( [ \"toggle\", \"show\", \"hide\" ], function( i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n} );\n\n// Generate shortcuts for custom animations\njQuery.each( {\n\tslideDown: genFx( \"show\" ),\n\tslideUp: genFx( \"hide\" ),\n\tslideToggle: genFx( \"toggle\" ),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n} );\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ti = 0,\n\t\ttimers = jQuery.timers;\n\n\tfxNow = Date.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\n\t\t// Run the timer and safely remove it when done (allowing for external removal)\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tjQuery.fx.start();\n};\n\njQuery.fx.interval = 13;\njQuery.fx.start = function() {\n\tif ( inProgress ) {\n\t\treturn;\n\t}\n\n\tinProgress = true;\n\tschedule();\n};\n\njQuery.fx.stop = function() {\n\tinProgress = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\n\t// Default speed\n\t_default: 400\n};\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = window.setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\twindow.clearTimeout( timeout );\n\t\t};\n\t} );\n};\n\n\n( function() {\n\tvar input = document.createElement( \"input\" ),\n\t\tselect = document.createElement( \"select\" ),\n\t\topt = select.appendChild( document.createElement( \"option\" ) );\n\n\tinput.type = \"checkbox\";\n\n\t// Support: Android <=4.3 only\n\t// Default value for a checkbox should be \"on\"\n\tsupport.checkOn = input.value !== \"\";\n\n\t// Support: IE <=11 only\n\t// Must access selectedIndex to make default options select\n\tsupport.optSelected = opt.selected;\n\n\t// Support: IE <=11 only\n\t// An input loses its value after becoming a radio\n\tinput = document.createElement( \"input\" );\n\tinput.value = \"t\";\n\tinput.type = \"radio\";\n\tsupport.radioValue = input.value === \"t\";\n} )();\n\n\nvar boolHook,\n\tattrHandle = jQuery.expr.attrHandle;\n\njQuery.fn.extend( {\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tattr: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set attributes on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === \"undefined\" ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// Attribute hooks are determined by the lowercase version\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\thooks = jQuery.attrHooks[ name.toLowerCase() ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\treturn value;\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\tret = jQuery.find.attr( elem, name );\n\n\t\t// Non-existent attributes return null, we normalize to undefined\n\t\treturn ret == null ? undefined : ret;\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" &&\n\t\t\t\t\tnodeName( elem, \"input\" ) ) {\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name,\n\t\t\ti = 0,\n\n\t\t\t// Attribute names can contain non-HTML whitespace characters\n\t\t\t// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2\n\t\t\tattrNames = value && value.match( rnothtmlwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( ( name = attrNames[ i++ ] ) ) {\n\t\t\t\telem.removeAttribute( name );\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Hooks for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else {\n\t\t\telem.setAttribute( name, name );\n\t\t}\n\t\treturn name;\n\t}\n};\n\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( i, name ) {\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = function( elem, name, isXML ) {\n\t\tvar ret, handle,\n\t\t\tlowercaseName = name.toLowerCase();\n\n\t\tif ( !isXML ) {\n\n\t\t\t// Avoid an infinite loop by temporarily removing this function from the getter\n\t\t\thandle = attrHandle[ lowercaseName ];\n\t\t\tattrHandle[ lowercaseName ] = ret;\n\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\tlowercaseName :\n\t\t\t\tnull;\n\t\t\tattrHandle[ lowercaseName ] = handle;\n\t\t}\n\t\treturn ret;\n\t};\n} );\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button)$/i,\n\trclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend( {\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tdelete this[ jQuery.propFix[ name ] || name ];\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set properties on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\treturn ( elem[ name ] = value );\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\treturn elem[ name ];\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\t// Support: IE <=9 - 11 only\n\t\t\t\t// elem.tabIndex doesn't always return the\n\t\t\t\t// correct value when it hasn't been explicitly set\n\t\t\t\t// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\t// Use proper attribute retrieval(#12072)\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n\t\t\t\tif ( tabindex ) {\n\t\t\t\t\treturn parseInt( tabindex, 10 );\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\trfocusable.test( elem.nodeName ) ||\n\t\t\t\t\trclickable.test( elem.nodeName ) &&\n\t\t\t\t\telem.href\n\t\t\t\t) {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t},\n\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t}\n} );\n\n// Support: IE <=11 only\n// Accessing the selectedIndex property\n// forces the browser to respect setting selected\n// on the option\n// The getter ensures a default option is selected\n// when in an optgroup\n// eslint rule \"no-unused-expressions\" is disabled for this code\n// since it considers such accessions noop\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent && parent.parentNode ) {\n\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t\tset: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\njQuery.each( [\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n} );\n\n\n\n\n\t// Strip and collapse whitespace according to HTML spec\n\t// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace\n\tfunction stripAndCollapse( value ) {\n\t\tvar tokens = value.match( rnothtmlwhite ) || [];\n\t\treturn tokens.join( \" \" );\n\t}\n\n\nfunction getClass( elem ) {\n\treturn elem.getAttribute && elem.getAttribute( \"class\" ) || \"\";\n}\n\nfunction classesToArray( value ) {\n\tif ( Array.isArray( value ) ) {\n\t\treturn value;\n\t}\n\tif ( typeof value === \"string\" ) {\n\t\treturn value.match( rnothtmlwhite ) || [];\n\t}\n\treturn [];\n}\n\njQuery.fn.extend( {\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tclasses = classesToArray( value );\n\n\t\tif ( classes.length ) {\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tif ( !arguments.length ) {\n\t\t\treturn this.attr( \"class\", \"\" );\n\t\t}\n\n\t\tclasses = classesToArray( value );\n\n\t\tif ( classes.length ) {\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) > -1 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value,\n\t\t\tisValidValue = type === \"string\" || Array.isArray( value );\n\n\t\tif ( typeof stateVal === \"boolean\" && isValidValue ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).toggleClass(\n\t\t\t\t\tvalue.call( this, i, getClass( this ), stateVal ),\n\t\t\t\t\tstateVal\n\t\t\t\t);\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar className, i, self, classNames;\n\n\t\t\tif ( isValidValue ) {\n\n\t\t\t\t// Toggle individual class names\n\t\t\t\ti = 0;\n\t\t\t\tself = jQuery( this );\n\t\t\t\tclassNames = classesToArray( value );\n\n\t\t\t\twhile ( ( className = classNames[ i++ ] ) ) {\n\n\t\t\t\t\t// Check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( value === undefined || type === \"boolean\" ) {\n\t\t\t\tclassName = getClass( this );\n\t\t\t\tif ( className ) {\n\n\t\t\t\t\t// Store className if set\n\t\t\t\t\tdataPriv.set( this, \"__className__\", className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed `false`,\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tif ( this.setAttribute ) {\n\t\t\t\t\tthis.setAttribute( \"class\",\n\t\t\t\t\t\tclassName || value === false ?\n\t\t\t\t\t\t\"\" :\n\t\t\t\t\t\tdataPriv.get( this, \"__className__\" ) || \"\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className, elem,\n\t\t\ti = 0;\n\n\t\tclassName = \" \" + selector + \" \";\n\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\tif ( elem.nodeType === 1 &&\n\t\t\t\t( \" \" + stripAndCollapse( getClass( elem ) ) + \" \" ).indexOf( className ) > -1 ) {\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n} );\n\n\n\n\nvar rreturn = /\\r/g;\n\njQuery.fn.extend( {\n\tval: function( value ) {\n\t\tvar hooks, ret, valueIsFunction,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] ||\n\t\t\t\t\tjQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks &&\n\t\t\t\t\t\"get\" in hooks &&\n\t\t\t\t\t( ret = hooks.get( elem, \"value\" ) ) !== undefined\n\t\t\t\t) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\t// Handle most common string cases\n\t\t\t\tif ( typeof ret === \"string\" ) {\n\t\t\t\t\treturn ret.replace( rreturn, \"\" );\n\t\t\t\t}\n\n\t\t\t\t// Handle cases where value is null/undef or number\n\t\t\t\treturn ret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tvalueIsFunction = isFunction( value );\n\n\t\treturn this.each( function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\n\t\t\t} else if ( Array.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !( \"set\" in hooks ) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\tvar val = jQuery.find.attr( elem, \"value\" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\n\t\t\t\t\t// Support: IE <=10 - 11 only\n\t\t\t\t\t// option.text throws exceptions (#14686, #14858)\n\t\t\t\t\t// Strip and collapse whitespace\n\t\t\t\t\t// https://html.spec.whatwg.org/#strip-and-collapse-whitespace\n\t\t\t\t\tstripAndCollapse( jQuery.text( elem ) );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option, i,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\",\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length;\n\n\t\t\t\tif ( index < 0 ) {\n\t\t\t\t\ti = max;\n\n\t\t\t\t} else {\n\t\t\t\t\ti = one ? index : 0;\n\t\t\t\t}\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t// IE8-9 doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t!option.disabled &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled ||\n\t\t\t\t\t\t\t\t!nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t/* eslint-disable no-cond-assign */\n\n\t\t\t\t\tif ( option.selected =\n\t\t\t\t\t\tjQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1\n\t\t\t\t\t) {\n\t\t\t\t\t\toptionSet = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t/* eslint-enable no-cond-assign */\n\t\t\t\t}\n\n\t\t\t\t// Force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\t\t\t\treturn values;\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Radios and checkboxes getter/setter\njQuery.each( [ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( Array.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\treturn elem.getAttribute( \"value\" ) === null ? \"on\" : elem.value;\n\t\t};\n\t}\n} );\n\n\n\n\n// Return jQuery for attributes-only inclusion\n\n\nsupport.focusin = \"onfocusin\" in window;\n\n\nvar rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\tstopPropagationCallback = function( e ) {\n\t\te.stopPropagation();\n\t};\n\njQuery.extend( jQuery.event, {\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\n\t\tvar i, cur, tmp, bubbleType, ontype, handle, special, lastElement,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split( \".\" ) : [];\n\n\t\tcur = lastElement = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf( \".\" ) > -1 ) {\n\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split( \".\" );\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf( \":\" ) < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join( \".\" );\n\t\tevent.rnamespace = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === ( elem.ownerDocument || document ) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tlastElement = cur;\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( dataPriv.get( cur, \"events\" ) || {} )[ event.type ] &&\n\t\t\t\tdataPriv.get( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( ( !special._default ||\n\t\t\t\tspecial._default.apply( eventPath.pop(), data ) === false ) &&\n\t\t\t\tacceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name as the event.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.addEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\telem[ type ]();\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.removeEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\t// Piggyback on a donor event to simulate a different one\n\t// Used only for `focus(in | out)` events\n\tsimulate: function( type, elem, event ) {\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true\n\t\t\t}\n\t\t);\n\n\t\tjQuery.event.trigger( e, null, elem );\n\t}\n\n} );\n\njQuery.fn.extend( {\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t} );\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[ 0 ];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n} );\n\n\n// Support: Firefox <=44\n// Firefox doesn't have focus(in | out) events\n// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787\n//\n// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1\n// focus(in | out) events fire after focus & blur events,\n// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order\n// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857\nif ( !support.focusin ) {\n\tjQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );\n\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tdataPriv.access( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tdataPriv.remove( doc, fix );\n\n\t\t\t\t} else {\n\t\t\t\t\tdataPriv.access( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t} );\n}\nvar location = window.location;\n\nvar nonce = Date.now();\n\nvar rquery = ( /\\?/ );\n\n\n\n// Cross-browser xml parsing\njQuery.parseXML = function( data ) {\n\tvar xml;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\n\t// Support: IE 9 - 11 only\n\t// IE throws on parseFromString with invalid input.\n\ttry {\n\t\txml = ( new window.DOMParser() ).parseFromString( data, \"text/xml\" );\n\t} catch ( e ) {\n\t\txml = undefined;\n\t}\n\n\tif ( !xml || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\tjQuery.error( \"Invalid XML: \" + data );\n\t}\n\treturn xml;\n};\n\n\nvar\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( Array.isArray( obj ) ) {\n\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams(\n\t\t\t\t\tprefix + \"[\" + ( typeof v === \"object\" && v != null ? i : \"\" ) + \"]\",\n\t\t\t\t\tv,\n\t\t\t\t\ttraditional,\n\t\t\t\t\tadd\n\t\t\t\t);\n\t\t\t}\n\t\t} );\n\n\t} else if ( !traditional && toType( obj ) === \"object\" ) {\n\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, valueOrFunction ) {\n\n\t\t\t// If value is a function, invoke it and use its return value\n\t\t\tvar value = isFunction( valueOrFunction ) ?\n\t\t\t\tvalueOrFunction() :\n\t\t\t\tvalueOrFunction;\n\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" +\n\t\t\t\tencodeURIComponent( value == null ? \"\" : value );\n\t\t};\n\n\tif ( a == null ) {\n\t\treturn \"\";\n\t}\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t} );\n\n\t} else {\n\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" );\n};\n\njQuery.fn.extend( {\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map( function() {\n\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t} )\n\t\t.filter( function() {\n\t\t\tvar type = this.type;\n\n\t\t\t// Use .is( \":disabled\" ) so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t} )\n\t\t.map( function( i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\tif ( val == null ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif ( Array.isArray( val ) ) {\n\t\t\t\treturn jQuery.map( val, function( val ) {\n\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t} ).get();\n\t}\n} );\n\n\nvar\n\tr20 = /%20/g,\n\trhash = /#.*$/,\n\trantiCache = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)$/mg,\n\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat( \"*\" ),\n\n\t// Anchor tag for parsing the document origin\n\toriginAnchor = document.createElement( \"a\" );\n\toriginAnchor.href = location.href;\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];\n\n\t\tif ( isFunction( func ) ) {\n\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( ( dataType = dataTypes[ i++ ] ) ) {\n\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType[ 0 ] === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" &&\n\t\t\t\t!seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t} );\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar key, deep,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n\tvar ct, type, finalDataType, firstDataType,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader( \"Content-Type\" );\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[ 0 ] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s.throws ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tstate: \"parsererror\",\n\t\t\t\t\t\t\t\terror: conv ? e : \"No conversion from \" + prev + \" to \" + current\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend( {\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: location.href,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( location.protocol ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /\\bxml\\b/,\n\t\t\thtml: /\\bhtml/,\n\t\t\tjson: /\\bjson\\b/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": JSON.parse,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar transport,\n\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\n\t\t\t// Response headers\n\t\t\tresponseHeadersString,\n\t\t\tresponseHeaders,\n\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\n\t\t\t// Url cleanup var\n\t\t\turlAnchor,\n\n\t\t\t// Request state (becomes false upon send and true upon completion)\n\t\t\tcompleted,\n\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\n\t\t\t// Loop variable\n\t\t\ti,\n\n\t\t\t// uncached part of the url\n\t\t\tuncached,\n\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context &&\n\t\t\t\t( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\t\tjQuery.event,\n\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks( \"once memory\" ),\n\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( completed ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( ( match = rheaders.exec( responseHeadersString ) ) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[ 1 ].toLowerCase() + \" \" ] =\n\t\t\t\t\t\t\t\t\t( responseHeaders[ match[ 1 ].toLowerCase() + \" \" ] || [] )\n\t\t\t\t\t\t\t\t\t\t.concat( match[ 2 ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() + \" \" ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match.join( \", \" );\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn completed ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\tname = requestHeadersNames[ name.toLowerCase() ] =\n\t\t\t\t\t\t\trequestHeadersNames[ name.toLowerCase() ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( completed ) {\n\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Lazy-add the new callbacks in a way that preserves old ones\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR );\n\n\t\t// Add protocol if not provided (prefilters might expect it)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || location.href ) + \"\" )\n\t\t\t.replace( rprotocol, location.protocol + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = ( s.dataType || \"*\" ).toLowerCase().match( rnothtmlwhite ) || [ \"\" ];\n\n\t\t// A cross-domain request is in order when the origin doesn't match the current origin.\n\t\tif ( s.crossDomain == null ) {\n\t\t\turlAnchor = document.createElement( \"a\" );\n\n\t\t\t// Support: IE <=8 - 11, Edge 12 - 15\n\t\t\t// IE throws exception on accessing the href property if url is malformed,\n\t\t\t// e.g. http://example.com:80x/\n\t\t\ttry {\n\t\t\t\turlAnchor.href = s.url;\n\n\t\t\t\t// Support: IE <=8 - 11 only\n\t\t\t\t// Anchor's host property isn't correctly set when s.url is relative\n\t\t\t\turlAnchor.href = urlAnchor.href;\n\t\t\t\ts.crossDomain = originAnchor.protocol + \"//\" + originAnchor.host !==\n\t\t\t\t\turlAnchor.protocol + \"//\" + urlAnchor.host;\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// If there is an error parsing the URL, assume it is crossDomain,\n\t\t\t\t// it can be rejected by the transport if it is invalid\n\t\t\t\ts.crossDomain = true;\n\t\t\t}\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( completed ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\t// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)\n\t\tfireGlobals = jQuery.event && s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger( \"ajaxStart\" );\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\t// Remove hash to simplify url manipulation\n\t\tcacheURL = s.url.replace( rhash, \"\" );\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// Remember the hash so we can put it back\n\t\t\tuncached = s.url.slice( cacheURL.length );\n\n\t\t\t// If data is available and should be processed, append data to url\n\t\t\tif ( s.data && ( s.processData || typeof s.data === \"string\" ) ) {\n\t\t\t\tcacheURL += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data;\n\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add or update anti-cache param if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\tcacheURL = cacheURL.replace( rantiCache, \"$1\" );\n\t\t\t\tuncached = ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + ( nonce++ ) + uncached;\n\t\t\t}\n\n\t\t\t// Put hash and anti-cache on the URL that will be requested (gh-1732)\n\t\t\ts.url = cacheURL + uncached;\n\n\t\t// Change '%20' to '+' if this is encoded form body content (gh-2658)\n\t\t} else if ( s.data && s.processData &&\n\t\t\t( s.contentType || \"\" ).indexOf( \"application/x-www-form-urlencoded\" ) === 0 ) {\n\t\t\ts.data = s.data.replace( r20, \"+\" );\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[ 0 ] ] +\n\t\t\t\t\t( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend &&\n\t\t\t( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {\n\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// Aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tcompleteDeferred.add( s.complete );\n\t\tjqXHR.done( s.success );\n\t\tjqXHR.fail( s.error );\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\n\t\t\t// If request was aborted inside ajaxSend, stop there\n\t\t\tif ( completed ) {\n\t\t\t\treturn jqXHR;\n\t\t\t}\n\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = window.setTimeout( function() {\n\t\t\t\t\tjqXHR.abort( \"timeout\" );\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tcompleted = false;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// Rethrow post-completion exceptions\n\t\t\t\tif ( completed ) {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\n\t\t\t\t// Propagate others as results\n\t\t\t\tdone( -1, e );\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Ignore repeat invocations\n\t\t\tif ( completed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcompleted = true;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\twindow.clearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"Last-Modified\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"etag\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\n\t\t\t\t// Extract error from statusText and normalize for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger( \"ajaxStop\" );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n} );\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\n\t\t// Shift arguments if data argument was omitted\n\t\tif ( isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\t// The url can be an options object (which then must have .url)\n\t\treturn jQuery.ajax( jQuery.extend( {\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t}, jQuery.isPlainObject( url ) && url ) );\n\t};\n} );\n\n\njQuery._evalUrl = function( url, options ) {\n\treturn jQuery.ajax( {\n\t\turl: url,\n\n\t\t// Make this explicit, since user can override this through ajaxSetup (#11264)\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tcache: true,\n\t\tasync: false,\n\t\tglobal: false,\n\n\t\t// Only evaluate the response if it is successful (gh-4126)\n\t\t// dataFilter is not invoked for failure responses, so using it instead\n\t\t// of the default converter is kludgy but it works.\n\t\tconverters: {\n\t\t\t\"text script\": function() {}\n\t\t},\n\t\tdataFilter: function( response ) {\n\t\t\tjQuery.globalEval( response, options );\n\t\t}\n\t} );\n};\n\n\njQuery.fn.extend( {\n\twrapAll: function( html ) {\n\t\tvar wrap;\n\n\t\tif ( this[ 0 ] ) {\n\t\t\tif ( isFunction( html ) ) {\n\t\t\t\thtml = html.call( this[ 0 ] );\n\t\t\t}\n\n\t\t\t// The elements to wrap the target around\n\t\t\twrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );\n\n\t\t\tif ( this[ 0 ].parentNode ) {\n\t\t\t\twrap.insertBefore( this[ 0 ] );\n\t\t\t}\n\n\t\t\twrap.map( function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstElementChild ) {\n\t\t\t\t\telem = elem.firstElementChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t} ).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( isFunction( html ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).wrapInner( html.call( this, i ) );\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t} );\n\t},\n\n\twrap: function( html ) {\n\t\tvar htmlIsFunction = isFunction( html );\n\n\t\treturn this.each( function( i ) {\n\t\t\tjQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );\n\t\t} );\n\t},\n\n\tunwrap: function( selector ) {\n\t\tthis.parent( selector ).not( \"body\" ).each( function() {\n\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t} );\n\t\treturn this;\n\t}\n} );\n\n\njQuery.expr.pseudos.hidden = function( elem ) {\n\treturn !jQuery.expr.pseudos.visible( elem );\n};\njQuery.expr.pseudos.visible = function( elem ) {\n\treturn !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );\n};\n\n\n\n\njQuery.ajaxSettings.xhr = function() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch ( e ) {}\n};\n\nvar xhrSuccessStatus = {\n\n\t\t// File protocol always yields status code 0, assume 200\n\t\t0: 200,\n\n\t\t// Support: IE <=9 only\n\t\t// #1450: sometimes IE returns 1223 when it should be 204\n\t\t1223: 204\n\t},\n\txhrSupported = jQuery.ajaxSettings.xhr();\n\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nsupport.ajax = xhrSupported = !!xhrSupported;\n\njQuery.ajaxTransport( function( options ) {\n\tvar callback, errorCallback;\n\n\t// Cross domain only allowed if supported through XMLHttpRequest\n\tif ( support.cors || xhrSupported && !options.crossDomain ) {\n\t\treturn {\n\t\t\tsend: function( headers, complete ) {\n\t\t\t\tvar i,\n\t\t\t\t\txhr = options.xhr();\n\n\t\t\t\txhr.open(\n\t\t\t\t\toptions.type,\n\t\t\t\t\toptions.url,\n\t\t\t\t\toptions.async,\n\t\t\t\t\toptions.username,\n\t\t\t\t\toptions.password\n\t\t\t\t);\n\n\t\t\t\t// Apply custom fields if provided\n\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Override mime type if needed\n\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t}\n\n\t\t\t\t// X-Requested-With header\n\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\tif ( !options.crossDomain && !headers[ \"X-Requested-With\" ] ) {\n\t\t\t\t\theaders[ \"X-Requested-With\" ] = \"XMLHttpRequest\";\n\t\t\t\t}\n\n\t\t\t\t// Set headers\n\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t}\n\n\t\t\t\t// Callback\n\t\t\t\tcallback = function( type ) {\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\tcallback = errorCallback = xhr.onload =\n\t\t\t\t\t\t\t\txhr.onerror = xhr.onabort = xhr.ontimeout =\n\t\t\t\t\t\t\t\t\txhr.onreadystatechange = null;\n\n\t\t\t\t\t\t\tif ( type === \"abort\" ) {\n\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t} else if ( type === \"error\" ) {\n\n\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t// On a manual native abort, IE9 throws\n\t\t\t\t\t\t\t\t// errors on any property access that is not readyState\n\t\t\t\t\t\t\t\tif ( typeof xhr.status !== \"number\" ) {\n\t\t\t\t\t\t\t\t\tcomplete( 0, \"error\" );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcomplete(\n\n\t\t\t\t\t\t\t\t\t\t// File: protocol always yields status 0; see #8605, #14207\n\t\t\t\t\t\t\t\t\t\txhr.status,\n\t\t\t\t\t\t\t\t\t\txhr.statusText\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcomplete(\n\t\t\t\t\t\t\t\t\txhrSuccessStatus[ xhr.status ] || xhr.status,\n\t\t\t\t\t\t\t\t\txhr.statusText,\n\n\t\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t\t// IE9 has no XHR2 but throws on binary (trac-11426)\n\t\t\t\t\t\t\t\t\t// For XHR2 non-text, let the caller handle it (gh-2498)\n\t\t\t\t\t\t\t\t\t( xhr.responseType || \"text\" ) !== \"text\"  ||\n\t\t\t\t\t\t\t\t\ttypeof xhr.responseText !== \"string\" ?\n\t\t\t\t\t\t\t\t\t\t{ binary: xhr.response } :\n\t\t\t\t\t\t\t\t\t\t{ text: xhr.responseText },\n\t\t\t\t\t\t\t\t\txhr.getAllResponseHeaders()\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t};\n\n\t\t\t\t// Listen to events\n\t\t\t\txhr.onload = callback();\n\t\t\t\terrorCallback = xhr.onerror = xhr.ontimeout = callback( \"error\" );\n\n\t\t\t\t// Support: IE 9 only\n\t\t\t\t// Use onreadystatechange to replace onabort\n\t\t\t\t// to handle uncaught aborts\n\t\t\t\tif ( xhr.onabort !== undefined ) {\n\t\t\t\t\txhr.onabort = errorCallback;\n\t\t\t\t} else {\n\t\t\t\t\txhr.onreadystatechange = function() {\n\n\t\t\t\t\t\t// Check readyState before timeout as it changes\n\t\t\t\t\t\tif ( xhr.readyState === 4 ) {\n\n\t\t\t\t\t\t\t// Allow onerror to be called first,\n\t\t\t\t\t\t\t// but that will not handle a native abort\n\t\t\t\t\t\t\t// Also, save errorCallback to a variable\n\t\t\t\t\t\t\t// as xhr.onerror cannot be accessed\n\t\t\t\t\t\t\twindow.setTimeout( function() {\n\t\t\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\t\t\terrorCallback();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Create the abort callback\n\t\t\t\tcallback = callback( \"abort\" );\n\n\t\t\t\ttry {\n\n\t\t\t\t\t// Do send the request (this may raise an exception)\n\t\t\t\t\txhr.send( options.hasContent && options.data || null );\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t// #14683: Only rethrow if this hasn't been notified as an error yet\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tthrow e;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\n// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)\njQuery.ajaxPrefilter( function( s ) {\n\tif ( s.crossDomain ) {\n\t\ts.contents.script = false;\n\t}\n} );\n\n// Install script dataType\njQuery.ajaxSetup( {\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, \" +\n\t\t\t\"application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /\\b(?:java|ecma)script\\b/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n} );\n\n// Handle cache's special case and crossDomain\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t}\n} );\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function( s ) {\n\n\t// This transport only deals with cross domain or forced-by-attrs requests\n\tif ( s.crossDomain || s.scriptAttrs ) {\n\t\tvar script, callback;\n\t\treturn {\n\t\t\tsend: function( _, complete ) {\n\t\t\t\tscript = jQuery( \"<script>\" )\n\t\t\t\t\t.attr( s.scriptAttrs || {} )\n\t\t\t\t\t.prop( { charset: s.scriptCharset, src: s.url } )\n\t\t\t\t\t.on( \"load error\", callback = function( evt ) {\n\t\t\t\t\t\tscript.remove();\n\t\t\t\t\t\tcallback = null;\n\t\t\t\t\t\tif ( evt ) {\n\t\t\t\t\t\t\tcomplete( evt.type === \"error\" ? 404 : 200, evt.type );\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\n\t\t\t\t// Use native DOM manipulation to avoid our domManip AJAX trickery\n\t\t\t\tdocument.head.appendChild( script[ 0 ] );\n\t\t\t},\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup( {\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n} );\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" &&\n\t\t\t\t( s.contentType || \"\" )\n\t\t\t\t\t.indexOf( \"application/x-www-form-urlencoded\" ) === 0 &&\n\t\t\t\trjsonp.test( s.data ) && \"data\"\n\t\t);\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\n\t\t// Insert callback into url or form data\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[ \"script json\" ] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// Force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always( function() {\n\n\t\t\t// If previous value didn't exist - remove it\n\t\t\tif ( overwritten === undefined ) {\n\t\t\t\tjQuery( window ).removeProp( callbackName );\n\n\t\t\t// Otherwise restore preexisting value\n\t\t\t} else {\n\t\t\t\twindow[ callbackName ] = overwritten;\n\t\t\t}\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\n\t\t\t\t// Make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// Save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t} );\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n} );\n\n\n\n\n// Support: Safari 8 only\n// In Safari 8 documents created via document.implementation.createHTMLDocument\n// collapse sibling forms: the second one becomes a child of the first one.\n// Because of that, this security measure has to be disabled in Safari 8.\n// https://bugs.webkit.org/show_bug.cgi?id=137337\nsupport.createHTMLDocument = ( function() {\n\tvar body = document.implementation.createHTMLDocument( \"\" ).body;\n\tbody.innerHTML = \"<form></form><form></form>\";\n\treturn body.childNodes.length === 2;\n} )();\n\n\n// Argument \"data\" should be string of html\n// context (optional): If specified, the fragment will be created in this context,\n// defaults to document\n// keepScripts (optional): If true, will include scripts passed in the html string\njQuery.parseHTML = function( data, context, keepScripts ) {\n\tif ( typeof data !== \"string\" ) {\n\t\treturn [];\n\t}\n\tif ( typeof context === \"boolean\" ) {\n\t\tkeepScripts = context;\n\t\tcontext = false;\n\t}\n\n\tvar base, parsed, scripts;\n\n\tif ( !context ) {\n\n\t\t// Stop scripts or inline event handlers from being executed immediately\n\t\t// by using document.implementation\n\t\tif ( support.createHTMLDocument ) {\n\t\t\tcontext = document.implementation.createHTMLDocument( \"\" );\n\n\t\t\t// Set the base href for the created document\n\t\t\t// so any parsed elements with URLs\n\t\t\t// are based on the document's URL (gh-2965)\n\t\t\tbase = context.createElement( \"base\" );\n\t\t\tbase.href = document.location.href;\n\t\t\tcontext.head.appendChild( base );\n\t\t} else {\n\t\t\tcontext = document;\n\t\t}\n\t}\n\n\tparsed = rsingleTag.exec( data );\n\tscripts = !keepScripts && [];\n\n\t// Single tag\n\tif ( parsed ) {\n\t\treturn [ context.createElement( parsed[ 1 ] ) ];\n\t}\n\n\tparsed = buildFragment( [ data ], context, scripts );\n\n\tif ( scripts && scripts.length ) {\n\t\tjQuery( scripts ).remove();\n\t}\n\n\treturn jQuery.merge( [], parsed.childNodes );\n};\n\n\n/**\n * Load a url into a page\n */\njQuery.fn.load = function( url, params, callback ) {\n\tvar selector, type, response,\n\t\tself = this,\n\t\toff = url.indexOf( \" \" );\n\n\tif ( off > -1 ) {\n\t\tselector = stripAndCollapse( url.slice( off ) );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// If we have elements to modify, make the request\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax( {\n\t\t\turl: url,\n\n\t\t\t// If \"type\" variable is undefined, then \"GET\" method will be used.\n\t\t\t// Make value of this field explicit since\n\t\t\t// user can override it through ajaxSetup method\n\t\t\ttype: type || \"GET\",\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t} ).done( function( responseText ) {\n\n\t\t\t// Save response for use in complete callback\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\n\t\t\t\t// If a selector was specified, locate the right elements in a dummy div\n\t\t\t\t// Exclude scripts to avoid IE 'Permission Denied' errors\n\t\t\t\tjQuery( \"<div>\" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n\t\t\t\t// Otherwise use the full result\n\t\t\t\tresponseText );\n\n\t\t// If the request succeeds, this function gets \"data\", \"status\", \"jqXHR\"\n\t\t// but they are ignored because response was set above.\n\t\t// If it fails, this function gets \"jqXHR\", \"status\", \"error\"\n\t\t} ).always( callback && function( jqXHR, status ) {\n\t\t\tself.each( function() {\n\t\t\t\tcallback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t\t} );\n\t\t} );\n\t}\n\n\treturn this;\n};\n\n\n\n\n// Attach a bunch of functions for handling common AJAX events\njQuery.each( [\n\t\"ajaxStart\",\n\t\"ajaxStop\",\n\t\"ajaxComplete\",\n\t\"ajaxError\",\n\t\"ajaxSuccess\",\n\t\"ajaxSend\"\n], function( i, type ) {\n\tjQuery.fn[ type ] = function( fn ) {\n\t\treturn this.on( type, fn );\n\t};\n} );\n\n\n\n\njQuery.expr.pseudos.animated = function( elem ) {\n\treturn jQuery.grep( jQuery.timers, function( fn ) {\n\t\treturn elem === fn.elem;\n\t} ).length;\n};\n\n\n\n\njQuery.offset = {\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, \"position\" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\n\t\t// Set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, \"top\" );\n\t\tcurCSSLeft = jQuery.css( elem, \"left\" );\n\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) &&\n\t\t\t( curCSSTop + curCSSLeft ).indexOf( \"auto\" ) > -1;\n\n\t\t// Need to be able to calculate position if either\n\t\t// top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( isFunction( options ) ) {\n\n\t\t\t// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)\n\t\t\toptions = options.call( elem, i, jQuery.extend( {}, curOffset ) );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\njQuery.fn.extend( {\n\n\t// offset() relates an element's border box to the document origin\n\toffset: function( options ) {\n\n\t\t// Preserve chaining for setter\n\t\tif ( arguments.length ) {\n\t\t\treturn options === undefined ?\n\t\t\t\tthis :\n\t\t\t\tthis.each( function( i ) {\n\t\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t\t} );\n\t\t}\n\n\t\tvar rect, win,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !elem ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Return zeros for disconnected and hidden (display: none) elements (gh-2310)\n\t\t// Support: IE <=11 only\n\t\t// Running getBoundingClientRect on a\n\t\t// disconnected node in IE throws an error\n\t\tif ( !elem.getClientRects().length ) {\n\t\t\treturn { top: 0, left: 0 };\n\t\t}\n\n\t\t// Get document-relative position by adding viewport scroll to viewport-relative gBCR\n\t\trect = elem.getBoundingClientRect();\n\t\twin = elem.ownerDocument.defaultView;\n\t\treturn {\n\t\t\ttop: rect.top + win.pageYOffset,\n\t\t\tleft: rect.left + win.pageXOffset\n\t\t};\n\t},\n\n\t// position() relates an element's margin box to its offset parent's padding box\n\t// This corresponds to the behavior of CSS absolute positioning\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset, doc,\n\t\t\telem = this[ 0 ],\n\t\t\tparentOffset = { top: 0, left: 0 };\n\n\t\t// position:fixed elements are offset from the viewport, which itself always has zero offset\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\n\t\t\t// Assume position:fixed implies availability of getBoundingClientRect\n\t\t\toffset = elem.getBoundingClientRect();\n\n\t\t} else {\n\t\t\toffset = this.offset();\n\n\t\t\t// Account for the *real* offset parent, which can be the document or its root element\n\t\t\t// when a statically positioned element is identified\n\t\t\tdoc = elem.ownerDocument;\n\t\t\toffsetParent = elem.offsetParent || doc.documentElement;\n\t\t\twhile ( offsetParent &&\n\t\t\t\t( offsetParent === doc.body || offsetParent === doc.documentElement ) &&\n\t\t\t\tjQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\n\t\t\t\toffsetParent = offsetParent.parentNode;\n\t\t\t}\n\t\t\tif ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {\n\n\t\t\t\t// Incorporate borders into its offset, since they are outside its content origin\n\t\t\t\tparentOffset = jQuery( offsetParent ).offset();\n\t\t\t\tparentOffset.top += jQuery.css( offsetParent, \"borderTopWidth\", true );\n\t\t\t\tparentOffset.left += jQuery.css( offsetParent, \"borderLeftWidth\", true );\n\t\t\t}\n\t\t}\n\n\t\t// Subtract parent offsets and element margins\n\t\treturn {\n\t\t\ttop: offset.top - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true )\n\t\t};\n\t},\n\n\t// This method will return documentElement in the following cases:\n\t// 1) For the element inside the iframe without offsetParent, this method will return\n\t//    documentElement of the parent window\n\t// 2) For the hidden or detached element\n\t// 3) For body or html element, i.e. in case of the html node - it will return itself\n\t//\n\t// but those exceptions were never presented as a real life use-cases\n\t// and might be considered as more preferable results.\n\t//\n\t// This logic, however, is not guaranteed and can change at any point in the future\n\toffsetParent: function() {\n\t\treturn this.map( function() {\n\t\t\tvar offsetParent = this.offsetParent;\n\n\t\t\twhile ( offsetParent && jQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\n\t\t\treturn offsetParent || documentElement;\n\t\t} );\n\t}\n} );\n\n// Create scrollLeft and scrollTop methods\njQuery.each( { scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\" }, function( method, prop ) {\n\tvar top = \"pageYOffset\" === prop;\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn access( this, function( elem, method, val ) {\n\n\t\t\t// Coalesce documents and windows\n\t\t\tvar win;\n\t\t\tif ( isWindow( elem ) ) {\n\t\t\t\twin = elem;\n\t\t\t} else if ( elem.nodeType === 9 ) {\n\t\t\t\twin = elem.defaultView;\n\t\t\t}\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? win[ prop ] : elem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : win.pageXOffset,\n\t\t\t\t\ttop ? val : win.pageYOffset\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length );\n\t};\n} );\n\n// Support: Safari <=7 - 9.1, Chrome <=37 - 49\n// Add the top/left cssHooks using jQuery.fn.position\n// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347\n// getComputedStyle returns percent when specified for top/left/bottom/right;\n// rather than make the css module depend on the offset module, just check for it here\njQuery.each( [ \"top\", \"left\" ], function( i, prop ) {\n\tjQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,\n\t\tfunction( elem, computed ) {\n\t\t\tif ( computed ) {\n\t\t\t\tcomputed = curCSS( elem, prop );\n\n\t\t\t\t// If curCSS returns percentage, fallback to offset\n\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\tcomputed;\n\t\t\t}\n\t\t}\n\t);\n} );\n\n\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name },\n\t\tfunction( defaultExtra, funcName ) {\n\n\t\t// Margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( isWindow( elem ) ) {\n\n\t\t\t\t\t// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)\n\t\t\t\t\treturn funcName.indexOf( \"outer\" ) === 0 ?\n\t\t\t\t\t\telem[ \"inner\" + name ] :\n\t\t\t\t\t\telem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],\n\t\t\t\t\t// whichever is greatest\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable );\n\t\t};\n\t} );\n} );\n\n\njQuery.each( ( \"blur focus focusin focusout resize scroll click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup contextmenu\" ).split( \" \" ),\n\tfunction( i, name ) {\n\n\t// Handle event binding\n\tjQuery.fn[ name ] = function( data, fn ) {\n\t\treturn arguments.length > 0 ?\n\t\t\tthis.on( name, null, data, fn ) :\n\t\t\tthis.trigger( name );\n\t};\n} );\n\njQuery.fn.extend( {\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t}\n} );\n\n\n\n\njQuery.fn.extend( {\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ?\n\t\t\tthis.off( selector, \"**\" ) :\n\t\t\tthis.off( types, selector || \"**\", fn );\n\t}\n} );\n\n// Bind a function to a context, optionally partially applying any\n// arguments.\n// jQuery.proxy is deprecated to promote standards (specifically Function#bind)\n// However, it is not slated for removal any time soon\njQuery.proxy = function( fn, context ) {\n\tvar tmp, args, proxy;\n\n\tif ( typeof context === \"string\" ) {\n\t\ttmp = fn[ context ];\n\t\tcontext = fn;\n\t\tfn = tmp;\n\t}\n\n\t// Quick check to determine if target is callable, in the spec\n\t// this throws a TypeError, but we will just return undefined.\n\tif ( !isFunction( fn ) ) {\n\t\treturn undefined;\n\t}\n\n\t// Simulated bind\n\targs = slice.call( arguments, 2 );\n\tproxy = function() {\n\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t};\n\n\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\treturn proxy;\n};\n\njQuery.holdReady = function( hold ) {\n\tif ( hold ) {\n\t\tjQuery.readyWait++;\n\t} else {\n\t\tjQuery.ready( true );\n\t}\n};\njQuery.isArray = Array.isArray;\njQuery.parseJSON = JSON.parse;\njQuery.nodeName = nodeName;\njQuery.isFunction = isFunction;\njQuery.isWindow = isWindow;\njQuery.camelCase = camelCase;\njQuery.type = toType;\n\njQuery.now = Date.now;\n\njQuery.isNumeric = function( obj ) {\n\n\t// As of jQuery 3.0, isNumeric is limited to\n\t// strings and numbers (primitives or objects)\n\t// that can be coerced to finite numbers (gh-2662)\n\tvar type = jQuery.type( obj );\n\treturn ( type === \"number\" || type === \"string\" ) &&\n\n\t\t// parseFloat NaNs numeric-cast false positives (\"\")\n\t\t// ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n\t\t// subtraction forces infinities to NaN\n\t\t!isNaN( obj - parseFloat( obj ) );\n};\n\n\n\n\n// Register as a named AMD module, since jQuery can be concatenated with other\n// files that may use define, but not via a proper concatenation script that\n// understands anonymous AMD modules. A named AMD is safest and most robust\n// way to register. Lowercase jquery is used because AMD module names are\n// derived from file names, and jQuery is normally delivered in a lowercase\n// file name. Do this after creating the global so that if an AMD module wants\n// to call noConflict to hide this version of jQuery, it will work.\n\n// Note that for maximum portability, libraries that are not jQuery should\n// declare themselves as anonymous modules, and avoid setting a global if an\n// AMD loader is present. jQuery is a special case. For more information, see\n// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon\n\nif ( typeof define === \"function\" && define.amd ) {\n\tdefine( \"jquery\", [], function() {\n\t\treturn jQuery;\n\t} );\n}\n\n\n\n\nvar\n\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$;\n\njQuery.noConflict = function( deep ) {\n\tif ( window.$ === jQuery ) {\n\t\twindow.$ = _$;\n\t}\n\n\tif ( deep && window.jQuery === jQuery ) {\n\t\twindow.jQuery = _jQuery;\n\t}\n\n\treturn jQuery;\n};\n\n// Expose jQuery and $ identifiers, even in AMD\n// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n// and CommonJS for browser emulators (#13566)\nif ( !noGlobal ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\n\n\n\nreturn jQuery;\n} );\n"
  },
  {
    "path": "docs/_static/jquery-3.5.1.js",
    "content": "/*!\n * jQuery JavaScript Library v3.5.1\n * https://jquery.com/\n *\n * Includes Sizzle.js\n * https://sizzlejs.com/\n *\n * Copyright JS Foundation and other contributors\n * Released under the MIT license\n * https://jquery.org/license\n *\n * Date: 2020-05-04T22:49Z\n */\n( function( global, factory ) {\n\n\t\"use strict\";\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\n\t\t// For CommonJS and CommonJS-like environments where a proper `window`\n\t\t// is present, execute the factory and get jQuery.\n\t\t// For environments that do not have a `window` with a `document`\n\t\t// (such as Node.js), expose a factory as module.exports.\n\t\t// This accentuates the need for the creation of a real `window`.\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info.\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n} )( typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1\n// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode\n// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common\n// enough that all such attempts are guarded in a try block.\n\"use strict\";\n\nvar arr = [];\n\nvar getProto = Object.getPrototypeOf;\n\nvar slice = arr.slice;\n\nvar flat = arr.flat ? function( array ) {\n\treturn arr.flat.call( array );\n} : function( array ) {\n\treturn arr.concat.apply( [], array );\n};\n\n\nvar push = arr.push;\n\nvar indexOf = arr.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar fnToString = hasOwn.toString;\n\nvar ObjectFunctionString = fnToString.call( Object );\n\nvar support = {};\n\nvar isFunction = function isFunction( obj ) {\n\n      // Support: Chrome <=57, Firefox <=52\n      // In some browsers, typeof returns \"function\" for HTML <object> elements\n      // (i.e., `typeof document.createElement( \"object\" ) === \"function\"`).\n      // We don't want to classify *any* DOM node as a function.\n      return typeof obj === \"function\" && typeof obj.nodeType !== \"number\";\n  };\n\n\nvar isWindow = function isWindow( obj ) {\n\t\treturn obj != null && obj === obj.window;\n\t};\n\n\nvar document = window.document;\n\n\n\n\tvar preservedScriptAttributes = {\n\t\ttype: true,\n\t\tsrc: true,\n\t\tnonce: true,\n\t\tnoModule: true\n\t};\n\n\tfunction DOMEval( code, node, doc ) {\n\t\tdoc = doc || document;\n\n\t\tvar i, val,\n\t\t\tscript = doc.createElement( \"script\" );\n\n\t\tscript.text = code;\n\t\tif ( node ) {\n\t\t\tfor ( i in preservedScriptAttributes ) {\n\n\t\t\t\t// Support: Firefox 64+, Edge 18+\n\t\t\t\t// Some browsers don't support the \"nonce\" property on scripts.\n\t\t\t\t// On the other hand, just using `getAttribute` is not enough as\n\t\t\t\t// the `nonce` attribute is reset to an empty string whenever it\n\t\t\t\t// becomes browsing-context connected.\n\t\t\t\t// See https://github.com/whatwg/html/issues/2369\n\t\t\t\t// See https://html.spec.whatwg.org/#nonce-attributes\n\t\t\t\t// The `node.getAttribute` check was added for the sake of\n\t\t\t\t// `jQuery.globalEval` so that it can fake a nonce-containing node\n\t\t\t\t// via an object.\n\t\t\t\tval = node[ i ] || node.getAttribute && node.getAttribute( i );\n\t\t\t\tif ( val ) {\n\t\t\t\t\tscript.setAttribute( i, val );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tdoc.head.appendChild( script ).parentNode.removeChild( script );\n\t}\n\n\nfunction toType( obj ) {\n\tif ( obj == null ) {\n\t\treturn obj + \"\";\n\t}\n\n\t// Support: Android <=2.3 only (functionish RegExp)\n\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\tclass2type[ toString.call( obj ) ] || \"object\" :\n\t\ttypeof obj;\n}\n/* global Symbol */\n// Defining this global in .eslintrc.json would create a danger of using the global\n// unguarded in another place, it seems safer to define global only for this module\n\n\n\nvar\n\tversion = \"3.5.1\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t};\n\njQuery.fn = jQuery.prototype = {\n\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\n\t\t// Return all the elements in a clean array\n\t\tif ( num == null ) {\n\t\t\treturn slice.call( this );\n\t\t}\n\n\t\t// Return just the one element from the set\n\t\treturn num < 0 ? this[ num + this.length ] : this[ num ];\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\teach: function( callback ) {\n\t\treturn jQuery.each( this, callback );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map( this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t} ) );\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teven: function() {\n\t\treturn this.pushStack( jQuery.grep( this, function( _elem, i ) {\n\t\t\treturn ( i + 1 ) % 2;\n\t\t} ) );\n\t},\n\n\todd: function() {\n\t\treturn this.pushStack( jQuery.grep( this, function( _elem, i ) {\n\t\t\treturn i % 2;\n\t\t} ) );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor();\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: arr.sort,\n\tsplice: arr.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[ 0 ] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// Skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !isFunction( target ) ) {\n\t\ttarget = {};\n\t}\n\n\t// Extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\n\t\t// Only deal with non-null/undefined values\n\t\tif ( ( options = arguments[ i ] ) != null ) {\n\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent Object.prototype pollution\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( name === \"__proto__\" || target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject( copy ) ||\n\t\t\t\t\t( copyIsArray = Array.isArray( copy ) ) ) ) {\n\t\t\t\t\tsrc = target[ name ];\n\n\t\t\t\t\t// Ensure proper type for the source value\n\t\t\t\t\tif ( copyIsArray && !Array.isArray( src ) ) {\n\t\t\t\t\t\tclone = [];\n\t\t\t\t\t} else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {\n\t\t\t\t\t\tclone = {};\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src;\n\t\t\t\t\t}\n\t\t\t\t\tcopyIsArray = false;\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend( {\n\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\tisPlainObject: function( obj ) {\n\t\tvar proto, Ctor;\n\n\t\t// Detect obvious negatives\n\t\t// Use toString instead of jQuery.type to catch host objects\n\t\tif ( !obj || toString.call( obj ) !== \"[object Object]\" ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tproto = getProto( obj );\n\n\t\t// Objects with no prototype (e.g., `Object.create( null )`) are plain\n\t\tif ( !proto ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Objects with prototype are plain iff they were constructed by a global Object function\n\t\tCtor = hasOwn.call( proto, \"constructor\" ) && proto.constructor;\n\t\treturn typeof Ctor === \"function\" && fnToString.call( Ctor ) === ObjectFunctionString;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\t// Evaluates a script in a provided context; falls back to the global one\n\t// if not specified.\n\tglobalEval: function( code, options, doc ) {\n\t\tDOMEval( code, { nonce: options && options.nonce }, doc );\n\t},\n\n\teach: function( obj, callback ) {\n\t\tvar length, i = 0;\n\n\t\tif ( isArrayLike( obj ) ) {\n\t\t\tlength = obj.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor ( i in obj ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArrayLike( Object( arr ) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\treturn arr == null ? -1 : indexOf.call( arr, elem, i );\n\t},\n\n\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t// push.apply(_, arraylike) throws on ancient WebKit\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\tfor ( ; j < len; j++ ) {\n\t\t\tfirst[ i++ ] = second[ j ];\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar length, value,\n\t\t\ti = 0,\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArrayLike( elems ) ) {\n\t\t\tlength = elems.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn flat( ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n} );\n\nif ( typeof Symbol === \"function\" ) {\n\tjQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];\n}\n\n// Populate the class2type map\njQuery.each( \"Boolean Number String Function Array Date RegExp Object Error Symbol\".split( \" \" ),\nfunction( _i, name ) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n} );\n\nfunction isArrayLike( obj ) {\n\n\t// Support: real iOS 8.2 only (not reproducible in simulator)\n\t// `in` check used to prevent JIT error (gh-2145)\n\t// hasOwn isn't used here due to false negatives\n\t// regarding Nodelist length in IE\n\tvar length = !!obj && \"length\" in obj && obj.length,\n\t\ttype = toType( obj );\n\n\tif ( isFunction( obj ) || isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v2.3.5\n * https://sizzlejs.com/\n *\n * Copyright JS Foundation and other contributors\n * Released under the MIT license\n * https://js.foundation/\n *\n * Date: 2020-03-14\n */\n( function( window ) {\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + 1 * new Date(),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tnonnativeSelectorCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// Instance methods\n\thasOwn = ( {} ).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpushNative = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\n\t// Use a stripped-down indexOf as it's faster than native\n\t// https://jsperf.com/thor-indexof-vs-for/5\n\tindexOf = function( list, elem ) {\n\t\tvar i = 0,\n\t\t\tlen = list.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( list[ i ] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|\" +\n\t\t\"ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\n\t// https://www.w3.org/TR/css-syntax-3/#ident-token-diagram\n\tidentifier = \"(?:\\\\\\\\[\\\\da-fA-F]{1,6}\" + whitespace +\n\t\t\"?|\\\\\\\\[^\\\\r\\\\n\\\\f]|[\\\\w-]|[^\\0-\\\\x7f])+\",\n\n\t// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + identifier + \")(?:\" + whitespace +\n\n\t\t// Operator (capture 2)\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\n\t\t// \"Attribute values must be CSS identifiers [capture 5]\n\t\t// or strings [capture 3 or capture 4]\"\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" +\n\t\twhitespace + \"*\\\\]\",\n\n\tpseudos = \":(\" + identifier + \")(?:\\\\((\" +\n\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\n\t\t// 2. simple (capture 6)\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\n\t\t// 3. anything else (capture 2)\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + \"+\", \"g\" ),\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" +\n\t\twhitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace +\n\t\t\"*\" ),\n\trdescend = new RegExp( whitespace + \"|>\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + identifier + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + identifier + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + identifier + \"|[*])\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" +\n\t\t\twhitespace + \"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" +\n\t\t\twhitespace + \"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace +\n\t\t\t\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" + whitespace +\n\t\t\t\"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trhtml = /HTML$/i,\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\n\t// CSS escapes\n\t// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\[\\\\da-fA-F]{1,6}\" + whitespace + \"?|\\\\\\\\([^\\\\r\\\\n\\\\f])\", \"g\" ),\n\tfunescape = function( escape, nonHex ) {\n\t\tvar high = \"0x\" + escape.slice( 1 ) - 0x10000;\n\n\t\treturn nonHex ?\n\n\t\t\t// Strip the backslash prefix from a non-hex escape sequence\n\t\t\tnonHex :\n\n\t\t\t// Replace a hexadecimal escape sequence with the encoded Unicode code point\n\t\t\t// Support: IE <=11+\n\t\t\t// For values outside the Basic Multilingual Plane (BMP), manually construct a\n\t\t\t// surrogate pair\n\t\t\thigh < 0 ?\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// CSS string/identifier serialization\n\t// https://drafts.csswg.org/cssom/#common-serializing-idioms\n\trcssescape = /([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\0-\\x1f\\x7f-\\uFFFF\\w-]/g,\n\tfcssescape = function( ch, asCodePoint ) {\n\t\tif ( asCodePoint ) {\n\n\t\t\t// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER\n\t\t\tif ( ch === \"\\0\" ) {\n\t\t\t\treturn \"\\uFFFD\";\n\t\t\t}\n\n\t\t\t// Control characters and (dependent upon position) numbers get escaped as code points\n\t\t\treturn ch.slice( 0, -1 ) + \"\\\\\" +\n\t\t\t\tch.charCodeAt( ch.length - 1 ).toString( 16 ) + \" \";\n\t\t}\n\n\t\t// Other potentially-special ASCII characters get backslash-escaped\n\t\treturn \"\\\\\" + ch;\n\t},\n\n\t// Used for iframes\n\t// See setDocument()\n\t// Removing the function wrapper causes a \"Permission Denied\"\n\t// error in IE\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t},\n\n\tinDisabledFieldset = addCombinator(\n\t\tfunction( elem ) {\n\t\t\treturn elem.disabled === true && elem.nodeName.toLowerCase() === \"fieldset\";\n\t\t},\n\t\t{ dir: \"parentNode\", next: \"legend\" }\n\t);\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t( arr = slice.call( preferredDoc.childNodes ) ),\n\t\tpreferredDoc.childNodes\n\t);\n\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\t// eslint-disable-next-line no-unused-expressions\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpushNative.apply( target, slice.call( els ) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( ( target[ j++ ] = els[ i++ ] ) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar m, i, elem, nid, match, groups, newSelector,\n\t\tnewContext = context && context.ownerDocument,\n\n\t\t// nodeType defaults to 9, since context defaults to document\n\t\tnodeType = context ? context.nodeType : 9;\n\n\tresults = results || [];\n\n\t// Return early from calls with invalid selector or context\n\tif ( typeof selector !== \"string\" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\t// Try to shortcut find operations (as opposed to filters) in HTML documents\n\tif ( !seed ) {\n\t\tsetDocument( context );\n\t\tcontext = context || document;\n\n\t\tif ( documentIsHTML ) {\n\n\t\t\t// If the selector is sufficiently simple, try using a \"get*By*\" DOM method\n\t\t\t// (excepting DocumentFragment context, where the methods don't exist)\n\t\t\tif ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) {\n\n\t\t\t\t// ID selector\n\t\t\t\tif ( ( m = match[ 1 ] ) ) {\n\n\t\t\t\t\t// Document context\n\t\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\t\tif ( ( elem = context.getElementById( m ) ) ) {\n\n\t\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t// Element context\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\tif ( newContext && ( elem = newContext.getElementById( m ) ) &&\n\t\t\t\t\t\t\tcontains( context, elem ) &&\n\t\t\t\t\t\t\telem.id === m ) {\n\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t// Type selector\n\t\t\t\t} else if ( match[ 2 ] ) {\n\t\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\t\treturn results;\n\n\t\t\t\t// Class selector\n\t\t\t\t} else if ( ( m = match[ 3 ] ) && support.getElementsByClassName &&\n\t\t\t\t\tcontext.getElementsByClassName ) {\n\n\t\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\t\treturn results;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Take advantage of querySelectorAll\n\t\t\tif ( support.qsa &&\n\t\t\t\t!nonnativeSelectorCache[ selector + \" \" ] &&\n\t\t\t\t( !rbuggyQSA || !rbuggyQSA.test( selector ) ) &&\n\n\t\t\t\t// Support: IE 8 only\n\t\t\t\t// Exclude object elements\n\t\t\t\t( nodeType !== 1 || context.nodeName.toLowerCase() !== \"object\" ) ) {\n\n\t\t\t\tnewSelector = selector;\n\t\t\t\tnewContext = context;\n\n\t\t\t\t// qSA considers elements outside a scoping root when evaluating child or\n\t\t\t\t// descendant combinators, which is not what we want.\n\t\t\t\t// In such cases, we work around the behavior by prefixing every selector in the\n\t\t\t\t// list with an ID selector referencing the scope context.\n\t\t\t\t// The technique has to be used as well when a leading combinator is used\n\t\t\t\t// as such selectors are not recognized by querySelectorAll.\n\t\t\t\t// Thanks to Andrew Dupont for this technique.\n\t\t\t\tif ( nodeType === 1 &&\n\t\t\t\t\t( rdescend.test( selector ) || rcombinators.test( selector ) ) ) {\n\n\t\t\t\t\t// Expand context for sibling selectors\n\t\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) ||\n\t\t\t\t\t\tcontext;\n\n\t\t\t\t\t// We can use :scope instead of the ID hack if the browser\n\t\t\t\t\t// supports it & if we're not changing the context.\n\t\t\t\t\tif ( newContext !== context || !support.scope ) {\n\n\t\t\t\t\t\t// Capture the context ID, setting it first if necessary\n\t\t\t\t\t\tif ( ( nid = context.getAttribute( \"id\" ) ) ) {\n\t\t\t\t\t\t\tnid = nid.replace( rcssescape, fcssescape );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcontext.setAttribute( \"id\", ( nid = expando ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prefix every selector in the list\n\t\t\t\t\tgroups = tokenize( selector );\n\t\t\t\t\ti = groups.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tgroups[ i ] = ( nid ? \"#\" + nid : \":scope\" ) + \" \" +\n\t\t\t\t\t\t\ttoSelector( groups[ i ] );\n\t\t\t\t\t}\n\t\t\t\t\tnewSelector = groups.join( \",\" );\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t);\n\t\t\t\t\treturn results;\n\t\t\t\t} catch ( qsaError ) {\n\t\t\t\t\tnonnativeSelectorCache( selector, true );\n\t\t\t\t} finally {\n\t\t\t\t\tif ( nid === expando ) {\n\t\t\t\t\t\tcontext.removeAttribute( \"id\" );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {function(string, object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn ( cache[ key + \" \" ] = value );\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created element and returns a boolean result\n */\nfunction assert( fn ) {\n\tvar el = document.createElement( \"fieldset\" );\n\n\ttry {\n\t\treturn !!fn( el );\n\t} catch ( e ) {\n\t\treturn false;\n\t} finally {\n\n\t\t// Remove from its parent by default\n\t\tif ( el.parentNode ) {\n\t\t\tel.parentNode.removeChild( el );\n\t\t}\n\n\t\t// release memory in IE\n\t\tel = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split( \"|\" ),\n\t\ti = arr.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[ i ] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\ta.sourceIndex - b.sourceIndex;\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( ( cur = cur.nextSibling ) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn ( name === \"input\" || name === \"button\" ) && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for :enabled/:disabled\n * @param {Boolean} disabled true for :disabled; false for :enabled\n */\nfunction createDisabledPseudo( disabled ) {\n\n\t// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable\n\treturn function( elem ) {\n\n\t\t// Only certain elements can match :enabled or :disabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled\n\t\tif ( \"form\" in elem ) {\n\n\t\t\t// Check for inherited disabledness on relevant non-disabled elements:\n\t\t\t// * listed form-associated elements in a disabled fieldset\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#category-listed\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled\n\t\t\t// * option elements in a disabled optgroup\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled\n\t\t\t// All such elements have a \"form\" property.\n\t\t\tif ( elem.parentNode && elem.disabled === false ) {\n\n\t\t\t\t// Option elements defer to a parent optgroup if present\n\t\t\t\tif ( \"label\" in elem ) {\n\t\t\t\t\tif ( \"label\" in elem.parentNode ) {\n\t\t\t\t\t\treturn elem.parentNode.disabled === disabled;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn elem.disabled === disabled;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Support: IE 6 - 11\n\t\t\t\t// Use the isDisabled shortcut property to check for disabled fieldset ancestors\n\t\t\t\treturn elem.isDisabled === disabled ||\n\n\t\t\t\t\t// Where there is no isDisabled, check manually\n\t\t\t\t\t/* jshint -W018 */\n\t\t\t\t\telem.isDisabled !== !disabled &&\n\t\t\t\t\tinDisabledFieldset( elem ) === disabled;\n\t\t\t}\n\n\t\t\treturn elem.disabled === disabled;\n\n\t\t// Try to winnow out elements that can't be disabled before trusting the disabled property.\n\t\t// Some victims get caught in our net (label, legend, menu, track), but it shouldn't\n\t\t// even exist on them, let alone have a boolean value.\n\t\t} else if ( \"label\" in elem ) {\n\t\t\treturn elem.disabled === disabled;\n\t\t}\n\n\t\t// Remaining elements are neither :enabled nor :disabled\n\t\treturn false;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction( function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction( function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ ( j = matchIndexes[ i ] ) ] ) {\n\t\t\t\t\tseed[ j ] = !( matches[ j ] = seed[ j ] );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t} );\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== \"undefined\" && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\tvar namespace = elem.namespaceURI,\n\t\tdocElem = ( elem.ownerDocument || elem ).documentElement;\n\n\t// Support: IE <=8\n\t// Assume HTML when documentElement doesn't yet exist, such as inside loading iframes\n\t// https://bugs.jquery.com/ticket/4833\n\treturn !rhtml.test( namespace || docElem && docElem.nodeName || \"HTML\" );\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare, subWindow,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// Return early if doc is invalid or already selected\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Update global variables\n\tdocument = doc;\n\tdocElem = document.documentElement;\n\tdocumentIsHTML = !isXML( document );\n\n\t// Support: IE 9 - 11+, Edge 12 - 18+\n\t// Accessing iframe documents after unload throws \"permission denied\" errors (jQuery #13936)\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( preferredDoc != document &&\n\t\t( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {\n\n\t\t// Support: IE 11, Edge\n\t\tif ( subWindow.addEventListener ) {\n\t\t\tsubWindow.addEventListener( \"unload\", unloadHandler, false );\n\n\t\t// Support: IE 9 - 10 only\n\t\t} else if ( subWindow.attachEvent ) {\n\t\t\tsubWindow.attachEvent( \"onunload\", unloadHandler );\n\t\t}\n\t}\n\n\t// Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only,\n\t// Safari 4 - 5 only, Opera <=11.6 - 12.x only\n\t// IE/Edge & older browsers don't support the :scope pseudo-class.\n\t// Support: Safari 6.0 only\n\t// Safari 6.0 supports :scope but it's an alias of :root there.\n\tsupport.scope = assert( function( el ) {\n\t\tdocElem.appendChild( el ).appendChild( document.createElement( \"div\" ) );\n\t\treturn typeof el.querySelectorAll !== \"undefined\" &&\n\t\t\t!el.querySelectorAll( \":scope fieldset div\" ).length;\n\t} );\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties\n\t// (excepting IE8 booleans)\n\tsupport.attributes = assert( function( el ) {\n\t\tel.className = \"i\";\n\t\treturn !el.getAttribute( \"className\" );\n\t} );\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert( function( el ) {\n\t\tel.appendChild( document.createComment( \"\" ) );\n\t\treturn !el.getElementsByTagName( \"*\" ).length;\n\t} );\n\n\t// Support: IE<9\n\tsupport.getElementsByClassName = rnative.test( document.getElementsByClassName );\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programmatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert( function( el ) {\n\t\tdocElem.appendChild( el ).id = expando;\n\t\treturn !document.getElementsByName || !document.getElementsByName( expando ).length;\n\t} );\n\n\t// ID filter and find\n\tif ( support.getById ) {\n\t\tExpr.filter[ \"ID\" ] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute( \"id\" ) === attrId;\n\t\t\t};\n\t\t};\n\t\tExpr.find[ \"ID\" ] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar elem = context.getElementById( id );\n\t\t\t\treturn elem ? [ elem ] : [];\n\t\t\t}\n\t\t};\n\t} else {\n\t\tExpr.filter[ \"ID\" ] =  function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" &&\n\t\t\t\t\telem.getAttributeNode( \"id\" );\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\n\t\t// Support: IE 6 - 7 only\n\t\t// getElementById is not reliable as a find shortcut\n\t\tExpr.find[ \"ID\" ] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar node, i, elems,\n\t\t\t\t\telem = context.getElementById( id );\n\n\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t// Verify the id attribute\n\t\t\t\t\tnode = elem.getAttributeNode( \"id\" );\n\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t}\n\n\t\t\t\t\t// Fall back on getElementsByName\n\t\t\t\t\telems = context.getElementsByName( id );\n\t\t\t\t\ti = 0;\n\t\t\t\t\twhile ( ( elem = elems[ i++ ] ) ) {\n\t\t\t\t\t\tnode = elem.getAttributeNode( \"id\" );\n\t\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn [];\n\t\t\t}\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[ \"TAG\" ] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t\t// DocumentFragment nodes don't have gEBTN\n\t\t\t} else if ( support.qsa ) {\n\t\t\t\treturn context.querySelectorAll( tag );\n\t\t\t}\n\t\t} :\n\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\n\t\t\t\t// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( ( elem = results[ i++ ] ) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[ \"CLASS\" ] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( typeof context.getElementsByClassName !== \"undefined\" && documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See https://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) {\n\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert( function( el ) {\n\n\t\t\tvar input;\n\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// https://bugs.jquery.com/ticket/12359\n\t\t\tdocElem.appendChild( el ).innerHTML = \"<a id='\" + expando + \"'></a>\" +\n\t\t\t\t\"<select id='\" + expando + \"-\\r\\\\' msallowcapture=''>\" +\n\t\t\t\t\"<option selected=''></option></select>\";\n\n\t\t\t// Support: IE8, Opera 11-12.16\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\t// The test attribute must be unknown in Opera but \"safe\" for WinRT\n\t\t\t// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\t\t\tif ( el.querySelectorAll( \"[msallowcapture^='']\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !el.querySelectorAll( \"[selected]\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+\n\t\t\tif ( !el.querySelectorAll( \"[id~=\" + expando + \"-]\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"~=\" );\n\t\t\t}\n\n\t\t\t// Support: IE 11+, Edge 15 - 18+\n\t\t\t// IE 11/Edge don't find elements on a `[name='']` query in some cases.\n\t\t\t// Adding a temporary attribute to the document before the selection works\n\t\t\t// around the issue.\n\t\t\t// Interestingly, IE 10 & older don't seem to have the issue.\n\t\t\tinput = document.createElement( \"input\" );\n\t\t\tinput.setAttribute( \"name\", \"\" );\n\t\t\tel.appendChild( input );\n\t\t\tif ( !el.querySelectorAll( \"[name='']\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*name\" + whitespace + \"*=\" +\n\t\t\t\t\twhitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !el.querySelectorAll( \":checked\" ).length ) {\n\t\t\t\trbuggyQSA.push( \":checked\" );\n\t\t\t}\n\n\t\t\t// Support: Safari 8+, iOS 8+\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t\t// In-page `selector#id sibling-combinator selector` fails\n\t\t\tif ( !el.querySelectorAll( \"a#\" + expando + \"+*\" ).length ) {\n\t\t\t\trbuggyQSA.push( \".#.+[+~]\" );\n\t\t\t}\n\n\t\t\t// Support: Firefox <=3.6 - 5 only\n\t\t\t// Old Firefox doesn't throw on a badly-escaped identifier.\n\t\t\tel.querySelectorAll( \"\\\\\\f\" );\n\t\t\trbuggyQSA.push( \"[\\\\r\\\\n\\\\f]\" );\n\t\t} );\n\n\t\tassert( function( el ) {\n\t\t\tel.innerHTML = \"<a href='' disabled='disabled'></a>\" +\n\t\t\t\t\"<select disabled='disabled'><option/></select>\";\n\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = document.createElement( \"input\" );\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tel.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( el.querySelectorAll( \"[name=d]\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( el.querySelectorAll( \":enabled\" ).length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Support: IE9-11+\n\t\t\t// IE's :disabled selector does not pick up the children of disabled fieldsets\n\t\t\tdocElem.appendChild( el ).disabled = true;\n\t\t\tif ( el.querySelectorAll( \":disabled\" ).length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Support: Opera 10 - 11 only\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tel.querySelectorAll( \"*,:x\" );\n\t\t\trbuggyQSA.push( \",.*:\" );\n\t\t} );\n\t}\n\n\tif ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector ) ) ) ) {\n\n\t\tassert( function( el ) {\n\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( el, \"*\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( el, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t} );\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( \"|\" ) );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( \"|\" ) );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully self-exclusive\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t) );\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( ( b = b.parentNode ) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t// two documents; shallow comparisons work.\n\t\t// eslint-disable-next-line eqeqeq\n\t\tcompare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\tif ( a == document || a.ownerDocument == preferredDoc &&\n\t\t\t\tcontains( preferredDoc, a ) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\tif ( b == document || b.ownerDocument == preferredDoc &&\n\t\t\t\tcontains( preferredDoc, b ) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t/* eslint-disable eqeqeq */\n\t\t\treturn a == document ? -1 :\n\t\t\t\tb == document ? 1 :\n\t\t\t\t/* eslint-enable eqeqeq */\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( ( cur = cur.parentNode ) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( ( cur = cur.parentNode ) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[ i ] === bp[ i ] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[ i ], bp[ i ] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t/* eslint-disable eqeqeq */\n\t\t\tap[ i ] == preferredDoc ? -1 :\n\t\t\tbp[ i ] == preferredDoc ? 1 :\n\t\t\t/* eslint-enable eqeqeq */\n\t\t\t0;\n\t};\n\n\treturn document;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\tsetDocument( elem );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t!nonnativeSelectorCache[ expr + \" \" ] &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\n\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t// fragment in IE 9\n\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch ( e ) {\n\t\t\tnonnativeSelectorCache( expr, true );\n\t\t}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\n\t// Set document vars if needed\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( ( context.ownerDocument || context ) != document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\n\t// Set document vars if needed\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( ( elem.ownerDocument || elem ) != document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t( val = elem.getAttributeNode( name ) ) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.escape = function( sel ) {\n\treturn ( sel + \"\" ).replace( rcssescape, fcssescape );\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( ( elem = results[ i++ ] ) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( ( node = elem[ i++ ] ) ) {\n\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[ 1 ] = match[ 1 ].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[ 3 ] = ( match[ 3 ] || match[ 4 ] ||\n\t\t\t\tmatch[ 5 ] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[ 2 ] === \"~=\" ) {\n\t\t\t\tmatch[ 3 ] = \" \" + match[ 3 ] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[ 1 ] = match[ 1 ].toLowerCase();\n\n\t\t\tif ( match[ 1 ].slice( 0, 3 ) === \"nth\" ) {\n\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[ 3 ] ) {\n\t\t\t\t\tSizzle.error( match[ 0 ] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[ 4 ] = +( match[ 4 ] ?\n\t\t\t\t\tmatch[ 5 ] + ( match[ 6 ] || 1 ) :\n\t\t\t\t\t2 * ( match[ 3 ] === \"even\" || match[ 3 ] === \"odd\" ) );\n\t\t\t\tmatch[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === \"odd\" );\n\n\t\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[ 3 ] ) {\n\t\t\t\tSizzle.error( match[ 0 ] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[ 6 ] && match[ 2 ];\n\n\t\t\tif ( matchExpr[ \"CHILD\" ].test( match[ 0 ] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[ 3 ] ) {\n\t\t\t\tmatch[ 2 ] = match[ 4 ] || match[ 5 ] || \"\";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t( excess = tokenize( unquoted, true ) ) &&\n\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t( excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length ) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[ 0 ] = match[ 0 ].slice( 0, excess );\n\t\t\t\tmatch[ 2 ] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() {\n\t\t\t\t\treturn true;\n\t\t\t\t} :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t( pattern = new RegExp( \"(^|\" + whitespace +\n\t\t\t\t\t\")\" + className + \"(\" + whitespace + \"|$)\" ) ) && classCache(\n\t\t\t\t\t\tclassName, function( elem ) {\n\t\t\t\t\t\t\treturn pattern.test(\n\t\t\t\t\t\t\t\ttypeof elem.className === \"string\" && elem.className ||\n\t\t\t\t\t\t\t\ttypeof elem.getAttribute !== \"undefined\" &&\n\t\t\t\t\t\t\t\t\telem.getAttribute( \"class\" ) ||\n\t\t\t\t\t\t\t\t\"\"\n\t\t\t\t\t\t\t);\n\t\t\t\t} );\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\t/* eslint-disable max-len */\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result.replace( rwhitespace, \" \" ) + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t\t/* eslint-enable max-len */\n\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, _argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, _context, xml ) {\n\t\t\t\t\tvar cache, uniqueCache, outerCache, node, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType,\n\t\t\t\t\t\tdiff = false;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( ( node = node[ dir ] ) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) {\n\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\n\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\tnode = parent;\n\t\t\t\t\t\t\touterCache = node[ expando ] || ( node[ expando ] = {} );\n\n\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t( outerCache[ node.uniqueID ] = {} );\n\n\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\tdiff = nodeIndex && cache[ 2 ];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( ( node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t( diff = nodeIndex = 0 ) || start.pop() ) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t\tif ( useCache ) {\n\n\t\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\touterCache = node[ expando ] || ( node[ expando ] = {} );\n\n\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t( outerCache[ node.uniqueID ] = {} );\n\n\t\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\t\tdiff = nodeIndex;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// xml :nth-child(...)\n\t\t\t\t\t\t\t// or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t\tif ( diff === false ) {\n\n\t\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\t\twhile ( ( node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t\t( diff = nodeIndex = 0 ) || start.pop() ) ) {\n\n\t\t\t\t\t\t\t\t\tif ( ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) &&\n\t\t\t\t\t\t\t\t\t\t++diff ) {\n\n\t\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t\touterCache = node[ expando ] ||\n\t\t\t\t\t\t\t\t\t\t\t\t( node[ expando ] = {} );\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t\t\t\t( outerCache[ node.uniqueID ] = {} );\n\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction( function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf( seed, matched[ i ] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[ i ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t} ) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction( function( selector ) {\n\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction( function( seed, matches, _context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( ( elem = unmatched[ i ] ) ) {\n\t\t\t\t\t\t\tseed[ i ] = !( matches[ i ] = elem );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} ) :\n\t\t\t\tfunction( elem, _context, xml ) {\n\t\t\t\t\tinput[ 0 ] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\n\t\t\t\t\t// Don't keep the element (issue #299)\n\t\t\t\t\tinput[ 0 ] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t} ),\n\n\t\t\"has\": markFunction( function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t} ),\n\n\t\t\"contains\": markFunction( function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t} ),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test( lang || \"\" ) ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( ( elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute( \"xml:lang\" ) || elem.getAttribute( \"lang\" ) ) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( ( elem = elem.parentNode ) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t} ),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement &&\n\t\t\t\t( !document.hasFocus || document.hasFocus() ) &&\n\t\t\t\t!!( elem.type || elem.href || ~elem.tabIndex );\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": createDisabledPseudo( false ),\n\t\t\"disabled\": createDisabledPseudo( true ),\n\n\t\t\"checked\": function( elem ) {\n\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn ( nodeName === \"input\" && !!elem.checked ) ||\n\t\t\t\t( nodeName === \"option\" && !!elem.selected );\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\t// eslint-disable-next-line no-unused-expressions\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t//   but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[ \"empty\" ]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( ( attr = elem.getAttribute( \"type\" ) ) == null ||\n\t\t\t\t\tattr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo( function() {\n\t\t\treturn [ 0 ];\n\t\t} ),\n\n\t\t\"last\": createPositionalPseudo( function( _matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t} ),\n\n\t\t\"eq\": createPositionalPseudo( function( _matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t} ),\n\n\t\t\"even\": createPositionalPseudo( function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} ),\n\n\t\t\"odd\": createPositionalPseudo( function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} ),\n\n\t\t\"lt\": createPositionalPseudo( function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ?\n\t\t\t\targument + length :\n\t\t\t\targument > length ?\n\t\t\t\t\tlength :\n\t\t\t\t\targument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} ),\n\n\t\t\"gt\": createPositionalPseudo( function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} )\n\t}\n};\n\nExpr.pseudos[ \"nth\" ] = Expr.pseudos[ \"eq\" ];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || ( match = rcomma.exec( soFar ) ) ) {\n\t\t\tif ( match ) {\n\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[ 0 ].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( ( tokens = [] ) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( ( match = rcombinators.exec( soFar ) ) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push( {\n\t\t\t\tvalue: matched,\n\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[ 0 ].replace( rtrim, \" \" )\n\t\t\t} );\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] ||\n\t\t\t\t( match = preFilters[ type ]( match ) ) ) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push( {\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t} );\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[ i ].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tskip = combinator.next,\n\t\tkey = skip || dir,\n\t\tcheckNonElements = base && key === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( ( elem = elem[ dir ] ) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, uniqueCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( ( elem = elem[ dir ] ) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( ( elem = elem[ dir ] ) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || ( elem[ expando ] = {} );\n\n\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\tuniqueCache = outerCache[ elem.uniqueID ] ||\n\t\t\t\t\t\t\t( outerCache[ elem.uniqueID ] = {} );\n\n\t\t\t\t\t\tif ( skip && skip === elem.nodeName.toLowerCase() ) {\n\t\t\t\t\t\t\telem = elem[ dir ] || elem;\n\t\t\t\t\t\t} else if ( ( oldCache = uniqueCache[ key ] ) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn ( newCache[ 2 ] = oldCache[ 2 ] );\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\tuniqueCache[ key ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[ i ]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[ 0 ];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[ i ], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( ( elem = unmatched[ i ] ) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction( function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts(\n\t\t\t\tselector || \"*\",\n\t\t\t\tcontext.nodeType ? [ context ] : context,\n\t\t\t\t[]\n\t\t\t),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( ( elem = temp[ i ] ) ) {\n\t\t\t\t\tmatcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( ( elem = matcherOut[ i ] ) ) {\n\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( ( matcherIn[ i ] = elem ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, ( matcherOut = [] ), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( ( elem = matcherOut[ i ] ) &&\n\t\t\t\t\t\t( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) {\n\n\t\t\t\t\t\tseed[ temp ] = !( results[ temp ] = elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t} );\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[ 0 ].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[ \" \" ],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\tvar ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t( checkContext = context ).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\n\t\t\t// Avoid hanging onto element (issue #299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) {\n\t\t\tmatchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[ j ].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\n\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\ttokens\n\t\t\t\t\t\t.slice( 0, i - 1 )\n\t\t\t\t\t\t.concat( { value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" } )\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[ \"TAG\" ]( \"*\", outermost ),\n\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\n\t\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t\t// two documents; shallow comparisons work.\n\t\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\t\toutermostContext = context == document || context || outermost;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: <number>) matching elements by id\n\t\t\tfor ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\n\t\t\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t\t\t// two documents; shallow comparisons work.\n\t\t\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\t\t\tif ( !context && elem.ownerDocument != document ) {\n\t\t\t\t\t\tsetDocument( elem );\n\t\t\t\t\t\txml = !documentIsHTML;\n\t\t\t\t\t}\n\t\t\t\t\twhile ( ( matcher = elementMatchers[ j++ ] ) ) {\n\t\t\t\t\t\tif ( matcher( elem, context || document, xml ) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( ( elem = !matcher && elem ) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// `i` is now the count of elements visited above, and adding it to `matchedCount`\n\t\t\t// makes the latter nonnegative.\n\t\t\tmatchedCount += i;\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\t// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`\n\t\t\t// equals `i`), unless we didn't visit _any_ elements in the above loop because we have\n\t\t\t// no element matchers and no seed.\n\t\t\t// Incrementing an initially-string \"0\" `i` allows `i` to remain a string only in that\n\t\t\t// case, which will result in a \"00\" `matchedCount` that differs from `i` but is also\n\t\t\t// numerically zero.\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( ( matcher = setMatchers[ j++ ] ) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !( unmatched[ i ] || setMatched[ i ] ) ) {\n\t\t\t\t\t\t\t\tsetMatched[ i ] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[ i ] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache(\n\t\t\tselector,\n\t\t\tmatcherFromGroupMatchers( elementMatchers, setMatchers )\n\t\t);\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\n/**\n * A low-level selection function that works with Sizzle's compiled\n *  selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n *  selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( ( selector = compiled.selector || selector ) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is only one selector in the list and no seed\n\t// (the latter of which guarantees us context)\n\tif ( match.length === 1 ) {\n\n\t\t// Reduce context if the leading compound selector is an ID\n\t\ttokens = match[ 0 ] = match[ 0 ].slice( 0 );\n\t\tif ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === \"ID\" &&\n\t\t\tcontext.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) {\n\n\t\t\tcontext = ( Expr.find[ \"ID\" ]( token.matches[ 0 ]\n\t\t\t\t.replace( runescape, funescape ), context ) || [] )[ 0 ];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr[ \"needsContext\" ].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[ i ];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ ( type = token.type ) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( ( find = Expr.find[ type ] ) ) {\n\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( ( seed = find(\n\t\t\t\t\ttoken.matches[ 0 ].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) ||\n\t\t\t\t\t\tcontext\n\t\t\t\t) ) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\t!context || rsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split( \"\" ).sort( sortOrder ).join( \"\" ) === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert( function( el ) {\n\n\t// Should return 1, but returns 4 (following)\n\treturn el.compareDocumentPosition( document.createElement( \"fieldset\" ) ) & 1;\n} );\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert( function( el ) {\n\tel.innerHTML = \"<a href='#'></a>\";\n\treturn el.firstChild.getAttribute( \"href\" ) === \"#\";\n} ) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t} );\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert( function( el ) {\n\tel.innerHTML = \"<input/>\";\n\tel.firstChild.setAttribute( \"value\", \"\" );\n\treturn el.firstChild.getAttribute( \"value\" ) === \"\";\n} ) ) {\n\taddHandle( \"value\", function( elem, _name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t} );\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert( function( el ) {\n\treturn el.getAttribute( \"disabled\" ) == null;\n} ) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t( val = elem.getAttributeNode( name ) ) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\t\tnull;\n\t\t}\n\t} );\n}\n\nreturn Sizzle;\n\n} )( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\n\n// Deprecated\njQuery.expr[ \":\" ] = jQuery.expr.pseudos;\njQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\njQuery.escapeSelector = Sizzle.escape;\n\n\n\n\nvar dir = function( elem, dir, until ) {\n\tvar matched = [],\n\t\ttruncate = until !== undefined;\n\n\twhile ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {\n\t\tif ( elem.nodeType === 1 ) {\n\t\t\tif ( truncate && jQuery( elem ).is( until ) ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmatched.push( elem );\n\t\t}\n\t}\n\treturn matched;\n};\n\n\nvar siblings = function( n, elem ) {\n\tvar matched = [];\n\n\tfor ( ; n; n = n.nextSibling ) {\n\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\tmatched.push( n );\n\t\t}\n\t}\n\n\treturn matched;\n};\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\n\n\nfunction nodeName( elem, name ) {\n\n  return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\n};\nvar rsingleTag = ( /^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i );\n\n\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t} );\n\t}\n\n\t// Single element\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t} );\n\t}\n\n\t// Arraylike of elements (jQuery, arguments, Array)\n\tif ( typeof qualifier !== \"string\" ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( indexOf.call( qualifier, elem ) > -1 ) !== not;\n\t\t} );\n\t}\n\n\t// Filtered directly for both simple and complex selectors\n\treturn jQuery.filter( qualifier, elements, not );\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\tif ( elems.length === 1 && elem.nodeType === 1 ) {\n\t\treturn jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];\n\t}\n\n\treturn jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\treturn elem.nodeType === 1;\n\t} ) );\n};\n\njQuery.fn.extend( {\n\tfind: function( selector ) {\n\t\tvar i, ret,\n\t\t\tlen = this.length,\n\t\t\tself = this;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter( function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} ) );\n\t\t}\n\n\t\tret = this.pushStack( [] );\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\treturn len > 1 ? jQuery.uniqueSort( ret ) : ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], false ) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], true ) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n} );\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\t// Shortcut simple #id case for speed\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/,\n\n\tinit = jQuery.fn.init = function( selector, context, root ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Method init() accepts an alternate rootjQuery\n\t\t// so migrate can support jQuery.sub (gh-2101)\n\t\troot = root || rootjQuery;\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector[ 0 ] === \"<\" &&\n\t\t\t\tselector[ selector.length - 1 ] === \">\" &&\n\t\t\t\tselector.length >= 3 ) {\n\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && ( match[ 1 ] || !context ) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[ 1 ] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[ 0 ] : context;\n\n\t\t\t\t\t// Option to run scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[ 1 ],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[ 2 ] );\n\n\t\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t\t// Inject the element directly into the jQuery object\n\t\t\t\t\t\tthis[ 0 ] = elem;\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || root ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis[ 0 ] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( isFunction( selector ) ) {\n\t\t\treturn root.ready !== undefined ?\n\t\t\t\troot.ready( selector ) :\n\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\n\t// Methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.fn.extend( {\n\thas: function( target ) {\n\t\tvar targets = jQuery( target, this ),\n\t\t\tl = targets.length;\n\n\t\treturn this.filter( function() {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[ i ] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\ttargets = typeof selectors !== \"string\" && jQuery( selectors );\n\n\t\t// Positional selectors never match, since there's no _selection_ context\n\t\tif ( !rneedsContext.test( selectors ) ) {\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tfor ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {\n\n\t\t\t\t\t// Always skip document fragments\n\t\t\t\t\tif ( cur.nodeType < 11 && ( targets ?\n\t\t\t\t\t\ttargets.index( cur ) > -1 :\n\n\t\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\t\tjQuery.find.matchesSelector( cur, selectors ) ) ) {\n\n\t\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within the set\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// Index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn indexOf.call( jQuery( elem ), this[ 0 ] );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn indexOf.call( this,\n\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[ 0 ] : elem\n\t\t);\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.uniqueSort(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter( selector )\n\t\t);\n\t}\n} );\n\nfunction sibling( cur, dir ) {\n\twhile ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}\n\treturn cur;\n}\n\njQuery.each( {\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, _i, until ) {\n\t\treturn dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, _i, until ) {\n\t\treturn dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, _i, until ) {\n\t\treturn dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn siblings( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn siblings( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\tif ( elem.contentDocument != null &&\n\n\t\t\t// Support: IE 11+\n\t\t\t// <object> elements with no `data` attribute has an object\n\t\t\t// `contentDocument` with a `null` prototype.\n\t\t\tgetProto( elem.contentDocument ) ) {\n\n\t\t\treturn elem.contentDocument;\n\t\t}\n\n\t\t// Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only\n\t\t// Treat the template element as a regular one in browsers that\n\t\t// don't support it.\n\t\tif ( nodeName( elem, \"template\" ) ) {\n\t\t\telem = elem.content || elem;\n\t\t}\n\n\t\treturn jQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar matched = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tmatched = jQuery.filter( selector, matched );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tjQuery.uniqueSort( matched );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tmatched.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched );\n\t};\n} );\nvar rnothtmlwhite = ( /[^\\x20\\t\\r\\n\\f]+/g );\n\n\n\n// Convert String-formatted options into Object-formatted ones\nfunction createOptions( options ) {\n\tvar object = {};\n\tjQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t} );\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\tcreateOptions( options ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\n\t\t// Last fire value for non-forgettable lists\n\t\tmemory,\n\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\n\t\t// Flag to prevent firing\n\t\tlocked,\n\n\t\t// Actual callback list\n\t\tlist = [],\n\n\t\t// Queue of execution data for repeatable lists\n\t\tqueue = [],\n\n\t\t// Index of currently firing callback (modified by add/remove as needed)\n\t\tfiringIndex = -1,\n\n\t\t// Fire callbacks\n\t\tfire = function() {\n\n\t\t\t// Enforce single-firing\n\t\t\tlocked = locked || options.once;\n\n\t\t\t// Execute callbacks for all pending executions,\n\t\t\t// respecting firingIndex overrides and runtime changes\n\t\t\tfired = firing = true;\n\t\t\tfor ( ; queue.length; firingIndex = -1 ) {\n\t\t\t\tmemory = queue.shift();\n\t\t\t\twhile ( ++firingIndex < list.length ) {\n\n\t\t\t\t\t// Run callback and check for early termination\n\t\t\t\t\tif ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&\n\t\t\t\t\t\toptions.stopOnFalse ) {\n\n\t\t\t\t\t\t// Jump to end and forget the data so .add doesn't re-fire\n\t\t\t\t\t\tfiringIndex = list.length;\n\t\t\t\t\t\tmemory = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Forget the data if we're done with it\n\t\t\tif ( !options.memory ) {\n\t\t\t\tmemory = false;\n\t\t\t}\n\n\t\t\tfiring = false;\n\n\t\t\t// Clean up if we're done firing for good\n\t\t\tif ( locked ) {\n\n\t\t\t\t// Keep an empty list if we have data for future add calls\n\t\t\t\tif ( memory ) {\n\t\t\t\t\tlist = [];\n\n\t\t\t\t// Otherwise, this object is spent\n\t\t\t\t} else {\n\t\t\t\t\tlist = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t// Actual Callbacks object\n\t\tself = {\n\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\n\t\t\t\t\t// If we have memory from a past run, we should fire after adding\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfiringIndex = list.length - 1;\n\t\t\t\t\t\tqueue.push( memory );\n\t\t\t\t\t}\n\n\t\t\t\t\t( function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tif ( isFunction( arg ) ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && toType( arg ) !== \"string\" ) {\n\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t} )( arguments );\n\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\tvar index;\n\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\tlist.splice( index, 1 );\n\n\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ?\n\t\t\t\t\tjQuery.inArray( fn, list ) > -1 :\n\t\t\t\t\tlist.length > 0;\n\t\t\t},\n\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Disable .fire and .add\n\t\t\t// Abort any current/pending executions\n\t\t\t// Clear all callbacks and values\n\t\t\tdisable: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tlist = memory = \"\";\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\n\t\t\t// Disable .fire\n\t\t\t// Also disable .add unless we have memory (since it would have no effect)\n\t\t\t// Abort any pending executions\n\t\t\tlock: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tif ( !memory && !firing ) {\n\t\t\t\t\tlist = memory = \"\";\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tlocked: function() {\n\t\t\t\treturn !!locked;\n\t\t\t},\n\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( !locked ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tqueue.push( args );\n\t\t\t\t\tif ( !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\nfunction Identity( v ) {\n\treturn v;\n}\nfunction Thrower( ex ) {\n\tthrow ex;\n}\n\nfunction adoptValue( value, resolve, reject, noValue ) {\n\tvar method;\n\n\ttry {\n\n\t\t// Check for promise aspect first to privilege synchronous behavior\n\t\tif ( value && isFunction( ( method = value.promise ) ) ) {\n\t\t\tmethod.call( value ).done( resolve ).fail( reject );\n\n\t\t// Other thenables\n\t\t} else if ( value && isFunction( ( method = value.then ) ) ) {\n\t\t\tmethod.call( value, resolve, reject );\n\n\t\t// Other non-thenables\n\t\t} else {\n\n\t\t\t// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:\n\t\t\t// * false: [ value ].slice( 0 ) => resolve( value )\n\t\t\t// * true: [ value ].slice( 1 ) => resolve()\n\t\t\tresolve.apply( undefined, [ value ].slice( noValue ) );\n\t\t}\n\n\t// For Promises/A+, convert exceptions into rejections\n\t// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in\n\t// Deferred#then to conditionally suppress rejection.\n\t} catch ( value ) {\n\n\t\t// Support: Android 4.0 only\n\t\t// Strict mode functions invoked without .call/.apply get global-object context\n\t\treject.apply( undefined, [ value ] );\n\t}\n}\n\njQuery.extend( {\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\n\t\t\t\t// action, add listener, callbacks,\n\t\t\t\t// ... .then handlers, argument index, [final state]\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks( \"memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"memory\" ), 2 ],\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 0, \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 1, \"rejected\" ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\t\"catch\": function( fn ) {\n\t\t\t\t\treturn promise.then( null, fn );\n\t\t\t\t},\n\n\t\t\t\t// Keep pipe for back-compat\n\t\t\t\tpipe: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( _i, tuple ) {\n\n\t\t\t\t\t\t\t// Map tuples (progress, done, fail) to arguments (done, fail, progress)\n\t\t\t\t\t\t\tvar fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];\n\n\t\t\t\t\t\t\t// deferred.progress(function() { bind to newDefer or newDefer.notify })\n\t\t\t\t\t\t\t// deferred.done(function() { bind to newDefer or newDefer.resolve })\n\t\t\t\t\t\t\t// deferred.fail(function() { bind to newDefer or newDefer.reject })\n\t\t\t\t\t\t\tdeferred[ tuple[ 1 ] ]( function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify )\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ](\n\t\t\t\t\t\t\t\t\t\tthis,\n\t\t\t\t\t\t\t\t\t\tfn ? [ returned ] : arguments\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} );\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\t\t\t\tthen: function( onFulfilled, onRejected, onProgress ) {\n\t\t\t\t\tvar maxDepth = 0;\n\t\t\t\t\tfunction resolve( depth, deferred, handler, special ) {\n\t\t\t\t\t\treturn function() {\n\t\t\t\t\t\t\tvar that = this,\n\t\t\t\t\t\t\t\targs = arguments,\n\t\t\t\t\t\t\t\tmightThrow = function() {\n\t\t\t\t\t\t\t\t\tvar returned, then;\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.3\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-59\n\t\t\t\t\t\t\t\t\t// Ignore double-resolution attempts\n\t\t\t\t\t\t\t\t\tif ( depth < maxDepth ) {\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturned = handler.apply( that, args );\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.1\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-48\n\t\t\t\t\t\t\t\t\tif ( returned === deferred.promise() ) {\n\t\t\t\t\t\t\t\t\t\tthrow new TypeError( \"Thenable self-resolution\" );\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ sections 2.3.3.1, 3.5\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-54\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-75\n\t\t\t\t\t\t\t\t\t// Retrieve `then` only once\n\t\t\t\t\t\t\t\t\tthen = returned &&\n\n\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.4\n\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-64\n\t\t\t\t\t\t\t\t\t\t// Only check objects and functions for thenability\n\t\t\t\t\t\t\t\t\t\t( typeof returned === \"object\" ||\n\t\t\t\t\t\t\t\t\t\t\ttypeof returned === \"function\" ) &&\n\t\t\t\t\t\t\t\t\t\treturned.then;\n\n\t\t\t\t\t\t\t\t\t// Handle a returned thenable\n\t\t\t\t\t\t\t\t\tif ( isFunction( then ) ) {\n\n\t\t\t\t\t\t\t\t\t\t// Special processors (notify) just wait for resolution\n\t\t\t\t\t\t\t\t\t\tif ( special ) {\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special )\n\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t// Normal processors (resolve) also hook into progress\n\t\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t\t// ...and disregard older resolution values\n\t\t\t\t\t\t\t\t\t\t\tmaxDepth++;\n\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity,\n\t\t\t\t\t\t\t\t\t\t\t\t\tdeferred.notifyWith )\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Handle all other returned values\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\tif ( handler !== Identity ) {\n\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\targs = [ returned ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t// Process the value(s)\n\t\t\t\t\t\t\t\t\t\t// Default process is resolve\n\t\t\t\t\t\t\t\t\t\t( special || deferred.resolveWith )( that, args );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\n\t\t\t\t\t\t\t\t// Only normal processors (resolve) catch and reject exceptions\n\t\t\t\t\t\t\t\tprocess = special ?\n\t\t\t\t\t\t\t\t\tmightThrow :\n\t\t\t\t\t\t\t\t\tfunction() {\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tmightThrow();\n\t\t\t\t\t\t\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t\t\t\t\t\t\tif ( jQuery.Deferred.exceptionHook ) {\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery.Deferred.exceptionHook( e,\n\t\t\t\t\t\t\t\t\t\t\t\t\tprocess.stackTrace );\n\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.4.1\n\t\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-61\n\t\t\t\t\t\t\t\t\t\t\t// Ignore post-resolution exceptions\n\t\t\t\t\t\t\t\t\t\t\tif ( depth + 1 >= maxDepth ) {\n\n\t\t\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\t\t\tif ( handler !== Thrower ) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\t\t\targs = [ e ];\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t\tdeferred.rejectWith( that, args );\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.1\n\t\t\t\t\t\t\t// https://promisesaplus.com/#point-57\n\t\t\t\t\t\t\t// Re-resolve promises immediately to dodge false rejection from\n\t\t\t\t\t\t\t// subsequent errors\n\t\t\t\t\t\t\tif ( depth ) {\n\t\t\t\t\t\t\t\tprocess();\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// Call an optional hook to record the stack, in case of exception\n\t\t\t\t\t\t\t\t// since it's otherwise lost when execution goes async\n\t\t\t\t\t\t\t\tif ( jQuery.Deferred.getStackHook ) {\n\t\t\t\t\t\t\t\t\tprocess.stackTrace = jQuery.Deferred.getStackHook();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\twindow.setTimeout( process );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\n\t\t\t\t\t\t// progress_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 0 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onProgress ) ?\n\t\t\t\t\t\t\t\t\tonProgress :\n\t\t\t\t\t\t\t\t\tIdentity,\n\t\t\t\t\t\t\t\tnewDefer.notifyWith\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// fulfilled_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 1 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onFulfilled ) ?\n\t\t\t\t\t\t\t\t\tonFulfilled :\n\t\t\t\t\t\t\t\t\tIdentity\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// rejected_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 2 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onRejected ) ?\n\t\t\t\t\t\t\t\t\tonRejected :\n\t\t\t\t\t\t\t\t\tThrower\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 5 ];\n\n\t\t\t// promise.progress = list.add\n\t\t\t// promise.done = list.add\n\t\t\t// promise.fail = list.add\n\t\t\tpromise[ tuple[ 1 ] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(\n\t\t\t\t\tfunction() {\n\n\t\t\t\t\t\t// state = \"resolved\" (i.e., fulfilled)\n\t\t\t\t\t\t// state = \"rejected\"\n\t\t\t\t\t\tstate = stateString;\n\t\t\t\t\t},\n\n\t\t\t\t\t// rejected_callbacks.disable\n\t\t\t\t\t// fulfilled_callbacks.disable\n\t\t\t\t\ttuples[ 3 - i ][ 2 ].disable,\n\n\t\t\t\t\t// rejected_handlers.disable\n\t\t\t\t\t// fulfilled_handlers.disable\n\t\t\t\t\ttuples[ 3 - i ][ 3 ].disable,\n\n\t\t\t\t\t// progress_callbacks.lock\n\t\t\t\t\ttuples[ 0 ][ 2 ].lock,\n\n\t\t\t\t\t// progress_handlers.lock\n\t\t\t\t\ttuples[ 0 ][ 3 ].lock\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// progress_handlers.fire\n\t\t\t// fulfilled_handlers.fire\n\t\t\t// rejected_handlers.fire\n\t\t\tlist.add( tuple[ 3 ].fire );\n\n\t\t\t// deferred.notify = function() { deferred.notifyWith(...) }\n\t\t\t// deferred.resolve = function() { deferred.resolveWith(...) }\n\t\t\t// deferred.reject = function() { deferred.rejectWith(...) }\n\t\t\tdeferred[ tuple[ 0 ] ] = function() {\n\t\t\t\tdeferred[ tuple[ 0 ] + \"With\" ]( this === deferred ? undefined : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\n\t\t\t// deferred.notifyWith = list.fireWith\n\t\t\t// deferred.resolveWith = list.fireWith\n\t\t\t// deferred.rejectWith = list.fireWith\n\t\t\tdeferred[ tuple[ 0 ] + \"With\" ] = list.fireWith;\n\t\t} );\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( singleValue ) {\n\t\tvar\n\n\t\t\t// count of uncompleted subordinates\n\t\t\tremaining = arguments.length,\n\n\t\t\t// count of unprocessed arguments\n\t\t\ti = remaining,\n\n\t\t\t// subordinate fulfillment data\n\t\t\tresolveContexts = Array( i ),\n\t\t\tresolveValues = slice.call( arguments ),\n\n\t\t\t// the master Deferred\n\t\t\tmaster = jQuery.Deferred(),\n\n\t\t\t// subordinate callback factory\n\t\t\tupdateFunc = function( i ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tresolveContexts[ i ] = this;\n\t\t\t\t\tresolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( !( --remaining ) ) {\n\t\t\t\t\t\tmaster.resolveWith( resolveContexts, resolveValues );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t};\n\n\t\t// Single- and empty arguments are adopted like Promise.resolve\n\t\tif ( remaining <= 1 ) {\n\t\t\tadoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,\n\t\t\t\t!remaining );\n\n\t\t\t// Use .then() to unwrap secondary thenables (cf. gh-3000)\n\t\t\tif ( master.state() === \"pending\" ||\n\t\t\t\tisFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {\n\n\t\t\t\treturn master.then();\n\t\t\t}\n\t\t}\n\n\t\t// Multiple arguments are aggregated like Promise.all array elements\n\t\twhile ( i-- ) {\n\t\t\tadoptValue( resolveValues[ i ], updateFunc( i ), master.reject );\n\t\t}\n\n\t\treturn master.promise();\n\t}\n} );\n\n\n// These usually indicate a programmer mistake during development,\n// warn about them ASAP rather than swallowing them by default.\nvar rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;\n\njQuery.Deferred.exceptionHook = function( error, stack ) {\n\n\t// Support: IE 8 - 9 only\n\t// Console exists when dev tools are open, which can happen at any time\n\tif ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {\n\t\twindow.console.warn( \"jQuery.Deferred exception: \" + error.message, error.stack, stack );\n\t}\n};\n\n\n\n\njQuery.readyException = function( error ) {\n\twindow.setTimeout( function() {\n\t\tthrow error;\n\t} );\n};\n\n\n\n\n// The deferred used on DOM ready\nvar readyList = jQuery.Deferred();\n\njQuery.fn.ready = function( fn ) {\n\n\treadyList\n\t\t.then( fn )\n\n\t\t// Wrap jQuery.readyException in a function so that the lookup\n\t\t// happens at the time of error handling instead of callback\n\t\t// registration.\n\t\t.catch( function( error ) {\n\t\t\tjQuery.readyException( error );\n\t\t} );\n\n\treturn this;\n};\n\njQuery.extend( {\n\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\t}\n} );\n\njQuery.ready.then = readyList.then;\n\n// The ready event handler and self cleanup method\nfunction completed() {\n\tdocument.removeEventListener( \"DOMContentLoaded\", completed );\n\twindow.removeEventListener( \"load\", completed );\n\tjQuery.ready();\n}\n\n// Catch cases where $(document).ready() is called\n// after the browser event has already occurred.\n// Support: IE <=9 - 10 only\n// Older IE sometimes signals \"interactive\" too soon\nif ( document.readyState === \"complete\" ||\n\t( document.readyState !== \"loading\" && !document.documentElement.doScroll ) ) {\n\n\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\twindow.setTimeout( jQuery.ready );\n\n} else {\n\n\t// Use the handy event callback\n\tdocument.addEventListener( \"DOMContentLoaded\", completed );\n\n\t// A fallback to window.onload, that will always work\n\twindow.addEventListener( \"load\", completed );\n}\n\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlen = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( toType( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\taccess( elems, fn, i, key[ i ], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, _key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\tfn(\n\t\t\t\t\telems[ i ], key, raw ?\n\t\t\t\t\tvalue :\n\t\t\t\t\tvalue.call( elems[ i ], i, fn( elems[ i ], key ) )\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( chainable ) {\n\t\treturn elems;\n\t}\n\n\t// Gets\n\tif ( bulk ) {\n\t\treturn fn.call( elems );\n\t}\n\n\treturn len ? fn( elems[ 0 ], key ) : emptyGet;\n};\n\n\n// Matches dashed string for camelizing\nvar rmsPrefix = /^-ms-/,\n\trdashAlpha = /-([a-z])/g;\n\n// Used by camelCase as callback to replace()\nfunction fcamelCase( _all, letter ) {\n\treturn letter.toUpperCase();\n}\n\n// Convert dashed to camelCase; used by the css and data modules\n// Support: IE <=9 - 11, Edge 12 - 15\n// Microsoft forgot to hump their vendor prefix (#9572)\nfunction camelCase( string ) {\n\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n}\nvar acceptData = function( owner ) {\n\n\t// Accepts only:\n\t//  - Node\n\t//    - Node.ELEMENT_NODE\n\t//    - Node.DOCUMENT_NODE\n\t//  - Object\n\t//    - Any\n\treturn owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );\n};\n\n\n\n\nfunction Data() {\n\tthis.expando = jQuery.expando + Data.uid++;\n}\n\nData.uid = 1;\n\nData.prototype = {\n\n\tcache: function( owner ) {\n\n\t\t// Check if the owner object already has a cache\n\t\tvar value = owner[ this.expando ];\n\n\t\t// If not, create one\n\t\tif ( !value ) {\n\t\t\tvalue = {};\n\n\t\t\t// We can accept data for non-element nodes in modern browsers,\n\t\t\t// but we should not, see #8335.\n\t\t\t// Always return an empty object.\n\t\t\tif ( acceptData( owner ) ) {\n\n\t\t\t\t// If it is a node unlikely to be stringify-ed or looped over\n\t\t\t\t// use plain assignment\n\t\t\t\tif ( owner.nodeType ) {\n\t\t\t\t\towner[ this.expando ] = value;\n\n\t\t\t\t// Otherwise secure it in a non-enumerable property\n\t\t\t\t// configurable must be true to allow the property to be\n\t\t\t\t// deleted when data is removed\n\t\t\t\t} else {\n\t\t\t\t\tObject.defineProperty( owner, this.expando, {\n\t\t\t\t\t\tvalue: value,\n\t\t\t\t\t\tconfigurable: true\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn value;\n\t},\n\tset: function( owner, data, value ) {\n\t\tvar prop,\n\t\t\tcache = this.cache( owner );\n\n\t\t// Handle: [ owner, key, value ] args\n\t\t// Always use camelCase key (gh-2257)\n\t\tif ( typeof data === \"string\" ) {\n\t\t\tcache[ camelCase( data ) ] = value;\n\n\t\t// Handle: [ owner, { properties } ] args\n\t\t} else {\n\n\t\t\t// Copy the properties one-by-one to the cache object\n\t\t\tfor ( prop in data ) {\n\t\t\t\tcache[ camelCase( prop ) ] = data[ prop ];\n\t\t\t}\n\t\t}\n\t\treturn cache;\n\t},\n\tget: function( owner, key ) {\n\t\treturn key === undefined ?\n\t\t\tthis.cache( owner ) :\n\n\t\t\t// Always use camelCase key (gh-2257)\n\t\t\towner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];\n\t},\n\taccess: function( owner, key, value ) {\n\n\t\t// In cases where either:\n\t\t//\n\t\t//   1. No key was specified\n\t\t//   2. A string key was specified, but no value provided\n\t\t//\n\t\t// Take the \"read\" path and allow the get method to determine\n\t\t// which value to return, respectively either:\n\t\t//\n\t\t//   1. The entire cache object\n\t\t//   2. The data stored at the key\n\t\t//\n\t\tif ( key === undefined ||\n\t\t\t\t( ( key && typeof key === \"string\" ) && value === undefined ) ) {\n\n\t\t\treturn this.get( owner, key );\n\t\t}\n\n\t\t// When the key is not a string, or both a key and value\n\t\t// are specified, set or extend (existing objects) with either:\n\t\t//\n\t\t//   1. An object of properties\n\t\t//   2. A key and value\n\t\t//\n\t\tthis.set( owner, key, value );\n\n\t\t// Since the \"set\" path can have two possible entry points\n\t\t// return the expected data based on which path was taken[*]\n\t\treturn value !== undefined ? value : key;\n\t},\n\tremove: function( owner, key ) {\n\t\tvar i,\n\t\t\tcache = owner[ this.expando ];\n\n\t\tif ( cache === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key !== undefined ) {\n\n\t\t\t// Support array or space separated string of keys\n\t\t\tif ( Array.isArray( key ) ) {\n\n\t\t\t\t// If key is an array of keys...\n\t\t\t\t// We always set camelCase keys, so remove that.\n\t\t\t\tkey = key.map( camelCase );\n\t\t\t} else {\n\t\t\t\tkey = camelCase( key );\n\n\t\t\t\t// If a key with the spaces exists, use it.\n\t\t\t\t// Otherwise, create an array by matching non-whitespace\n\t\t\t\tkey = key in cache ?\n\t\t\t\t\t[ key ] :\n\t\t\t\t\t( key.match( rnothtmlwhite ) || [] );\n\t\t\t}\n\n\t\t\ti = key.length;\n\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete cache[ key[ i ] ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if there's no more data\n\t\tif ( key === undefined || jQuery.isEmptyObject( cache ) ) {\n\n\t\t\t// Support: Chrome <=35 - 45\n\t\t\t// Webkit & Blink performance suffers when deleting properties\n\t\t\t// from DOM nodes, so set to undefined instead\n\t\t\t// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)\n\t\t\tif ( owner.nodeType ) {\n\t\t\t\towner[ this.expando ] = undefined;\n\t\t\t} else {\n\t\t\t\tdelete owner[ this.expando ];\n\t\t\t}\n\t\t}\n\t},\n\thasData: function( owner ) {\n\t\tvar cache = owner[ this.expando ];\n\t\treturn cache !== undefined && !jQuery.isEmptyObject( cache );\n\t}\n};\nvar dataPriv = new Data();\n\nvar dataUser = new Data();\n\n\n\n//\tImplementation Summary\n//\n//\t1. Enforce API surface and semantic compatibility with 1.9.x branch\n//\t2. Improve the module's maintainability by reducing the storage\n//\t\tpaths to a single mechanism.\n//\t3. Use the same single mechanism to support \"private\" and \"user\" data.\n//\t4. _Never_ expose \"private\" data to user code (TODO: Drop _data, _removeData)\n//\t5. Avoid exposing implementation details on user objects (eg. expando properties)\n//\t6. Provide a clear path for implementation upgrade to WeakMap in 2014\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /[A-Z]/g;\n\nfunction getData( data ) {\n\tif ( data === \"true\" ) {\n\t\treturn true;\n\t}\n\n\tif ( data === \"false\" ) {\n\t\treturn false;\n\t}\n\n\tif ( data === \"null\" ) {\n\t\treturn null;\n\t}\n\n\t// Only convert to a number if it doesn't change the string\n\tif ( data === +data + \"\" ) {\n\t\treturn +data;\n\t}\n\n\tif ( rbrace.test( data ) ) {\n\t\treturn JSON.parse( data );\n\t}\n\n\treturn data;\n}\n\nfunction dataAttr( elem, key, data ) {\n\tvar name;\n\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\t\tname = \"data-\" + key.replace( rmultiDash, \"-$&\" ).toLowerCase();\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = getData( data );\n\t\t\t} catch ( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tdataUser.set( elem, key, data );\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\treturn data;\n}\n\njQuery.extend( {\n\thasData: function( elem ) {\n\t\treturn dataUser.hasData( elem ) || dataPriv.hasData( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn dataUser.access( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\tdataUser.remove( elem, name );\n\t},\n\n\t// TODO: Now that all calls to _data and _removeData have been replaced\n\t// with direct calls to dataPriv methods, these can be deprecated.\n\t_data: function( elem, name, data ) {\n\t\treturn dataPriv.access( elem, name, data );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\tdataPriv.remove( elem, name );\n\t}\n} );\n\njQuery.fn.extend( {\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[ 0 ],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = dataUser.get( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !dataPriv.get( elem, \"hasDataAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE 11 only\n\t\t\t\t\t\t// The attrs elements can be null (#14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = camelCase( name.slice( 5 ) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdataPriv.set( elem, \"hasDataAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each( function() {\n\t\t\t\tdataUser.set( this, key );\n\t\t\t} );\n\t\t}\n\n\t\treturn access( this, function( value ) {\n\t\t\tvar data;\n\n\t\t\t// The calling jQuery object (element matches) is not empty\n\t\t\t// (and therefore has an element appears at this[ 0 ]) and the\n\t\t\t// `value` parameter was not undefined. An empty jQuery object\n\t\t\t// will result in `undefined` for elem = this[ 0 ] which will\n\t\t\t// throw an exception if an attempt to read a data cache is made.\n\t\t\tif ( elem && value === undefined ) {\n\n\t\t\t\t// Attempt to get data from the cache\n\t\t\t\t// The key will always be camelCased in Data\n\t\t\t\tdata = dataUser.get( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// Attempt to \"discover\" the data in\n\t\t\t\t// HTML5 custom data-* attrs\n\t\t\t\tdata = dataAttr( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// We tried really hard, but the data doesn't exist.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Set the data...\n\t\t\tthis.each( function() {\n\n\t\t\t\t// We always store the camelCased key\n\t\t\t\tdataUser.set( this, key, value );\n\t\t\t} );\n\t\t}, null, value, arguments.length > 1, null, true );\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each( function() {\n\t\t\tdataUser.remove( this, key );\n\t\t} );\n\t}\n} );\n\n\njQuery.extend( {\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = dataPriv.get( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || Array.isArray( data ) ) {\n\t\t\t\t\tqueue = dataPriv.access( elem, type, jQuery.makeArray( data ) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// Clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// Not public - generate a queueHooks object, or return the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn dataPriv.get( elem, key ) || dataPriv.access( elem, key, {\n\t\t\tempty: jQuery.Callbacks( \"once memory\" ).add( function() {\n\t\t\t\tdataPriv.remove( elem, [ type + \"queue\", key ] );\n\t\t\t} )\n\t\t} );\n\t}\n} );\n\njQuery.fn.extend( {\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[ 0 ], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each( function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// Ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[ 0 ] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t} );\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t} );\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = dataPriv.get( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n} );\nvar pnum = ( /[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/ ).source;\n\nvar rcssNum = new RegExp( \"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\" );\n\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar documentElement = document.documentElement;\n\n\n\n\tvar isAttached = function( elem ) {\n\t\t\treturn jQuery.contains( elem.ownerDocument, elem );\n\t\t},\n\t\tcomposed = { composed: true };\n\n\t// Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only\n\t// Check attachment across shadow DOM boundaries when possible (gh-3504)\n\t// Support: iOS 10.0-10.2 only\n\t// Early iOS 10 versions support `attachShadow` but not `getRootNode`,\n\t// leading to errors. We need to check for `getRootNode`.\n\tif ( documentElement.getRootNode ) {\n\t\tisAttached = function( elem ) {\n\t\t\treturn jQuery.contains( elem.ownerDocument, elem ) ||\n\t\t\t\telem.getRootNode( composed ) === elem.ownerDocument;\n\t\t};\n\t}\nvar isHiddenWithinTree = function( elem, el ) {\n\n\t\t// isHiddenWithinTree might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\n\t\t// Inline style trumps all\n\t\treturn elem.style.display === \"none\" ||\n\t\t\telem.style.display === \"\" &&\n\n\t\t\t// Otherwise, check computed style\n\t\t\t// Support: Firefox <=43 - 45\n\t\t\t// Disconnected elements can have computed display: none, so first confirm that elem is\n\t\t\t// in the document.\n\t\t\tisAttached( elem ) &&\n\n\t\t\tjQuery.css( elem, \"display\" ) === \"none\";\n\t};\n\n\n\nfunction adjustCSS( elem, prop, valueParts, tween ) {\n\tvar adjusted, scale,\n\t\tmaxIterations = 20,\n\t\tcurrentValue = tween ?\n\t\t\tfunction() {\n\t\t\t\treturn tween.cur();\n\t\t\t} :\n\t\t\tfunction() {\n\t\t\t\treturn jQuery.css( elem, prop, \"\" );\n\t\t\t},\n\t\tinitial = currentValue(),\n\t\tunit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n\t\t// Starting value computation is required for potential unit mismatches\n\t\tinitialInUnit = elem.nodeType &&\n\t\t\t( jQuery.cssNumber[ prop ] || unit !== \"px\" && +initial ) &&\n\t\t\trcssNum.exec( jQuery.css( elem, prop ) );\n\n\tif ( initialInUnit && initialInUnit[ 3 ] !== unit ) {\n\n\t\t// Support: Firefox <=54\n\t\t// Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)\n\t\tinitial = initial / 2;\n\n\t\t// Trust units reported by jQuery.css\n\t\tunit = unit || initialInUnit[ 3 ];\n\n\t\t// Iteratively approximate from a nonzero starting point\n\t\tinitialInUnit = +initial || 1;\n\n\t\twhile ( maxIterations-- ) {\n\n\t\t\t// Evaluate and update our best guess (doubling guesses that zero out).\n\t\t\t// Finish if the scale equals or crosses 1 (making the old*new product non-positive).\n\t\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\t\t\tif ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {\n\t\t\t\tmaxIterations = 0;\n\t\t\t}\n\t\t\tinitialInUnit = initialInUnit / scale;\n\n\t\t}\n\n\t\tinitialInUnit = initialInUnit * 2;\n\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\n\t\t// Make sure we update the tween properties later on\n\t\tvalueParts = valueParts || [];\n\t}\n\n\tif ( valueParts ) {\n\t\tinitialInUnit = +initialInUnit || +initial || 0;\n\n\t\t// Apply relative offset (+=/-=) if specified\n\t\tadjusted = valueParts[ 1 ] ?\n\t\t\tinitialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :\n\t\t\t+valueParts[ 2 ];\n\t\tif ( tween ) {\n\t\t\ttween.unit = unit;\n\t\t\ttween.start = initialInUnit;\n\t\t\ttween.end = adjusted;\n\t\t}\n\t}\n\treturn adjusted;\n}\n\n\nvar defaultDisplayMap = {};\n\nfunction getDefaultDisplay( elem ) {\n\tvar temp,\n\t\tdoc = elem.ownerDocument,\n\t\tnodeName = elem.nodeName,\n\t\tdisplay = defaultDisplayMap[ nodeName ];\n\n\tif ( display ) {\n\t\treturn display;\n\t}\n\n\ttemp = doc.body.appendChild( doc.createElement( nodeName ) );\n\tdisplay = jQuery.css( temp, \"display\" );\n\n\ttemp.parentNode.removeChild( temp );\n\n\tif ( display === \"none\" ) {\n\t\tdisplay = \"block\";\n\t}\n\tdefaultDisplayMap[ nodeName ] = display;\n\n\treturn display;\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\t// Determine new display value for elements that need to change\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\n\t\t\t// Since we force visibility upon cascade-hidden elements, an immediate (and slow)\n\t\t\t// check is required in this first loop unless we have a nonempty display value (either\n\t\t\t// inline or about-to-be-restored)\n\t\t\tif ( display === \"none\" ) {\n\t\t\t\tvalues[ index ] = dataPriv.get( elem, \"display\" ) || null;\n\t\t\t\tif ( !values[ index ] ) {\n\t\t\t\t\telem.style.display = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( elem.style.display === \"\" && isHiddenWithinTree( elem ) ) {\n\t\t\t\tvalues[ index ] = getDefaultDisplay( elem );\n\t\t\t}\n\t\t} else {\n\t\t\tif ( display !== \"none\" ) {\n\t\t\t\tvalues[ index ] = \"none\";\n\n\t\t\t\t// Remember what we're overwriting\n\t\t\t\tdataPriv.set( elem, \"display\", display );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of the elements in a second loop to avoid constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\tif ( values[ index ] != null ) {\n\t\t\telements[ index ].style.display = values[ index ];\n\t\t}\n\t}\n\n\treturn elements;\n}\n\njQuery.fn.extend( {\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tif ( isHiddenWithinTree( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t} );\n\t}\n} );\nvar rcheckableType = ( /^(?:checkbox|radio)$/i );\n\nvar rtagName = ( /<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)/i );\n\nvar rscriptType = ( /^$|^module$|\\/(?:java|ecma)script/i );\n\n\n\n( function() {\n\tvar fragment = document.createDocumentFragment(),\n\t\tdiv = fragment.appendChild( document.createElement( \"div\" ) ),\n\t\tinput = document.createElement( \"input\" );\n\n\t// Support: Android 4.0 - 4.3 only\n\t// Check state lost if the name is set (#11217)\n\t// Support: Windows Web Apps (WWA)\n\t// `name` and `type` must use .setAttribute for WWA (#14901)\n\tinput.setAttribute( \"type\", \"radio\" );\n\tinput.setAttribute( \"checked\", \"checked\" );\n\tinput.setAttribute( \"name\", \"t\" );\n\n\tdiv.appendChild( input );\n\n\t// Support: Android <=4.1 only\n\t// Older WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE <=11 only\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\tdiv.innerHTML = \"<textarea>x</textarea>\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n\n\t// Support: IE <=9 only\n\t// IE <=9 replaces <option> tags with their contents when inserted outside of\n\t// the select element.\n\tdiv.innerHTML = \"<option></option>\";\n\tsupport.option = !!div.lastChild;\n} )();\n\n\n// We have to close these tags to support XHTML (#13200)\nvar wrapMap = {\n\n\t// XHTML parsers do not magically insert elements in the\n\t// same way that tag soup parsers do. So we cannot shorten\n\t// this by omitting <tbody> or other required elements.\n\tthead: [ 1, \"<table>\", \"</table>\" ],\n\tcol: [ 2, \"<table><colgroup>\", \"</colgroup></table>\" ],\n\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\n\t_default: [ 0, \"\", \"\" ]\n};\n\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n// Support: IE <=9 only\nif ( !support.option ) {\n\twrapMap.optgroup = wrapMap.option = [ 1, \"<select multiple='multiple'>\", \"</select>\" ];\n}\n\n\nfunction getAll( context, tag ) {\n\n\t// Support: IE <=9 - 11 only\n\t// Use typeof to avoid zero-argument method invocation on host objects (#15151)\n\tvar ret;\n\n\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\tret = context.getElementsByTagName( tag || \"*\" );\n\n\t} else if ( typeof context.querySelectorAll !== \"undefined\" ) {\n\t\tret = context.querySelectorAll( tag || \"*\" );\n\n\t} else {\n\t\tret = [];\n\t}\n\n\tif ( tag === undefined || tag && nodeName( context, tag ) ) {\n\t\treturn jQuery.merge( [ context ], ret );\n\t}\n\n\treturn ret;\n}\n\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar i = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\tdataPriv.set(\n\t\t\telems[ i ],\n\t\t\t\"globalEval\",\n\t\t\t!refElements || dataPriv.get( refElements[ i ], \"globalEval\" )\n\t\t);\n\t}\n}\n\n\nvar rhtml = /<|&#?\\w+;/;\n\nfunction buildFragment( elems, context, scripts, selection, ignored ) {\n\tvar elem, tmp, tag, wrap, attached, j,\n\t\tfragment = context.createDocumentFragment(),\n\t\tnodes = [],\n\t\ti = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\telem = elems[ i ];\n\n\t\tif ( elem || elem === 0 ) {\n\n\t\t\t// Add nodes directly\n\t\t\tif ( toType( elem ) === \"object\" ) {\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t// Convert non-html into a text node\n\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t// Convert html into DOM nodes\n\t\t\t} else {\n\t\t\t\ttmp = tmp || fragment.appendChild( context.createElement( \"div\" ) );\n\n\t\t\t\t// Deserialize a standard representation\n\t\t\t\ttag = ( rtagName.exec( elem ) || [ \"\", \"\" ] )[ 1 ].toLowerCase();\n\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\t\t\t\ttmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];\n\n\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\tj = wrap[ 0 ];\n\t\t\t\twhile ( j-- ) {\n\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t}\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t// Remember the top-level container\n\t\t\t\ttmp = fragment.firstChild;\n\n\t\t\t\t// Ensure the created nodes are orphaned (#12392)\n\t\t\t\ttmp.textContent = \"\";\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove wrapper from fragment\n\tfragment.textContent = \"\";\n\n\ti = 0;\n\twhile ( ( elem = nodes[ i++ ] ) ) {\n\n\t\t// Skip elements already in the context collection (trac-4087)\n\t\tif ( selection && jQuery.inArray( elem, selection ) > -1 ) {\n\t\t\tif ( ignored ) {\n\t\t\t\tignored.push( elem );\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tattached = isAttached( elem );\n\n\t\t// Append to fragment\n\t\ttmp = getAll( fragment.appendChild( elem ), \"script\" );\n\n\t\t// Preserve script evaluation history\n\t\tif ( attached ) {\n\t\t\tsetGlobalEval( tmp );\n\t\t}\n\n\t\t// Capture executables\n\t\tif ( scripts ) {\n\t\t\tj = 0;\n\t\t\twhile ( ( elem = tmp[ j++ ] ) ) {\n\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\tscripts.push( elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fragment;\n}\n\n\nvar\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\n// Support: IE <=9 - 11+\n// focus() and blur() are asynchronous, except when they are no-op.\n// So expect focus to be synchronous when the element is already active,\n// and blur to be synchronous when the element is not already active.\n// (focus and blur are always synchronous in other supported browsers,\n// this just defines when we can count on it).\nfunction expectSync( elem, type ) {\n\treturn ( elem === safeActiveElement() ) === ( type === \"focus\" );\n}\n\n// Support: IE <=9 only\n// Accessing document.activeElement can throw unexpectedly\n// https://bugs.jquery.com/ticket/13393\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\nfunction on( elem, types, selector, data, fn, one ) {\n\tvar origFn, type;\n\n\t// Types can be a map of types/handlers\n\tif ( typeof types === \"object\" ) {\n\n\t\t// ( types-Object, selector, data )\n\t\tif ( typeof selector !== \"string\" ) {\n\n\t\t\t// ( types-Object, data )\n\t\t\tdata = data || selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tfor ( type in types ) {\n\t\t\ton( elem, type, selector, data, types[ type ], one );\n\t\t}\n\t\treturn elem;\n\t}\n\n\tif ( data == null && fn == null ) {\n\n\t\t// ( types, fn )\n\t\tfn = selector;\n\t\tdata = selector = undefined;\n\t} else if ( fn == null ) {\n\t\tif ( typeof selector === \"string\" ) {\n\n\t\t\t// ( types, selector, fn )\n\t\t\tfn = data;\n\t\t\tdata = undefined;\n\t\t} else {\n\n\t\t\t// ( types, data, fn )\n\t\t\tfn = data;\n\t\t\tdata = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t}\n\tif ( fn === false ) {\n\t\tfn = returnFalse;\n\t} else if ( !fn ) {\n\t\treturn elem;\n\t}\n\n\tif ( one === 1 ) {\n\t\torigFn = fn;\n\t\tfn = function( event ) {\n\n\t\t\t// Can use an empty set, since event contains the info\n\t\t\tjQuery().off( event );\n\t\t\treturn origFn.apply( this, arguments );\n\t\t};\n\n\t\t// Use same guid so caller can remove using origFn\n\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t}\n\treturn elem.each( function() {\n\t\tjQuery.event.add( this, types, fn, data, selector );\n\t} );\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\n\t\tvar handleObjIn, eventHandle, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.get( elem );\n\n\t\t// Only attach events to objects that accept data\n\t\tif ( !acceptData( elem ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Ensure that invalid selectors throw exceptions at attach time\n\t\t// Evaluate against documentElement in case elem is a non-element node (e.g., document)\n\t\tif ( selector ) {\n\t\t\tjQuery.find.matchesSelector( documentElement, selector );\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !( events = elemData.events ) ) {\n\t\t\tevents = elemData.events = Object.create( null );\n\t\t}\n\t\tif ( !( eventHandle = elemData.handle ) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== \"undefined\" && jQuery.event.triggered !== e.type ?\n\t\t\t\t\tjQuery.event.dispatch.apply( elem, arguments ) : undefined;\n\t\t\t};\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend( {\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join( \".\" )\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !( handlers = events[ type ] ) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener if the special events handler returns false\n\t\t\t\tif ( !special.setup ||\n\t\t\t\t\tspecial.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\n\t\tvar j, origCount, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.hasData( elem ) && dataPriv.get( elem );\n\n\t\tif ( !elemData || !( events = elemData.events ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[ 2 ] &&\n\t\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector ||\n\t\t\t\t\t\tselector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown ||\n\t\t\t\t\tspecial.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove data and the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdataPriv.remove( elem, \"handle events\" );\n\t\t}\n\t},\n\n\tdispatch: function( nativeEvent ) {\n\n\t\tvar i, j, ret, matched, handleObj, handlerQueue,\n\t\t\targs = new Array( arguments.length ),\n\n\t\t\t// Make a writable jQuery.Event from the native event object\n\t\t\tevent = jQuery.event.fix( nativeEvent ),\n\n\t\t\thandlers = (\n\t\t\t\t\tdataPriv.get( this, \"events\" ) || Object.create( null )\n\t\t\t\t)[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[ 0 ] = event;\n\n\t\tfor ( i = 1; i < arguments.length; i++ ) {\n\t\t\targs[ i ] = arguments[ i ];\n\t\t}\n\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( ( handleObj = matched.handlers[ j++ ] ) &&\n\t\t\t\t!event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// If the event is namespaced, then each handler is only invoked if it is\n\t\t\t\t// specially universal or its namespaces are a superset of the event's.\n\t\t\t\tif ( !event.rnamespace || handleObj.namespace === false ||\n\t\t\t\t\tevent.rnamespace.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||\n\t\t\t\t\t\thandleObj.handler ).apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( ( event.result = ret ) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar i, handleObj, sel, matchedHandlers, matchedSelectors,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\tif ( delegateCount &&\n\n\t\t\t// Support: IE <=9\n\t\t\t// Black-hole SVG <use> instance trees (trac-13180)\n\t\t\tcur.nodeType &&\n\n\t\t\t// Support: Firefox <=42\n\t\t\t// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)\n\t\t\t// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click\n\t\t\t// Support: IE 11 only\n\t\t\t// ...but not arrow key \"clicks\" of radio inputs, which can have `button` -1 (gh-2343)\n\t\t\t!( event.type === \"click\" && event.button >= 1 ) ) {\n\n\t\t\tfor ( ; cur !== this; cur = cur.parentNode || this ) {\n\n\t\t\t\t// Don't check non-elements (#13208)\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.nodeType === 1 && !( event.type === \"click\" && cur.disabled === true ) ) {\n\t\t\t\t\tmatchedHandlers = [];\n\t\t\t\t\tmatchedSelectors = {};\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatchedSelectors[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) > -1 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] ) {\n\t\t\t\t\t\t\tmatchedHandlers.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matchedHandlers.length ) {\n\t\t\t\t\t\thandlerQueue.push( { elem: cur, handlers: matchedHandlers } );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tcur = this;\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\taddProp: function( name, hook ) {\n\t\tObject.defineProperty( jQuery.Event.prototype, name, {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: true,\n\n\t\t\tget: isFunction( hook ) ?\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\t\treturn hook( this.originalEvent );\n\t\t\t\t\t}\n\t\t\t\t} :\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\t\treturn this.originalEvent[ name ];\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\tset: function( value ) {\n\t\t\t\tObject.defineProperty( this, name, {\n\t\t\t\t\tenumerable: true,\n\t\t\t\t\tconfigurable: true,\n\t\t\t\t\twritable: true,\n\t\t\t\t\tvalue: value\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t},\n\n\tfix: function( originalEvent ) {\n\t\treturn originalEvent[ jQuery.expando ] ?\n\t\t\toriginalEvent :\n\t\t\tnew jQuery.Event( originalEvent );\n\t},\n\n\tspecial: {\n\t\tload: {\n\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tclick: {\n\n\t\t\t// Utilize native event to ensure correct state for checkable inputs\n\t\t\tsetup: function( data ) {\n\n\t\t\t\t// For mutual compressibility with _default, replace `this` access with a local var.\n\t\t\t\t// `|| data` is dead code meant only to preserve the variable through minification.\n\t\t\t\tvar el = this || data;\n\n\t\t\t\t// Claim the first handler\n\t\t\t\tif ( rcheckableType.test( el.type ) &&\n\t\t\t\t\tel.click && nodeName( el, \"input\" ) ) {\n\n\t\t\t\t\t// dataPriv.set( el, \"click\", ... )\n\t\t\t\t\tleverageNative( el, \"click\", returnTrue );\n\t\t\t\t}\n\n\t\t\t\t// Return false to allow normal processing in the caller\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\ttrigger: function( data ) {\n\n\t\t\t\t// For mutual compressibility with _default, replace `this` access with a local var.\n\t\t\t\t// `|| data` is dead code meant only to preserve the variable through minification.\n\t\t\t\tvar el = this || data;\n\n\t\t\t\t// Force setup before triggering a click\n\t\t\t\tif ( rcheckableType.test( el.type ) &&\n\t\t\t\t\tel.click && nodeName( el, \"input\" ) ) {\n\n\t\t\t\t\tleverageNative( el, \"click\" );\n\t\t\t\t}\n\n\t\t\t\t// Return non-false to allow normal event-path propagation\n\t\t\t\treturn true;\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, suppress native .click() on links\n\t\t\t// Also prevent it if we're currently inside a leveraged native-event stack\n\t\t\t_default: function( event ) {\n\t\t\t\tvar target = event.target;\n\t\t\t\treturn rcheckableType.test( target.type ) &&\n\t\t\t\t\ttarget.click && nodeName( target, \"input\" ) &&\n\t\t\t\t\tdataPriv.get( target, \"click\" ) ||\n\t\t\t\t\tnodeName( target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Ensure the presence of an event listener that handles manually-triggered\n// synthetic events by interrupting progress until reinvoked in response to\n// *native* events that it fires directly, ensuring that state changes have\n// already occurred before other listeners are invoked.\nfunction leverageNative( el, type, expectSync ) {\n\n\t// Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add\n\tif ( !expectSync ) {\n\t\tif ( dataPriv.get( el, type ) === undefined ) {\n\t\t\tjQuery.event.add( el, type, returnTrue );\n\t\t}\n\t\treturn;\n\t}\n\n\t// Register the controller as a special universal handler for all event namespaces\n\tdataPriv.set( el, type, false );\n\tjQuery.event.add( el, type, {\n\t\tnamespace: false,\n\t\thandler: function( event ) {\n\t\t\tvar notAsync, result,\n\t\t\t\tsaved = dataPriv.get( this, type );\n\n\t\t\tif ( ( event.isTrigger & 1 ) && this[ type ] ) {\n\n\t\t\t\t// Interrupt processing of the outer synthetic .trigger()ed event\n\t\t\t\t// Saved data should be false in such cases, but might be a leftover capture object\n\t\t\t\t// from an async native handler (gh-4350)\n\t\t\t\tif ( !saved.length ) {\n\n\t\t\t\t\t// Store arguments for use when handling the inner native event\n\t\t\t\t\t// There will always be at least one argument (an event object), so this array\n\t\t\t\t\t// will not be confused with a leftover capture object.\n\t\t\t\t\tsaved = slice.call( arguments );\n\t\t\t\t\tdataPriv.set( this, type, saved );\n\n\t\t\t\t\t// Trigger the native event and capture its result\n\t\t\t\t\t// Support: IE <=9 - 11+\n\t\t\t\t\t// focus() and blur() are asynchronous\n\t\t\t\t\tnotAsync = expectSync( this, type );\n\t\t\t\t\tthis[ type ]();\n\t\t\t\t\tresult = dataPriv.get( this, type );\n\t\t\t\t\tif ( saved !== result || notAsync ) {\n\t\t\t\t\t\tdataPriv.set( this, type, false );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult = {};\n\t\t\t\t\t}\n\t\t\t\t\tif ( saved !== result ) {\n\n\t\t\t\t\t\t// Cancel the outer synthetic event\n\t\t\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\treturn result.value;\n\t\t\t\t\t}\n\n\t\t\t\t// If this is an inner synthetic event for an event with a bubbling surrogate\n\t\t\t\t// (focus or blur), assume that the surrogate already propagated from triggering the\n\t\t\t\t// native event and prevent that from happening again here.\n\t\t\t\t// This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the\n\t\t\t\t// bubbling surrogate propagates *after* the non-bubbling base), but that seems\n\t\t\t\t// less bad than duplication.\n\t\t\t\t} else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {\n\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t}\n\n\t\t\t// If this is a native event triggered above, everything is now in order\n\t\t\t// Fire an inner synthetic event with the original arguments\n\t\t\t} else if ( saved.length ) {\n\n\t\t\t\t// ...and capture the result\n\t\t\t\tdataPriv.set( this, type, {\n\t\t\t\t\tvalue: jQuery.event.trigger(\n\n\t\t\t\t\t\t// Support: IE <=9 - 11+\n\t\t\t\t\t\t// Extend with the prototype to reset the above stopImmediatePropagation()\n\t\t\t\t\t\tjQuery.extend( saved[ 0 ], jQuery.Event.prototype ),\n\t\t\t\t\t\tsaved.slice( 1 ),\n\t\t\t\t\t\tthis\n\t\t\t\t\t)\n\t\t\t\t} );\n\n\t\t\t\t// Abort handling of the native event\n\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t}\n\t\t}\n\t} );\n}\n\njQuery.removeEvent = function( elem, type, handle ) {\n\n\t// This \"if\" is needed for plain objects\n\tif ( elem.removeEventListener ) {\n\t\telem.removeEventListener( type, handle );\n\t}\n};\n\njQuery.Event = function( src, props ) {\n\n\t// Allow instantiation without the 'new' keyword\n\tif ( !( this instanceof jQuery.Event ) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\n\t\t\t\t// Support: Android <=2.3 only\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t\t// Create target properties\n\t\t// Support: Safari <=6 - 7 only\n\t\t// Target should not be a text node (#504, #13143)\n\t\tthis.target = ( src.target && src.target.nodeType === 3 ) ?\n\t\t\tsrc.target.parentNode :\n\t\t\tsrc.target;\n\n\t\tthis.currentTarget = src.currentTarget;\n\t\tthis.relatedTarget = src.relatedTarget;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || Date.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tconstructor: jQuery.Event,\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\tisSimulated: false,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.preventDefault();\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Includes all common event props including KeyEvent and MouseEvent specific props\njQuery.each( {\n\taltKey: true,\n\tbubbles: true,\n\tcancelable: true,\n\tchangedTouches: true,\n\tctrlKey: true,\n\tdetail: true,\n\teventPhase: true,\n\tmetaKey: true,\n\tpageX: true,\n\tpageY: true,\n\tshiftKey: true,\n\tview: true,\n\t\"char\": true,\n\tcode: true,\n\tcharCode: true,\n\tkey: true,\n\tkeyCode: true,\n\tbutton: true,\n\tbuttons: true,\n\tclientX: true,\n\tclientY: true,\n\toffsetX: true,\n\toffsetY: true,\n\tpointerId: true,\n\tpointerType: true,\n\tscreenX: true,\n\tscreenY: true,\n\ttargetTouches: true,\n\ttoElement: true,\n\ttouches: true,\n\n\twhich: function( event ) {\n\t\tvar button = event.button;\n\n\t\t// Add which for key events\n\t\tif ( event.which == null && rkeyEvent.test( event.type ) ) {\n\t\t\treturn event.charCode != null ? event.charCode : event.keyCode;\n\t\t}\n\n\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\tif ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {\n\t\t\tif ( button & 1 ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\tif ( button & 2 ) {\n\t\t\t\treturn 3;\n\t\t\t}\n\n\t\t\tif ( button & 4 ) {\n\t\t\t\treturn 2;\n\t\t\t}\n\n\t\t\treturn 0;\n\t\t}\n\n\t\treturn event.which;\n\t}\n}, jQuery.event.addProp );\n\njQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( type, delegateType ) {\n\tjQuery.event.special[ type ] = {\n\n\t\t// Utilize native event if possible so blur/focus sequence is correct\n\t\tsetup: function() {\n\n\t\t\t// Claim the first handler\n\t\t\t// dataPriv.set( this, \"focus\", ... )\n\t\t\t// dataPriv.set( this, \"blur\", ... )\n\t\t\tleverageNative( this, type, expectSync );\n\n\t\t\t// Return false to allow normal processing in the caller\n\t\t\treturn false;\n\t\t},\n\t\ttrigger: function() {\n\n\t\t\t// Force setup before trigger\n\t\t\tleverageNative( this, type );\n\n\t\t\t// Return non-false to allow normal event-path propagation\n\t\t\treturn true;\n\t\t},\n\n\t\tdelegateType: delegateType\n\t};\n} );\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\n// so that event delegation works in jQuery.\n// Do the same for pointerenter/pointerleave and pointerover/pointerout\n//\n// Support: Safari 7 only\n// Safari sends mouseenter too often; see:\n// https://bugs.chromium.org/p/chromium/issues/detail?id=470258\n// for the description of the bug (it existed in older Chrome versions as well).\njQuery.each( {\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mouseenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n} );\n\njQuery.fn.extend( {\n\n\ton: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn );\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\n\t\t\t// ( event )  dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ?\n\t\t\t\t\thandleObj.origType + \".\" + handleObj.namespace :\n\t\t\t\t\thandleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t} );\n\t}\n} );\n\n\nvar\n\n\t// Support: IE <=10 - 11, Edge 12 - 13 only\n\t// In IE/Edge using regex groups here causes severe slowdowns.\n\t// See https://connect.microsoft.com/IE/feedback/details/1736512/\n\trnoInnerhtml = /<script|<style|<link/i,\n\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g;\n\n// Prefer a tbody over its parent table for containing new rows\nfunction manipulationTarget( elem, content ) {\n\tif ( nodeName( elem, \"table\" ) &&\n\t\tnodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ) {\n\n\t\treturn jQuery( elem ).children( \"tbody\" )[ 0 ] || elem;\n\t}\n\n\treturn elem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = ( elem.getAttribute( \"type\" ) !== null ) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tif ( ( elem.type || \"\" ).slice( 0, 5 ) === \"true/\" ) {\n\t\telem.type = elem.type.slice( 5 );\n\t} else {\n\t\telem.removeAttribute( \"type\" );\n\t}\n\n\treturn elem;\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\tvar i, l, type, pdataOld, udataOld, udataCur, events;\n\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\t// 1. Copy private data: events, handlers, etc.\n\tif ( dataPriv.hasData( src ) ) {\n\t\tpdataOld = dataPriv.get( src );\n\t\tevents = pdataOld.events;\n\n\t\tif ( events ) {\n\t\t\tdataPriv.remove( dest, \"handle events\" );\n\n\t\t\tfor ( type in events ) {\n\t\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// 2. Copy user data\n\tif ( dataUser.hasData( src ) ) {\n\t\tudataOld = dataUser.access( src );\n\t\tudataCur = jQuery.extend( {}, udataOld );\n\n\t\tdataUser.set( dest, udataCur );\n\t}\n}\n\n// Fix IE bugs, see support tests\nfunction fixInput( src, dest ) {\n\tvar nodeName = dest.nodeName.toLowerCase();\n\n\t// Fails to persist the checked state of a cloned checkbox or radio button.\n\tif ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\tdest.checked = src.checked;\n\n\t// Fails to return the selected option to the default selected state when cloning options\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\nfunction domManip( collection, args, callback, ignored ) {\n\n\t// Flatten any nested arrays\n\targs = flat( args );\n\n\tvar fragment, first, scripts, hasScripts, node, doc,\n\t\ti = 0,\n\t\tl = collection.length,\n\t\tiNoClone = l - 1,\n\t\tvalue = args[ 0 ],\n\t\tvalueIsFunction = isFunction( value );\n\n\t// We can't cloneNode fragments that contain checked, in WebKit\n\tif ( valueIsFunction ||\n\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\treturn collection.each( function( index ) {\n\t\t\tvar self = collection.eq( index );\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\targs[ 0 ] = value.call( this, index, self.html() );\n\t\t\t}\n\t\t\tdomManip( self, args, callback, ignored );\n\t\t} );\n\t}\n\n\tif ( l ) {\n\t\tfragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );\n\t\tfirst = fragment.firstChild;\n\n\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\tfragment = first;\n\t\t}\n\n\t\t// Require either new content or an interest in ignored elements to invoke the callback\n\t\tif ( first || ignored ) {\n\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\thasScripts = scripts.length;\n\n\t\t\t// Use the original fragment for the last item\n\t\t\t// instead of the first because it can end up\n\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tnode = fragment;\n\n\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\tif ( hasScripts ) {\n\n\t\t\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcallback.call( collection[ i ], node, i );\n\t\t\t}\n\n\t\t\tif ( hasScripts ) {\n\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t// Reenable scripts\n\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t!dataPriv.access( node, \"globalEval\" ) &&\n\t\t\t\t\t\tjQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\tif ( node.src && ( node.type || \"\" ).toLowerCase()  !== \"module\" ) {\n\n\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\tif ( jQuery._evalUrl && !node.noModule ) {\n\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src, {\n\t\t\t\t\t\t\t\t\tnonce: node.nonce || node.getAttribute( \"nonce\" )\n\t\t\t\t\t\t\t\t}, doc );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tDOMEval( node.textContent.replace( rcleanScript, \"\" ), node, doc );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn collection;\n}\n\nfunction remove( elem, selector, keepData ) {\n\tvar node,\n\t\tnodes = selector ? jQuery.filter( selector, elem ) : elem,\n\t\ti = 0;\n\n\tfor ( ; ( node = nodes[ i ] ) != null; i++ ) {\n\t\tif ( !keepData && node.nodeType === 1 ) {\n\t\t\tjQuery.cleanData( getAll( node ) );\n\t\t}\n\n\t\tif ( node.parentNode ) {\n\t\t\tif ( keepData && isAttached( node ) ) {\n\t\t\t\tsetGlobalEval( getAll( node, \"script\" ) );\n\t\t\t}\n\t\t\tnode.parentNode.removeChild( node );\n\t\t}\n\t}\n\n\treturn elem;\n}\n\njQuery.extend( {\n\thtmlPrefilter: function( html ) {\n\t\treturn html;\n\t},\n\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar i, l, srcElements, destElements,\n\t\t\tclone = elem.cloneNode( true ),\n\t\t\tinPage = isAttached( elem );\n\n\t\t// Fix IE cloning issues\n\t\tif ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&\n\t\t\t\t!jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\tfixInput( srcElements[ i ], destElements[ i ] );\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\t\tcloneCopyEvent( srcElements[ i ], destElements[ i ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tcleanData: function( elems ) {\n\t\tvar data, elem, type,\n\t\t\tspecial = jQuery.event.special,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {\n\t\t\tif ( acceptData( elem ) ) {\n\t\t\t\tif ( ( data = elem[ dataPriv.expando ] ) ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataPriv.expando ] = undefined;\n\t\t\t\t}\n\t\t\t\tif ( elem[ dataUser.expando ] ) {\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataUser.expando ] = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n} );\n\njQuery.fn.extend( {\n\tdetach: function( selector ) {\n\t\treturn remove( this, selector, true );\n\t},\n\n\tremove: function( selector ) {\n\t\treturn remove( this, selector );\n\t},\n\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().each( function() {\n\t\t\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\t\t\tthis.textContent = value;\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t} );\n\t},\n\n\tprepend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t} );\n\t},\n\n\tbefore: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t} );\n\t},\n\n\tafter: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t} );\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = this[ i ] ) != null; i++ ) {\n\t\t\tif ( elem.nodeType === 1 ) {\n\n\t\t\t\t// Prevent memory leaks\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\n\t\t\t\t// Remove any remaining nodes\n\t\t\t\telem.textContent = \"\";\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map( function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t} );\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined && elem.nodeType === 1 ) {\n\t\t\t\treturn elem.innerHTML;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t!wrapMap[ ( rtagName.exec( value ) || [ \"\", \"\" ] )[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = jQuery.htmlPrefilter( value );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\t\telem = this[ i ] || {};\n\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch ( e ) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar ignored = [];\n\n\t\t// Make the changes, replacing each non-ignored context element with the new content\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tvar parent = this.parentNode;\n\n\t\t\tif ( jQuery.inArray( this, ignored ) < 0 ) {\n\t\t\t\tjQuery.cleanData( getAll( this ) );\n\t\t\t\tif ( parent ) {\n\t\t\t\t\tparent.replaceChild( elem, this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Force callback invocation\n\t\t}, ignored );\n\t}\n} );\n\njQuery.each( {\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1,\n\t\t\ti = 0;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone( true );\n\t\t\tjQuery( insert[ i ] )[ original ]( elems );\n\n\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t// .get() because push.apply(_, arraylike) throws on ancient WebKit\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n} );\nvar rnumnonpx = new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n\nvar getStyles = function( elem ) {\n\n\t\t// Support: IE <=11 only, Firefox <=30 (#15098, #14150)\n\t\t// IE throws on elements created in popups\n\t\t// FF meanwhile throws on frame elements through \"defaultView.getComputedStyle\"\n\t\tvar view = elem.ownerDocument.defaultView;\n\n\t\tif ( !view || !view.opener ) {\n\t\t\tview = window;\n\t\t}\n\n\t\treturn view.getComputedStyle( elem );\n\t};\n\nvar swap = function( elem, options, callback ) {\n\tvar ret, name,\n\t\told = {};\n\n\t// Remember the old values, and insert the new ones\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.call( elem );\n\n\t// Revert the old values\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\nvar rboxStyle = new RegExp( cssExpand.join( \"|\" ), \"i\" );\n\n\n\n( function() {\n\n\t// Executing both pixelPosition & boxSizingReliable tests require only one layout\n\t// so they're executed at the same time to save the second computation.\n\tfunction computeStyleTests() {\n\n\t\t// This is a singleton, we need to execute it only once\n\t\tif ( !div ) {\n\t\t\treturn;\n\t\t}\n\n\t\tcontainer.style.cssText = \"position:absolute;left:-11111px;width:60px;\" +\n\t\t\t\"margin-top:1px;padding:0;border:0\";\n\t\tdiv.style.cssText =\n\t\t\t\"position:relative;display:block;box-sizing:border-box;overflow:scroll;\" +\n\t\t\t\"margin:auto;border:1px;padding:1px;\" +\n\t\t\t\"width:60%;top:1%\";\n\t\tdocumentElement.appendChild( container ).appendChild( div );\n\n\t\tvar divStyle = window.getComputedStyle( div );\n\t\tpixelPositionVal = divStyle.top !== \"1%\";\n\n\t\t// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44\n\t\treliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;\n\n\t\t// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3\n\t\t// Some styles come back with percentage values, even though they shouldn't\n\t\tdiv.style.right = \"60%\";\n\t\tpixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;\n\n\t\t// Support: IE 9 - 11 only\n\t\t// Detect misreporting of content dimensions for box-sizing:border-box elements\n\t\tboxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;\n\n\t\t// Support: IE 9 only\n\t\t// Detect overflow:scroll screwiness (gh-3699)\n\t\t// Support: Chrome <=64\n\t\t// Don't get tricked when zoom affects offsetWidth (gh-4029)\n\t\tdiv.style.position = \"absolute\";\n\t\tscrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12;\n\n\t\tdocumentElement.removeChild( container );\n\n\t\t// Nullify the div so it wouldn't be stored in the memory and\n\t\t// it will also be a sign that checks already performed\n\t\tdiv = null;\n\t}\n\n\tfunction roundPixelMeasures( measure ) {\n\t\treturn Math.round( parseFloat( measure ) );\n\t}\n\n\tvar pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,\n\t\treliableTrDimensionsVal, reliableMarginLeftVal,\n\t\tcontainer = document.createElement( \"div\" ),\n\t\tdiv = document.createElement( \"div\" );\n\n\t// Finish early in limited (non-browser) environments\n\tif ( !div.style ) {\n\t\treturn;\n\t}\n\n\t// Support: IE <=9 - 11 only\n\t// Style of cloned element affects source element cloned (#8908)\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\tjQuery.extend( support, {\n\t\tboxSizingReliable: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn boxSizingReliableVal;\n\t\t},\n\t\tpixelBoxStyles: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelBoxStylesVal;\n\t\t},\n\t\tpixelPosition: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelPositionVal;\n\t\t},\n\t\treliableMarginLeft: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn reliableMarginLeftVal;\n\t\t},\n\t\tscrollboxSize: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn scrollboxSizeVal;\n\t\t},\n\n\t\t// Support: IE 9 - 11+, Edge 15 - 18+\n\t\t// IE/Edge misreport `getComputedStyle` of table rows with width/height\n\t\t// set in CSS while `offset*` properties report correct values.\n\t\t// Behavior in IE 9 is more subtle than in newer versions & it passes\n\t\t// some versions of this test; make sure not to make it pass there!\n\t\treliableTrDimensions: function() {\n\t\t\tvar table, tr, trChild, trStyle;\n\t\t\tif ( reliableTrDimensionsVal == null ) {\n\t\t\t\ttable = document.createElement( \"table\" );\n\t\t\t\ttr = document.createElement( \"tr\" );\n\t\t\t\ttrChild = document.createElement( \"div\" );\n\n\t\t\t\ttable.style.cssText = \"position:absolute;left:-11111px\";\n\t\t\t\ttr.style.height = \"1px\";\n\t\t\t\ttrChild.style.height = \"9px\";\n\n\t\t\t\tdocumentElement\n\t\t\t\t\t.appendChild( table )\n\t\t\t\t\t.appendChild( tr )\n\t\t\t\t\t.appendChild( trChild );\n\n\t\t\t\ttrStyle = window.getComputedStyle( tr );\n\t\t\t\treliableTrDimensionsVal = parseInt( trStyle.height ) > 3;\n\n\t\t\t\tdocumentElement.removeChild( table );\n\t\t\t}\n\t\t\treturn reliableTrDimensionsVal;\n\t\t}\n\t} );\n} )();\n\n\nfunction curCSS( elem, name, computed ) {\n\tvar width, minWidth, maxWidth, ret,\n\n\t\t// Support: Firefox 51+\n\t\t// Retrieving style before computed somehow\n\t\t// fixes an issue with getting wrong values\n\t\t// on detached elements\n\t\tstyle = elem.style;\n\n\tcomputed = computed || getStyles( elem );\n\n\t// getPropertyValue is needed for:\n\t//   .css('filter') (IE 9 only, #12537)\n\t//   .css('--customProperty) (#3144)\n\tif ( computed ) {\n\t\tret = computed.getPropertyValue( name ) || computed[ name ];\n\n\t\tif ( ret === \"\" && !isAttached( elem ) ) {\n\t\t\tret = jQuery.style( elem, name );\n\t\t}\n\n\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t// Android Browser returns percentage for some values,\n\t\t// but width seems to be reliably pixels.\n\t\t// This is against the CSSOM draft spec:\n\t\t// https://drafts.csswg.org/cssom/#resolved-values\n\t\tif ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\twidth = style.width;\n\t\t\tminWidth = style.minWidth;\n\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\tret = computed.width;\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.width = width;\n\t\t\tstyle.minWidth = minWidth;\n\t\t\tstyle.maxWidth = maxWidth;\n\t\t}\n\t}\n\n\treturn ret !== undefined ?\n\n\t\t// Support: IE <=9 - 11 only\n\t\t// IE returns zIndex value as an integer.\n\t\tret + \"\" :\n\t\tret;\n}\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\n\t// Define the hook, we'll check on the first run if it's really needed.\n\treturn {\n\t\tget: function() {\n\t\t\tif ( conditionFn() ) {\n\n\t\t\t\t// Hook not needed (or it's not possible to use it due\n\t\t\t\t// to missing dependency), remove it.\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Hook needed; redefine it so that the support test is not executed again.\n\t\t\treturn ( this.get = hookFn ).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\nvar cssPrefixes = [ \"Webkit\", \"Moz\", \"ms\" ],\n\temptyStyle = document.createElement( \"div\" ).style,\n\tvendorProps = {};\n\n// Return a vendor-prefixed property or undefined\nfunction vendorPropName( name ) {\n\n\t// Check for vendor prefixed names\n\tvar capName = name[ 0 ].toUpperCase() + name.slice( 1 ),\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in emptyStyle ) {\n\t\t\treturn name;\n\t\t}\n\t}\n}\n\n// Return a potentially-mapped jQuery.cssProps or vendor prefixed property\nfunction finalPropName( name ) {\n\tvar final = jQuery.cssProps[ name ] || vendorProps[ name ];\n\n\tif ( final ) {\n\t\treturn final;\n\t}\n\tif ( name in emptyStyle ) {\n\t\treturn name;\n\t}\n\treturn vendorProps[ name ] = vendorPropName( name ) || name;\n}\n\n\nvar\n\n\t// Swappable if display is none or starts with table\n\t// except \"table\", \"table-cell\", or \"table-caption\"\n\t// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trcustomProp = /^--/,\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: \"0\",\n\t\tfontWeight: \"400\"\n\t};\n\nfunction setPositiveNumber( _elem, value, subtract ) {\n\n\t// Any relative (+/-) values have already been\n\t// normalized at this point\n\tvar matches = rcssNum.exec( value );\n\treturn matches ?\n\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {\n\tvar i = dimension === \"width\" ? 1 : 0,\n\t\textra = 0,\n\t\tdelta = 0;\n\n\t// Adjustment may not be necessary\n\tif ( box === ( isBorderBox ? \"border\" : \"content\" ) ) {\n\t\treturn 0;\n\t}\n\n\tfor ( ; i < 4; i += 2 ) {\n\n\t\t// Both box models exclude margin\n\t\tif ( box === \"margin\" ) {\n\t\t\tdelta += jQuery.css( elem, box + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\t// If we get here with a content-box, we're seeking \"padding\" or \"border\" or \"margin\"\n\t\tif ( !isBorderBox ) {\n\n\t\t\t// Add padding\n\t\t\tdelta += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// For \"border\" or \"margin\", add border\n\t\t\tif ( box !== \"padding\" ) {\n\t\t\t\tdelta += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\n\t\t\t// But still keep track of it otherwise\n\t\t\t} else {\n\t\t\t\textra += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\n\t\t// If we get here with a border-box (content + padding + border), we're seeking \"content\" or\n\t\t// \"padding\" or \"margin\"\n\t\t} else {\n\n\t\t\t// For \"content\", subtract padding\n\t\t\tif ( box === \"content\" ) {\n\t\t\t\tdelta -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// For \"content\" or \"padding\", subtract border\n\t\t\tif ( box !== \"margin\" ) {\n\t\t\t\tdelta -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Account for positive content-box scroll gutter when requested by providing computedVal\n\tif ( !isBorderBox && computedVal >= 0 ) {\n\n\t\t// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border\n\t\t// Assuming integer scroll gutter, subtract the rest and round down\n\t\tdelta += Math.max( 0, Math.ceil(\n\t\t\telem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\tcomputedVal -\n\t\t\tdelta -\n\t\t\textra -\n\t\t\t0.5\n\n\t\t// If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter\n\t\t// Use an explicit zero to avoid NaN (gh-3964)\n\t\t) ) || 0;\n\t}\n\n\treturn delta;\n}\n\nfunction getWidthOrHeight( elem, dimension, extra ) {\n\n\t// Start with computed style\n\tvar styles = getStyles( elem ),\n\n\t\t// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).\n\t\t// Fake content-box until we know it's needed to know the true value.\n\t\tboxSizingNeeded = !support.boxSizingReliable() || extra,\n\t\tisBorderBox = boxSizingNeeded &&\n\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\tvalueIsBorderBox = isBorderBox,\n\n\t\tval = curCSS( elem, dimension, styles ),\n\t\toffsetProp = \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );\n\n\t// Support: Firefox <=54\n\t// Return a confounding non-pixel value or feign ignorance, as appropriate.\n\tif ( rnumnonpx.test( val ) ) {\n\t\tif ( !extra ) {\n\t\t\treturn val;\n\t\t}\n\t\tval = \"auto\";\n\t}\n\n\n\t// Support: IE 9 - 11 only\n\t// Use offsetWidth/offsetHeight for when box sizing is unreliable.\n\t// In those cases, the computed value can be trusted to be border-box.\n\tif ( ( !support.boxSizingReliable() && isBorderBox ||\n\n\t\t// Support: IE 10 - 11+, Edge 15 - 18+\n\t\t// IE/Edge misreport `getComputedStyle` of table rows with width/height\n\t\t// set in CSS while `offset*` properties report correct values.\n\t\t// Interestingly, in some cases IE 9 doesn't suffer from this issue.\n\t\t!support.reliableTrDimensions() && nodeName( elem, \"tr\" ) ||\n\n\t\t// Fall back to offsetWidth/offsetHeight when value is \"auto\"\n\t\t// This happens for inline elements with no explicit setting (gh-3571)\n\t\tval === \"auto\" ||\n\n\t\t// Support: Android <=4.1 - 4.3 only\n\t\t// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)\n\t\t!parseFloat( val ) && jQuery.css( elem, \"display\", false, styles ) === \"inline\" ) &&\n\n\t\t// Make sure the element is visible & connected\n\t\telem.getClientRects().length ) {\n\n\t\tisBorderBox = jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\n\t\t// Where available, offsetWidth/offsetHeight approximate border box dimensions.\n\t\t// Where not available (e.g., SVG), assume unreliable box-sizing and interpret the\n\t\t// retrieved value as a content box dimension.\n\t\tvalueIsBorderBox = offsetProp in elem;\n\t\tif ( valueIsBorderBox ) {\n\t\t\tval = elem[ offsetProp ];\n\t\t}\n\t}\n\n\t// Normalize \"\" and auto\n\tval = parseFloat( val ) || 0;\n\n\t// Adjust for the element's box model\n\treturn ( val +\n\t\tboxModelAdjustment(\n\t\t\telem,\n\t\t\tdimension,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles,\n\n\t\t\t// Provide the current computed size to request scroll gutter calculation (gh-3589)\n\t\t\tval\n\t\t)\n\t) + \"px\";\n}\n\njQuery.extend( {\n\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"animationIterationCount\": true,\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"flexGrow\": true,\n\t\t\"flexShrink\": true,\n\t\t\"fontWeight\": true,\n\t\t\"gridArea\": true,\n\t\t\"gridColumn\": true,\n\t\t\"gridColumnEnd\": true,\n\t\t\"gridColumnStart\": true,\n\t\t\"gridRow\": true,\n\t\t\"gridRowEnd\": true,\n\t\t\"gridRowStart\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name ),\n\t\t\tstyle = elem.style;\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to query the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Gets hook for the prefixed version, then unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// Convert \"+=\" or \"-=\" to relative numbers (#7345)\n\t\t\tif ( type === \"string\" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {\n\t\t\t\tvalue = adjustCSS( elem, name, ret );\n\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that null and NaN values aren't set (#7116)\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add the unit (except for certain CSS properties)\n\t\t\t// The isCustomProp check can be removed in jQuery 4.0 when we only auto-append\n\t\t\t// \"px\" to a few hardcoded values.\n\t\t\tif ( type === \"number\" && !isCustomProp ) {\n\t\t\t\tvalue += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? \"\" : \"px\" );\n\t\t\t}\n\n\t\t\t// background-* props affect original clone's values\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf( \"background\" ) === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !( \"set\" in hooks ) ||\n\t\t\t\t( value = hooks.set( elem, value, extra ) ) !== undefined ) {\n\n\t\t\t\tif ( isCustomProp ) {\n\t\t\t\t\tstyle.setProperty( name, value );\n\t\t\t\t} else {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks &&\n\t\t\t\t( ret = hooks.get( elem, false, extra ) ) !== undefined ) {\n\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar val, num, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name );\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to modify the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Try prefixed name followed by the unprefixed name\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t// Convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Make numeric if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || isFinite( num ) ? num || 0 : val;\n\t\t}\n\n\t\treturn val;\n\t}\n} );\n\njQuery.each( [ \"height\", \"width\" ], function( _i, dimension ) {\n\tjQuery.cssHooks[ dimension ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\n\t\t\t\t// Certain elements can have dimension info if we invisibly show them\n\t\t\t\t// but it must have a current display style that would benefit\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, \"display\" ) ) &&\n\n\t\t\t\t\t// Support: Safari 8+\n\t\t\t\t\t// Table columns in Safari have non-zero offsetWidth & zero\n\t\t\t\t\t// getBoundingClientRect().width unless display is changed.\n\t\t\t\t\t// Support: IE <=11 only\n\t\t\t\t\t// Running getBoundingClientRect on a disconnected node\n\t\t\t\t\t// in IE throws an error.\n\t\t\t\t\t( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?\n\t\t\t\t\t\tswap( elem, cssShow, function() {\n\t\t\t\t\t\t\treturn getWidthOrHeight( elem, dimension, extra );\n\t\t\t\t\t\t} ) :\n\t\t\t\t\t\tgetWidthOrHeight( elem, dimension, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar matches,\n\t\t\t\tstyles = getStyles( elem ),\n\n\t\t\t\t// Only read styles.position if the test has a chance to fail\n\t\t\t\t// to avoid forcing a reflow.\n\t\t\t\tscrollboxSizeBuggy = !support.scrollboxSize() &&\n\t\t\t\t\tstyles.position === \"absolute\",\n\n\t\t\t\t// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)\n\t\t\t\tboxSizingNeeded = scrollboxSizeBuggy || extra,\n\t\t\t\tisBorderBox = boxSizingNeeded &&\n\t\t\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\tsubtract = extra ?\n\t\t\t\t\tboxModelAdjustment(\n\t\t\t\t\t\telem,\n\t\t\t\t\t\tdimension,\n\t\t\t\t\t\textra,\n\t\t\t\t\t\tisBorderBox,\n\t\t\t\t\t\tstyles\n\t\t\t\t\t) :\n\t\t\t\t\t0;\n\n\t\t\t// Account for unreliable border-box dimensions by comparing offset* to computed and\n\t\t\t// faking a content-box to get border and padding (gh-3699)\n\t\t\tif ( isBorderBox && scrollboxSizeBuggy ) {\n\t\t\t\tsubtract -= Math.ceil(\n\t\t\t\t\telem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\t\t\tparseFloat( styles[ dimension ] ) -\n\t\t\t\t\tboxModelAdjustment( elem, dimension, \"border\", false, styles ) -\n\t\t\t\t\t0.5\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Convert to pixels if value adjustment is needed\n\t\t\tif ( subtract && ( matches = rcssNum.exec( value ) ) &&\n\t\t\t\t( matches[ 3 ] || \"px\" ) !== \"px\" ) {\n\n\t\t\t\telem.style[ dimension ] = value;\n\t\t\t\tvalue = jQuery.css( elem, dimension );\n\t\t\t}\n\n\t\t\treturn setPositiveNumber( elem, value, subtract );\n\t\t}\n\t};\n} );\n\njQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\treturn ( parseFloat( curCSS( elem, \"marginLeft\" ) ) ||\n\t\t\t\telem.getBoundingClientRect().left -\n\t\t\t\t\tswap( elem, { marginLeft: 0 }, function() {\n\t\t\t\t\t\treturn elem.getBoundingClientRect().left;\n\t\t\t\t\t} )\n\t\t\t\t) + \"px\";\n\t\t}\n\t}\n);\n\n// These hooks are used by animate to expand properties\njQuery.each( {\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// Assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split( \" \" ) : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( prefix !== \"margin\" ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n} );\n\njQuery.fn.extend( {\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( Array.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t}\n} );\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || jQuery.easing._default;\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\t// Use a property on the element directly when it is not a DOM element,\n\t\t\t// or when there is no matching style property that exists.\n\t\t\tif ( tween.elem.nodeType !== 1 ||\n\t\t\t\ttween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// Passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails.\n\t\t\t// Simple values such as \"10px\" are parsed to Float;\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as-is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\n\t\t\t// Use step hook for back compat.\n\t\t\t// Use cssHook if its there.\n\t\t\t// Use .style if available and use plain properties where available.\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.nodeType === 1 && (\n\t\t\t\t\tjQuery.cssHooks[ tween.prop ] ||\n\t\t\t\t\ttween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE <=9 only\n// Panic based approach to setting things on disconnected nodes\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t},\n\t_default: \"swing\"\n};\n\njQuery.fx = Tween.prototype.init;\n\n// Back compat <1.8 extension point\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, inProgress,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trrun = /queueHooks$/;\n\nfunction schedule() {\n\tif ( inProgress ) {\n\t\tif ( document.hidden === false && window.requestAnimationFrame ) {\n\t\t\twindow.requestAnimationFrame( schedule );\n\t\t} else {\n\t\t\twindow.setTimeout( schedule, jQuery.fx.interval );\n\t\t}\n\n\t\tjQuery.fx.tick();\n\t}\n}\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\twindow.setTimeout( function() {\n\t\tfxNow = undefined;\n\t} );\n\treturn ( fxNow = Date.now() );\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\ti = 0,\n\t\tattrs = { height: type };\n\n\t// If we include width, step value is 1 to do all cssExpand values,\n\t// otherwise step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {\n\n\t\t\t// We're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\tvar prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,\n\t\tisBox = \"width\" in props || \"height\" in props,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHiddenWithinTree( elem ),\n\t\tdataShow = dataPriv.get( elem, \"fxshow\" );\n\n\t// Queue-skipping animations hijack the fx hooks\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always( function() {\n\n\t\t\t// Ensure the complete handler is called before this completes\n\t\t\tanim.always( function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n\n\t// Detect show/hide animations\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.test( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\n\t\t\t\t// Pretend to be hidden if this is a \"show\" and\n\t\t\t\t// there is still data from a stopped show/hide\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\n\t\t\t\t// Ignore all other no-op show/hide data\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\t\t}\n\t}\n\n\t// Bail out if this is a no-op like .hide().hide()\n\tpropTween = !jQuery.isEmptyObject( props );\n\tif ( !propTween && jQuery.isEmptyObject( orig ) ) {\n\t\treturn;\n\t}\n\n\t// Restrict \"overflow\" and \"display\" styles during box animations\n\tif ( isBox && elem.nodeType === 1 ) {\n\n\t\t// Support: IE <=9 - 11, Edge 12 - 15\n\t\t// Record all 3 overflow attributes because IE does not infer the shorthand\n\t\t// from identically-valued overflowX and overflowY and Edge just mirrors\n\t\t// the overflowX value there.\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Identify a display type, preferring old show/hide data over the CSS cascade\n\t\trestoreDisplay = dataShow && dataShow.display;\n\t\tif ( restoreDisplay == null ) {\n\t\t\trestoreDisplay = dataPriv.get( elem, \"display\" );\n\t\t}\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\tif ( display === \"none\" ) {\n\t\t\tif ( restoreDisplay ) {\n\t\t\t\tdisplay = restoreDisplay;\n\t\t\t} else {\n\n\t\t\t\t// Get nonempty value(s) by temporarily forcing visibility\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t\trestoreDisplay = elem.style.display || restoreDisplay;\n\t\t\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\t\t\tshowHide( [ elem ] );\n\t\t\t}\n\t\t}\n\n\t\t// Animate inline elements as inline-block\n\t\tif ( display === \"inline\" || display === \"inline-block\" && restoreDisplay != null ) {\n\t\t\tif ( jQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\t\t// Restore the original display value at the end of pure show/hide animations\n\t\t\t\tif ( !propTween ) {\n\t\t\t\t\tanim.done( function() {\n\t\t\t\t\t\tstyle.display = restoreDisplay;\n\t\t\t\t\t} );\n\t\t\t\t\tif ( restoreDisplay == null ) {\n\t\t\t\t\t\tdisplay = style.display;\n\t\t\t\t\t\trestoreDisplay = display === \"none\" ? \"\" : display;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstyle.display = \"inline-block\";\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tanim.always( function() {\n\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t} );\n\t}\n\n\t// Implement show/hide animations\n\tpropTween = false;\n\tfor ( prop in orig ) {\n\n\t\t// General show/hide setup for this element animation\n\t\tif ( !propTween ) {\n\t\t\tif ( dataShow ) {\n\t\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\t\thidden = dataShow.hidden;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdataShow = dataPriv.access( elem, \"fxshow\", { display: restoreDisplay } );\n\t\t\t}\n\n\t\t\t// Store hidden/visible for toggle so `.stop().toggle()` \"reverses\"\n\t\t\tif ( toggle ) {\n\t\t\t\tdataShow.hidden = !hidden;\n\t\t\t}\n\n\t\t\t// Show elements before animating them\n\t\t\tif ( hidden ) {\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t}\n\n\t\t\t/* eslint-disable no-loop-func */\n\n\t\t\tanim.done( function() {\n\n\t\t\t/* eslint-enable no-loop-func */\n\n\t\t\t\t// The final step of a \"hide\" animation is actually hiding the element\n\t\t\t\tif ( !hidden ) {\n\t\t\t\t\tshowHide( [ elem ] );\n\t\t\t\t}\n\t\t\t\tdataPriv.remove( elem, \"fxshow\" );\n\t\t\t\tfor ( prop in orig ) {\n\t\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Per-property setup\n\t\tpropTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\t\tif ( !( prop in dataShow ) ) {\n\t\t\tdataShow[ prop ] = propTween.start;\n\t\t\tif ( hidden ) {\n\t\t\t\tpropTween.end = propTween.start;\n\t\t\t\tpropTween.start = 0;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( Array.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// Not quite $.extend, this won't overwrite existing keys.\n\t\t\t// Reusing 'index' because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = Animation.prefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\n\t\t\t// Don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t} ),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\n\t\t\t\t// Support: Android 2.3 only\n\t\t\t\t// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ] );\n\n\t\t\t// If there's more to do, yield\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t}\n\n\t\t\t// If this was an empty animation, synthesize a final progress notification\n\t\t\tif ( !length ) {\n\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t}\n\n\t\t\t// Resolve the animation and report its conclusion\n\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\treturn false;\n\t\t},\n\t\tanimation = deferred.promise( {\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, {\n\t\t\t\tspecialEasing: {},\n\t\t\t\teasing: jQuery.easing._default\n\t\t\t}, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\n\t\t\t\t\t// If we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// Resolve when we played the last frame; otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t} ),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length; index++ ) {\n\t\tresult = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\tif ( isFunction( result.stop ) ) {\n\t\t\t\tjQuery._queueHooks( animation.elem, animation.opts.queue ).stop =\n\t\t\t\t\tresult.stop.bind( result );\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\t// Attach callbacks from options\n\tanimation\n\t\t.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t} )\n\t);\n\n\treturn animation;\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n\ttweeners: {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value );\n\t\t\tadjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );\n\t\t\treturn tween;\n\t\t} ]\n\t},\n\n\ttweener: function( props, callback ) {\n\t\tif ( isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.match( rnothtmlwhite );\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\tAnimation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];\n\t\t\tAnimation.tweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilters: [ defaultPrefilter ],\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tAnimation.prefilters.unshift( callback );\n\t\t} else {\n\t\t\tAnimation.prefilters.push( callback );\n\t\t}\n\t}\n} );\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tisFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !isFunction( easing ) && easing\n\t};\n\n\t// Go to the end state if fx are off\n\tif ( jQuery.fx.off ) {\n\t\topt.duration = 0;\n\n\t} else {\n\t\tif ( typeof opt.duration !== \"number\" ) {\n\t\t\tif ( opt.duration in jQuery.fx.speeds ) {\n\t\t\t\topt.duration = jQuery.fx.speeds[ opt.duration ];\n\n\t\t\t} else {\n\t\t\t\topt.duration = jQuery.fx.speeds._default;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend( {\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// Show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHiddenWithinTree ).css( \"opacity\", 0 ).show()\n\n\t\t\t// Animate to the value specified\n\t\t\t.end().animate( { opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || dataPriv.get( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\t\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = dataPriv.get( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this &&\n\t\t\t\t\t( type == null || timers[ index ].queue === type ) ) {\n\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Start the next in the queue if the last step wasn't forced.\n\t\t\t// Timers currently will call their complete callbacks, which\n\t\t\t// will dequeue but only if they were gotoEnd.\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t} );\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tvar index,\n\t\t\t\tdata = dataPriv.get( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// Enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// Empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// Look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t} );\n\t}\n} );\n\njQuery.each( [ \"toggle\", \"show\", \"hide\" ], function( _i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n} );\n\n// Generate shortcuts for custom animations\njQuery.each( {\n\tslideDown: genFx( \"show\" ),\n\tslideUp: genFx( \"hide\" ),\n\tslideToggle: genFx( \"toggle\" ),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n} );\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ti = 0,\n\t\ttimers = jQuery.timers;\n\n\tfxNow = Date.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\n\t\t// Run the timer and safely remove it when done (allowing for external removal)\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tjQuery.fx.start();\n};\n\njQuery.fx.interval = 13;\njQuery.fx.start = function() {\n\tif ( inProgress ) {\n\t\treturn;\n\t}\n\n\tinProgress = true;\n\tschedule();\n};\n\njQuery.fx.stop = function() {\n\tinProgress = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\n\t// Default speed\n\t_default: 400\n};\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = window.setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\twindow.clearTimeout( timeout );\n\t\t};\n\t} );\n};\n\n\n( function() {\n\tvar input = document.createElement( \"input\" ),\n\t\tselect = document.createElement( \"select\" ),\n\t\topt = select.appendChild( document.createElement( \"option\" ) );\n\n\tinput.type = \"checkbox\";\n\n\t// Support: Android <=4.3 only\n\t// Default value for a checkbox should be \"on\"\n\tsupport.checkOn = input.value !== \"\";\n\n\t// Support: IE <=11 only\n\t// Must access selectedIndex to make default options select\n\tsupport.optSelected = opt.selected;\n\n\t// Support: IE <=11 only\n\t// An input loses its value after becoming a radio\n\tinput = document.createElement( \"input\" );\n\tinput.value = \"t\";\n\tinput.type = \"radio\";\n\tsupport.radioValue = input.value === \"t\";\n} )();\n\n\nvar boolHook,\n\tattrHandle = jQuery.expr.attrHandle;\n\njQuery.fn.extend( {\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tattr: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set attributes on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === \"undefined\" ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// Attribute hooks are determined by the lowercase version\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\thooks = jQuery.attrHooks[ name.toLowerCase() ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\treturn value;\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\tret = jQuery.find.attr( elem, name );\n\n\t\t// Non-existent attributes return null, we normalize to undefined\n\t\treturn ret == null ? undefined : ret;\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" &&\n\t\t\t\t\tnodeName( elem, \"input\" ) ) {\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name,\n\t\t\ti = 0,\n\n\t\t\t// Attribute names can contain non-HTML whitespace characters\n\t\t\t// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2\n\t\t\tattrNames = value && value.match( rnothtmlwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( ( name = attrNames[ i++ ] ) ) {\n\t\t\t\telem.removeAttribute( name );\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Hooks for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else {\n\t\t\telem.setAttribute( name, name );\n\t\t}\n\t\treturn name;\n\t}\n};\n\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( _i, name ) {\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = function( elem, name, isXML ) {\n\t\tvar ret, handle,\n\t\t\tlowercaseName = name.toLowerCase();\n\n\t\tif ( !isXML ) {\n\n\t\t\t// Avoid an infinite loop by temporarily removing this function from the getter\n\t\t\thandle = attrHandle[ lowercaseName ];\n\t\t\tattrHandle[ lowercaseName ] = ret;\n\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\tlowercaseName :\n\t\t\t\tnull;\n\t\t\tattrHandle[ lowercaseName ] = handle;\n\t\t}\n\t\treturn ret;\n\t};\n} );\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button)$/i,\n\trclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend( {\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tdelete this[ jQuery.propFix[ name ] || name ];\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set properties on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\treturn ( elem[ name ] = value );\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\treturn elem[ name ];\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\t// Support: IE <=9 - 11 only\n\t\t\t\t// elem.tabIndex doesn't always return the\n\t\t\t\t// correct value when it hasn't been explicitly set\n\t\t\t\t// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\t// Use proper attribute retrieval(#12072)\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n\t\t\t\tif ( tabindex ) {\n\t\t\t\t\treturn parseInt( tabindex, 10 );\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\trfocusable.test( elem.nodeName ) ||\n\t\t\t\t\trclickable.test( elem.nodeName ) &&\n\t\t\t\t\telem.href\n\t\t\t\t) {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t},\n\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t}\n} );\n\n// Support: IE <=11 only\n// Accessing the selectedIndex property\n// forces the browser to respect setting selected\n// on the option\n// The getter ensures a default option is selected\n// when in an optgroup\n// eslint rule \"no-unused-expressions\" is disabled for this code\n// since it considers such accessions noop\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent && parent.parentNode ) {\n\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t\tset: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\njQuery.each( [\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n} );\n\n\n\n\n\t// Strip and collapse whitespace according to HTML spec\n\t// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace\n\tfunction stripAndCollapse( value ) {\n\t\tvar tokens = value.match( rnothtmlwhite ) || [];\n\t\treturn tokens.join( \" \" );\n\t}\n\n\nfunction getClass( elem ) {\n\treturn elem.getAttribute && elem.getAttribute( \"class\" ) || \"\";\n}\n\nfunction classesToArray( value ) {\n\tif ( Array.isArray( value ) ) {\n\t\treturn value;\n\t}\n\tif ( typeof value === \"string\" ) {\n\t\treturn value.match( rnothtmlwhite ) || [];\n\t}\n\treturn [];\n}\n\njQuery.fn.extend( {\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tclasses = classesToArray( value );\n\n\t\tif ( classes.length ) {\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tif ( !arguments.length ) {\n\t\t\treturn this.attr( \"class\", \"\" );\n\t\t}\n\n\t\tclasses = classesToArray( value );\n\n\t\tif ( classes.length ) {\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) > -1 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value,\n\t\t\tisValidValue = type === \"string\" || Array.isArray( value );\n\n\t\tif ( typeof stateVal === \"boolean\" && isValidValue ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).toggleClass(\n\t\t\t\t\tvalue.call( this, i, getClass( this ), stateVal ),\n\t\t\t\t\tstateVal\n\t\t\t\t);\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar className, i, self, classNames;\n\n\t\t\tif ( isValidValue ) {\n\n\t\t\t\t// Toggle individual class names\n\t\t\t\ti = 0;\n\t\t\t\tself = jQuery( this );\n\t\t\t\tclassNames = classesToArray( value );\n\n\t\t\t\twhile ( ( className = classNames[ i++ ] ) ) {\n\n\t\t\t\t\t// Check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( value === undefined || type === \"boolean\" ) {\n\t\t\t\tclassName = getClass( this );\n\t\t\t\tif ( className ) {\n\n\t\t\t\t\t// Store className if set\n\t\t\t\t\tdataPriv.set( this, \"__className__\", className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed `false`,\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tif ( this.setAttribute ) {\n\t\t\t\t\tthis.setAttribute( \"class\",\n\t\t\t\t\t\tclassName || value === false ?\n\t\t\t\t\t\t\"\" :\n\t\t\t\t\t\tdataPriv.get( this, \"__className__\" ) || \"\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className, elem,\n\t\t\ti = 0;\n\n\t\tclassName = \" \" + selector + \" \";\n\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\tif ( elem.nodeType === 1 &&\n\t\t\t\t( \" \" + stripAndCollapse( getClass( elem ) ) + \" \" ).indexOf( className ) > -1 ) {\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n} );\n\n\n\n\nvar rreturn = /\\r/g;\n\njQuery.fn.extend( {\n\tval: function( value ) {\n\t\tvar hooks, ret, valueIsFunction,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] ||\n\t\t\t\t\tjQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks &&\n\t\t\t\t\t\"get\" in hooks &&\n\t\t\t\t\t( ret = hooks.get( elem, \"value\" ) ) !== undefined\n\t\t\t\t) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\t// Handle most common string cases\n\t\t\t\tif ( typeof ret === \"string\" ) {\n\t\t\t\t\treturn ret.replace( rreturn, \"\" );\n\t\t\t\t}\n\n\t\t\t\t// Handle cases where value is null/undef or number\n\t\t\t\treturn ret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tvalueIsFunction = isFunction( value );\n\n\t\treturn this.each( function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\n\t\t\t} else if ( Array.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !( \"set\" in hooks ) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\tvar val = jQuery.find.attr( elem, \"value\" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\n\t\t\t\t\t// Support: IE <=10 - 11 only\n\t\t\t\t\t// option.text throws exceptions (#14686, #14858)\n\t\t\t\t\t// Strip and collapse whitespace\n\t\t\t\t\t// https://html.spec.whatwg.org/#strip-and-collapse-whitespace\n\t\t\t\t\tstripAndCollapse( jQuery.text( elem ) );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option, i,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\",\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length;\n\n\t\t\t\tif ( index < 0 ) {\n\t\t\t\t\ti = max;\n\n\t\t\t\t} else {\n\t\t\t\t\ti = one ? index : 0;\n\t\t\t\t}\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t// IE8-9 doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t!option.disabled &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled ||\n\t\t\t\t\t\t\t\t!nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t/* eslint-disable no-cond-assign */\n\n\t\t\t\t\tif ( option.selected =\n\t\t\t\t\t\tjQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1\n\t\t\t\t\t) {\n\t\t\t\t\t\toptionSet = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t/* eslint-enable no-cond-assign */\n\t\t\t\t}\n\n\t\t\t\t// Force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\t\t\t\treturn values;\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Radios and checkboxes getter/setter\njQuery.each( [ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( Array.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\treturn elem.getAttribute( \"value\" ) === null ? \"on\" : elem.value;\n\t\t};\n\t}\n} );\n\n\n\n\n// Return jQuery for attributes-only inclusion\n\n\nsupport.focusin = \"onfocusin\" in window;\n\n\nvar rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\tstopPropagationCallback = function( e ) {\n\t\te.stopPropagation();\n\t};\n\njQuery.extend( jQuery.event, {\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\n\t\tvar i, cur, tmp, bubbleType, ontype, handle, special, lastElement,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split( \".\" ) : [];\n\n\t\tcur = lastElement = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf( \".\" ) > -1 ) {\n\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split( \".\" );\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf( \":\" ) < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join( \".\" );\n\t\tevent.rnamespace = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === ( elem.ownerDocument || document ) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tlastElement = cur;\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = (\n\t\t\t\t\tdataPriv.get( cur, \"events\" ) || Object.create( null )\n\t\t\t\t)[ event.type ] &&\n\t\t\t\tdataPriv.get( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( ( !special._default ||\n\t\t\t\tspecial._default.apply( eventPath.pop(), data ) === false ) &&\n\t\t\t\tacceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name as the event.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.addEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\telem[ type ]();\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.removeEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\t// Piggyback on a donor event to simulate a different one\n\t// Used only for `focus(in | out)` events\n\tsimulate: function( type, elem, event ) {\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true\n\t\t\t}\n\t\t);\n\n\t\tjQuery.event.trigger( e, null, elem );\n\t}\n\n} );\n\njQuery.fn.extend( {\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t} );\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[ 0 ];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n} );\n\n\n// Support: Firefox <=44\n// Firefox doesn't have focus(in | out) events\n// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787\n//\n// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1\n// focus(in | out) events fire after focus & blur events,\n// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order\n// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857\nif ( !support.focusin ) {\n\tjQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );\n\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\n\t\t\t\t// Handle: regular nodes (via `this.ownerDocument`), window\n\t\t\t\t// (via `this.document`) & document (via `this`).\n\t\t\t\tvar doc = this.ownerDocument || this.document || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tdataPriv.access( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this.document || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tdataPriv.remove( doc, fix );\n\n\t\t\t\t} else {\n\t\t\t\t\tdataPriv.access( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t} );\n}\nvar location = window.location;\n\nvar nonce = { guid: Date.now() };\n\nvar rquery = ( /\\?/ );\n\n\n\n// Cross-browser xml parsing\njQuery.parseXML = function( data ) {\n\tvar xml;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\n\t// Support: IE 9 - 11 only\n\t// IE throws on parseFromString with invalid input.\n\ttry {\n\t\txml = ( new window.DOMParser() ).parseFromString( data, \"text/xml\" );\n\t} catch ( e ) {\n\t\txml = undefined;\n\t}\n\n\tif ( !xml || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\tjQuery.error( \"Invalid XML: \" + data );\n\t}\n\treturn xml;\n};\n\n\nvar\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( Array.isArray( obj ) ) {\n\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams(\n\t\t\t\t\tprefix + \"[\" + ( typeof v === \"object\" && v != null ? i : \"\" ) + \"]\",\n\t\t\t\t\tv,\n\t\t\t\t\ttraditional,\n\t\t\t\t\tadd\n\t\t\t\t);\n\t\t\t}\n\t\t} );\n\n\t} else if ( !traditional && toType( obj ) === \"object\" ) {\n\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, valueOrFunction ) {\n\n\t\t\t// If value is a function, invoke it and use its return value\n\t\t\tvar value = isFunction( valueOrFunction ) ?\n\t\t\t\tvalueOrFunction() :\n\t\t\t\tvalueOrFunction;\n\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" +\n\t\t\t\tencodeURIComponent( value == null ? \"\" : value );\n\t\t};\n\n\tif ( a == null ) {\n\t\treturn \"\";\n\t}\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t} );\n\n\t} else {\n\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" );\n};\n\njQuery.fn.extend( {\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map( function() {\n\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t} )\n\t\t.filter( function() {\n\t\t\tvar type = this.type;\n\n\t\t\t// Use .is( \":disabled\" ) so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t} )\n\t\t.map( function( _i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\tif ( val == null ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif ( Array.isArray( val ) ) {\n\t\t\t\treturn jQuery.map( val, function( val ) {\n\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t} ).get();\n\t}\n} );\n\n\nvar\n\tr20 = /%20/g,\n\trhash = /#.*$/,\n\trantiCache = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)$/mg,\n\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat( \"*\" ),\n\n\t// Anchor tag for parsing the document origin\n\toriginAnchor = document.createElement( \"a\" );\n\toriginAnchor.href = location.href;\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];\n\n\t\tif ( isFunction( func ) ) {\n\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( ( dataType = dataTypes[ i++ ] ) ) {\n\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType[ 0 ] === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" &&\n\t\t\t\t!seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t} );\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar key, deep,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n\tvar ct, type, finalDataType, firstDataType,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader( \"Content-Type\" );\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[ 0 ] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s.throws ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tstate: \"parsererror\",\n\t\t\t\t\t\t\t\terror: conv ? e : \"No conversion from \" + prev + \" to \" + current\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend( {\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: location.href,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( location.protocol ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /\\bxml\\b/,\n\t\t\thtml: /\\bhtml/,\n\t\t\tjson: /\\bjson\\b/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": JSON.parse,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar transport,\n\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\n\t\t\t// Response headers\n\t\t\tresponseHeadersString,\n\t\t\tresponseHeaders,\n\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\n\t\t\t// Url cleanup var\n\t\t\turlAnchor,\n\n\t\t\t// Request state (becomes false upon send and true upon completion)\n\t\t\tcompleted,\n\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\n\t\t\t// Loop variable\n\t\t\ti,\n\n\t\t\t// uncached part of the url\n\t\t\tuncached,\n\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context &&\n\t\t\t\t( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\t\tjQuery.event,\n\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks( \"once memory\" ),\n\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( completed ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( ( match = rheaders.exec( responseHeadersString ) ) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[ 1 ].toLowerCase() + \" \" ] =\n\t\t\t\t\t\t\t\t\t( responseHeaders[ match[ 1 ].toLowerCase() + \" \" ] || [] )\n\t\t\t\t\t\t\t\t\t\t.concat( match[ 2 ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() + \" \" ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match.join( \", \" );\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn completed ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\tname = requestHeadersNames[ name.toLowerCase() ] =\n\t\t\t\t\t\t\trequestHeadersNames[ name.toLowerCase() ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( completed ) {\n\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Lazy-add the new callbacks in a way that preserves old ones\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR );\n\n\t\t// Add protocol if not provided (prefilters might expect it)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || location.href ) + \"\" )\n\t\t\t.replace( rprotocol, location.protocol + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = ( s.dataType || \"*\" ).toLowerCase().match( rnothtmlwhite ) || [ \"\" ];\n\n\t\t// A cross-domain request is in order when the origin doesn't match the current origin.\n\t\tif ( s.crossDomain == null ) {\n\t\t\turlAnchor = document.createElement( \"a\" );\n\n\t\t\t// Support: IE <=8 - 11, Edge 12 - 15\n\t\t\t// IE throws exception on accessing the href property if url is malformed,\n\t\t\t// e.g. http://example.com:80x/\n\t\t\ttry {\n\t\t\t\turlAnchor.href = s.url;\n\n\t\t\t\t// Support: IE <=8 - 11 only\n\t\t\t\t// Anchor's host property isn't correctly set when s.url is relative\n\t\t\t\turlAnchor.href = urlAnchor.href;\n\t\t\t\ts.crossDomain = originAnchor.protocol + \"//\" + originAnchor.host !==\n\t\t\t\t\turlAnchor.protocol + \"//\" + urlAnchor.host;\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// If there is an error parsing the URL, assume it is crossDomain,\n\t\t\t\t// it can be rejected by the transport if it is invalid\n\t\t\t\ts.crossDomain = true;\n\t\t\t}\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( completed ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\t// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)\n\t\tfireGlobals = jQuery.event && s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger( \"ajaxStart\" );\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\t// Remove hash to simplify url manipulation\n\t\tcacheURL = s.url.replace( rhash, \"\" );\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// Remember the hash so we can put it back\n\t\t\tuncached = s.url.slice( cacheURL.length );\n\n\t\t\t// If data is available and should be processed, append data to url\n\t\t\tif ( s.data && ( s.processData || typeof s.data === \"string\" ) ) {\n\t\t\t\tcacheURL += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data;\n\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add or update anti-cache param if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\tcacheURL = cacheURL.replace( rantiCache, \"$1\" );\n\t\t\t\tuncached = ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + ( nonce.guid++ ) +\n\t\t\t\t\tuncached;\n\t\t\t}\n\n\t\t\t// Put hash and anti-cache on the URL that will be requested (gh-1732)\n\t\t\ts.url = cacheURL + uncached;\n\n\t\t// Change '%20' to '+' if this is encoded form body content (gh-2658)\n\t\t} else if ( s.data && s.processData &&\n\t\t\t( s.contentType || \"\" ).indexOf( \"application/x-www-form-urlencoded\" ) === 0 ) {\n\t\t\ts.data = s.data.replace( r20, \"+\" );\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[ 0 ] ] +\n\t\t\t\t\t( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend &&\n\t\t\t( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {\n\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// Aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tcompleteDeferred.add( s.complete );\n\t\tjqXHR.done( s.success );\n\t\tjqXHR.fail( s.error );\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\n\t\t\t// If request was aborted inside ajaxSend, stop there\n\t\t\tif ( completed ) {\n\t\t\t\treturn jqXHR;\n\t\t\t}\n\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = window.setTimeout( function() {\n\t\t\t\t\tjqXHR.abort( \"timeout\" );\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tcompleted = false;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// Rethrow post-completion exceptions\n\t\t\t\tif ( completed ) {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\n\t\t\t\t// Propagate others as results\n\t\t\t\tdone( -1, e );\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Ignore repeat invocations\n\t\t\tif ( completed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcompleted = true;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\twindow.clearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Use a noop converter for missing script\n\t\t\tif ( !isSuccess && jQuery.inArray( \"script\", s.dataTypes ) > -1 ) {\n\t\t\t\ts.converters[ \"text script\" ] = function() {};\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"Last-Modified\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"etag\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\n\t\t\t\t// Extract error from statusText and normalize for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger( \"ajaxStop\" );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n} );\n\njQuery.each( [ \"get\", \"post\" ], function( _i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\n\t\t// Shift arguments if data argument was omitted\n\t\tif ( isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\t// The url can be an options object (which then must have .url)\n\t\treturn jQuery.ajax( jQuery.extend( {\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t}, jQuery.isPlainObject( url ) && url ) );\n\t};\n} );\n\njQuery.ajaxPrefilter( function( s ) {\n\tvar i;\n\tfor ( i in s.headers ) {\n\t\tif ( i.toLowerCase() === \"content-type\" ) {\n\t\t\ts.contentType = s.headers[ i ] || \"\";\n\t\t}\n\t}\n} );\n\n\njQuery._evalUrl = function( url, options, doc ) {\n\treturn jQuery.ajax( {\n\t\turl: url,\n\n\t\t// Make this explicit, since user can override this through ajaxSetup (#11264)\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tcache: true,\n\t\tasync: false,\n\t\tglobal: false,\n\n\t\t// Only evaluate the response if it is successful (gh-4126)\n\t\t// dataFilter is not invoked for failure responses, so using it instead\n\t\t// of the default converter is kludgy but it works.\n\t\tconverters: {\n\t\t\t\"text script\": function() {}\n\t\t},\n\t\tdataFilter: function( response ) {\n\t\t\tjQuery.globalEval( response, options, doc );\n\t\t}\n\t} );\n};\n\n\njQuery.fn.extend( {\n\twrapAll: function( html ) {\n\t\tvar wrap;\n\n\t\tif ( this[ 0 ] ) {\n\t\t\tif ( isFunction( html ) ) {\n\t\t\t\thtml = html.call( this[ 0 ] );\n\t\t\t}\n\n\t\t\t// The elements to wrap the target around\n\t\t\twrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );\n\n\t\t\tif ( this[ 0 ].parentNode ) {\n\t\t\t\twrap.insertBefore( this[ 0 ] );\n\t\t\t}\n\n\t\t\twrap.map( function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstElementChild ) {\n\t\t\t\t\telem = elem.firstElementChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t} ).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( isFunction( html ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).wrapInner( html.call( this, i ) );\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t} );\n\t},\n\n\twrap: function( html ) {\n\t\tvar htmlIsFunction = isFunction( html );\n\n\t\treturn this.each( function( i ) {\n\t\t\tjQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );\n\t\t} );\n\t},\n\n\tunwrap: function( selector ) {\n\t\tthis.parent( selector ).not( \"body\" ).each( function() {\n\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t} );\n\t\treturn this;\n\t}\n} );\n\n\njQuery.expr.pseudos.hidden = function( elem ) {\n\treturn !jQuery.expr.pseudos.visible( elem );\n};\njQuery.expr.pseudos.visible = function( elem ) {\n\treturn !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );\n};\n\n\n\n\njQuery.ajaxSettings.xhr = function() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch ( e ) {}\n};\n\nvar xhrSuccessStatus = {\n\n\t\t// File protocol always yields status code 0, assume 200\n\t\t0: 200,\n\n\t\t// Support: IE <=9 only\n\t\t// #1450: sometimes IE returns 1223 when it should be 204\n\t\t1223: 204\n\t},\n\txhrSupported = jQuery.ajaxSettings.xhr();\n\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nsupport.ajax = xhrSupported = !!xhrSupported;\n\njQuery.ajaxTransport( function( options ) {\n\tvar callback, errorCallback;\n\n\t// Cross domain only allowed if supported through XMLHttpRequest\n\tif ( support.cors || xhrSupported && !options.crossDomain ) {\n\t\treturn {\n\t\t\tsend: function( headers, complete ) {\n\t\t\t\tvar i,\n\t\t\t\t\txhr = options.xhr();\n\n\t\t\t\txhr.open(\n\t\t\t\t\toptions.type,\n\t\t\t\t\toptions.url,\n\t\t\t\t\toptions.async,\n\t\t\t\t\toptions.username,\n\t\t\t\t\toptions.password\n\t\t\t\t);\n\n\t\t\t\t// Apply custom fields if provided\n\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Override mime type if needed\n\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t}\n\n\t\t\t\t// X-Requested-With header\n\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\tif ( !options.crossDomain && !headers[ \"X-Requested-With\" ] ) {\n\t\t\t\t\theaders[ \"X-Requested-With\" ] = \"XMLHttpRequest\";\n\t\t\t\t}\n\n\t\t\t\t// Set headers\n\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t}\n\n\t\t\t\t// Callback\n\t\t\t\tcallback = function( type ) {\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\tcallback = errorCallback = xhr.onload =\n\t\t\t\t\t\t\t\txhr.onerror = xhr.onabort = xhr.ontimeout =\n\t\t\t\t\t\t\t\t\txhr.onreadystatechange = null;\n\n\t\t\t\t\t\t\tif ( type === \"abort\" ) {\n\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t} else if ( type === \"error\" ) {\n\n\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t// On a manual native abort, IE9 throws\n\t\t\t\t\t\t\t\t// errors on any property access that is not readyState\n\t\t\t\t\t\t\t\tif ( typeof xhr.status !== \"number\" ) {\n\t\t\t\t\t\t\t\t\tcomplete( 0, \"error\" );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcomplete(\n\n\t\t\t\t\t\t\t\t\t\t// File: protocol always yields status 0; see #8605, #14207\n\t\t\t\t\t\t\t\t\t\txhr.status,\n\t\t\t\t\t\t\t\t\t\txhr.statusText\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcomplete(\n\t\t\t\t\t\t\t\t\txhrSuccessStatus[ xhr.status ] || xhr.status,\n\t\t\t\t\t\t\t\t\txhr.statusText,\n\n\t\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t\t// IE9 has no XHR2 but throws on binary (trac-11426)\n\t\t\t\t\t\t\t\t\t// For XHR2 non-text, let the caller handle it (gh-2498)\n\t\t\t\t\t\t\t\t\t( xhr.responseType || \"text\" ) !== \"text\"  ||\n\t\t\t\t\t\t\t\t\ttypeof xhr.responseText !== \"string\" ?\n\t\t\t\t\t\t\t\t\t\t{ binary: xhr.response } :\n\t\t\t\t\t\t\t\t\t\t{ text: xhr.responseText },\n\t\t\t\t\t\t\t\t\txhr.getAllResponseHeaders()\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t};\n\n\t\t\t\t// Listen to events\n\t\t\t\txhr.onload = callback();\n\t\t\t\terrorCallback = xhr.onerror = xhr.ontimeout = callback( \"error\" );\n\n\t\t\t\t// Support: IE 9 only\n\t\t\t\t// Use onreadystatechange to replace onabort\n\t\t\t\t// to handle uncaught aborts\n\t\t\t\tif ( xhr.onabort !== undefined ) {\n\t\t\t\t\txhr.onabort = errorCallback;\n\t\t\t\t} else {\n\t\t\t\t\txhr.onreadystatechange = function() {\n\n\t\t\t\t\t\t// Check readyState before timeout as it changes\n\t\t\t\t\t\tif ( xhr.readyState === 4 ) {\n\n\t\t\t\t\t\t\t// Allow onerror to be called first,\n\t\t\t\t\t\t\t// but that will not handle a native abort\n\t\t\t\t\t\t\t// Also, save errorCallback to a variable\n\t\t\t\t\t\t\t// as xhr.onerror cannot be accessed\n\t\t\t\t\t\t\twindow.setTimeout( function() {\n\t\t\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\t\t\terrorCallback();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Create the abort callback\n\t\t\t\tcallback = callback( \"abort\" );\n\n\t\t\t\ttry {\n\n\t\t\t\t\t// Do send the request (this may raise an exception)\n\t\t\t\t\txhr.send( options.hasContent && options.data || null );\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t// #14683: Only rethrow if this hasn't been notified as an error yet\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tthrow e;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\n// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)\njQuery.ajaxPrefilter( function( s ) {\n\tif ( s.crossDomain ) {\n\t\ts.contents.script = false;\n\t}\n} );\n\n// Install script dataType\njQuery.ajaxSetup( {\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, \" +\n\t\t\t\"application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /\\b(?:java|ecma)script\\b/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n} );\n\n// Handle cache's special case and crossDomain\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t}\n} );\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function( s ) {\n\n\t// This transport only deals with cross domain or forced-by-attrs requests\n\tif ( s.crossDomain || s.scriptAttrs ) {\n\t\tvar script, callback;\n\t\treturn {\n\t\t\tsend: function( _, complete ) {\n\t\t\t\tscript = jQuery( \"<script>\" )\n\t\t\t\t\t.attr( s.scriptAttrs || {} )\n\t\t\t\t\t.prop( { charset: s.scriptCharset, src: s.url } )\n\t\t\t\t\t.on( \"load error\", callback = function( evt ) {\n\t\t\t\t\t\tscript.remove();\n\t\t\t\t\t\tcallback = null;\n\t\t\t\t\t\tif ( evt ) {\n\t\t\t\t\t\t\tcomplete( evt.type === \"error\" ? 404 : 200, evt.type );\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\n\t\t\t\t// Use native DOM manipulation to avoid our domManip AJAX trickery\n\t\t\t\tdocument.head.appendChild( script[ 0 ] );\n\t\t\t},\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup( {\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce.guid++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n} );\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" &&\n\t\t\t\t( s.contentType || \"\" )\n\t\t\t\t\t.indexOf( \"application/x-www-form-urlencoded\" ) === 0 &&\n\t\t\t\trjsonp.test( s.data ) && \"data\"\n\t\t);\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\n\t\t// Insert callback into url or form data\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[ \"script json\" ] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// Force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always( function() {\n\n\t\t\t// If previous value didn't exist - remove it\n\t\t\tif ( overwritten === undefined ) {\n\t\t\t\tjQuery( window ).removeProp( callbackName );\n\n\t\t\t// Otherwise restore preexisting value\n\t\t\t} else {\n\t\t\t\twindow[ callbackName ] = overwritten;\n\t\t\t}\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\n\t\t\t\t// Make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// Save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t} );\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n} );\n\n\n\n\n// Support: Safari 8 only\n// In Safari 8 documents created via document.implementation.createHTMLDocument\n// collapse sibling forms: the second one becomes a child of the first one.\n// Because of that, this security measure has to be disabled in Safari 8.\n// https://bugs.webkit.org/show_bug.cgi?id=137337\nsupport.createHTMLDocument = ( function() {\n\tvar body = document.implementation.createHTMLDocument( \"\" ).body;\n\tbody.innerHTML = \"<form></form><form></form>\";\n\treturn body.childNodes.length === 2;\n} )();\n\n\n// Argument \"data\" should be string of html\n// context (optional): If specified, the fragment will be created in this context,\n// defaults to document\n// keepScripts (optional): If true, will include scripts passed in the html string\njQuery.parseHTML = function( data, context, keepScripts ) {\n\tif ( typeof data !== \"string\" ) {\n\t\treturn [];\n\t}\n\tif ( typeof context === \"boolean\" ) {\n\t\tkeepScripts = context;\n\t\tcontext = false;\n\t}\n\n\tvar base, parsed, scripts;\n\n\tif ( !context ) {\n\n\t\t// Stop scripts or inline event handlers from being executed immediately\n\t\t// by using document.implementation\n\t\tif ( support.createHTMLDocument ) {\n\t\t\tcontext = document.implementation.createHTMLDocument( \"\" );\n\n\t\t\t// Set the base href for the created document\n\t\t\t// so any parsed elements with URLs\n\t\t\t// are based on the document's URL (gh-2965)\n\t\t\tbase = context.createElement( \"base\" );\n\t\t\tbase.href = document.location.href;\n\t\t\tcontext.head.appendChild( base );\n\t\t} else {\n\t\t\tcontext = document;\n\t\t}\n\t}\n\n\tparsed = rsingleTag.exec( data );\n\tscripts = !keepScripts && [];\n\n\t// Single tag\n\tif ( parsed ) {\n\t\treturn [ context.createElement( parsed[ 1 ] ) ];\n\t}\n\n\tparsed = buildFragment( [ data ], context, scripts );\n\n\tif ( scripts && scripts.length ) {\n\t\tjQuery( scripts ).remove();\n\t}\n\n\treturn jQuery.merge( [], parsed.childNodes );\n};\n\n\n/**\n * Load a url into a page\n */\njQuery.fn.load = function( url, params, callback ) {\n\tvar selector, type, response,\n\t\tself = this,\n\t\toff = url.indexOf( \" \" );\n\n\tif ( off > -1 ) {\n\t\tselector = stripAndCollapse( url.slice( off ) );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// If we have elements to modify, make the request\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax( {\n\t\t\turl: url,\n\n\t\t\t// If \"type\" variable is undefined, then \"GET\" method will be used.\n\t\t\t// Make value of this field explicit since\n\t\t\t// user can override it through ajaxSetup method\n\t\t\ttype: type || \"GET\",\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t} ).done( function( responseText ) {\n\n\t\t\t// Save response for use in complete callback\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\n\t\t\t\t// If a selector was specified, locate the right elements in a dummy div\n\t\t\t\t// Exclude scripts to avoid IE 'Permission Denied' errors\n\t\t\t\tjQuery( \"<div>\" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n\t\t\t\t// Otherwise use the full result\n\t\t\t\tresponseText );\n\n\t\t// If the request succeeds, this function gets \"data\", \"status\", \"jqXHR\"\n\t\t// but they are ignored because response was set above.\n\t\t// If it fails, this function gets \"jqXHR\", \"status\", \"error\"\n\t\t} ).always( callback && function( jqXHR, status ) {\n\t\t\tself.each( function() {\n\t\t\t\tcallback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t\t} );\n\t\t} );\n\t}\n\n\treturn this;\n};\n\n\n\n\njQuery.expr.pseudos.animated = function( elem ) {\n\treturn jQuery.grep( jQuery.timers, function( fn ) {\n\t\treturn elem === fn.elem;\n\t} ).length;\n};\n\n\n\n\njQuery.offset = {\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, \"position\" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\n\t\t// Set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, \"top\" );\n\t\tcurCSSLeft = jQuery.css( elem, \"left\" );\n\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) &&\n\t\t\t( curCSSTop + curCSSLeft ).indexOf( \"auto\" ) > -1;\n\n\t\t// Need to be able to calculate position if either\n\t\t// top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( isFunction( options ) ) {\n\n\t\t\t// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)\n\t\t\toptions = options.call( elem, i, jQuery.extend( {}, curOffset ) );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\n\t\t} else {\n\t\t\tif ( typeof props.top === \"number\" ) {\n\t\t\t\tprops.top += \"px\";\n\t\t\t}\n\t\t\tif ( typeof props.left === \"number\" ) {\n\t\t\t\tprops.left += \"px\";\n\t\t\t}\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\njQuery.fn.extend( {\n\n\t// offset() relates an element's border box to the document origin\n\toffset: function( options ) {\n\n\t\t// Preserve chaining for setter\n\t\tif ( arguments.length ) {\n\t\t\treturn options === undefined ?\n\t\t\t\tthis :\n\t\t\t\tthis.each( function( i ) {\n\t\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t\t} );\n\t\t}\n\n\t\tvar rect, win,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !elem ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Return zeros for disconnected and hidden (display: none) elements (gh-2310)\n\t\t// Support: IE <=11 only\n\t\t// Running getBoundingClientRect on a\n\t\t// disconnected node in IE throws an error\n\t\tif ( !elem.getClientRects().length ) {\n\t\t\treturn { top: 0, left: 0 };\n\t\t}\n\n\t\t// Get document-relative position by adding viewport scroll to viewport-relative gBCR\n\t\trect = elem.getBoundingClientRect();\n\t\twin = elem.ownerDocument.defaultView;\n\t\treturn {\n\t\t\ttop: rect.top + win.pageYOffset,\n\t\t\tleft: rect.left + win.pageXOffset\n\t\t};\n\t},\n\n\t// position() relates an element's margin box to its offset parent's padding box\n\t// This corresponds to the behavior of CSS absolute positioning\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset, doc,\n\t\t\telem = this[ 0 ],\n\t\t\tparentOffset = { top: 0, left: 0 };\n\n\t\t// position:fixed elements are offset from the viewport, which itself always has zero offset\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\n\t\t\t// Assume position:fixed implies availability of getBoundingClientRect\n\t\t\toffset = elem.getBoundingClientRect();\n\n\t\t} else {\n\t\t\toffset = this.offset();\n\n\t\t\t// Account for the *real* offset parent, which can be the document or its root element\n\t\t\t// when a statically positioned element is identified\n\t\t\tdoc = elem.ownerDocument;\n\t\t\toffsetParent = elem.offsetParent || doc.documentElement;\n\t\t\twhile ( offsetParent &&\n\t\t\t\t( offsetParent === doc.body || offsetParent === doc.documentElement ) &&\n\t\t\t\tjQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\n\t\t\t\toffsetParent = offsetParent.parentNode;\n\t\t\t}\n\t\t\tif ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {\n\n\t\t\t\t// Incorporate borders into its offset, since they are outside its content origin\n\t\t\t\tparentOffset = jQuery( offsetParent ).offset();\n\t\t\t\tparentOffset.top += jQuery.css( offsetParent, \"borderTopWidth\", true );\n\t\t\t\tparentOffset.left += jQuery.css( offsetParent, \"borderLeftWidth\", true );\n\t\t\t}\n\t\t}\n\n\t\t// Subtract parent offsets and element margins\n\t\treturn {\n\t\t\ttop: offset.top - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true )\n\t\t};\n\t},\n\n\t// This method will return documentElement in the following cases:\n\t// 1) For the element inside the iframe without offsetParent, this method will return\n\t//    documentElement of the parent window\n\t// 2) For the hidden or detached element\n\t// 3) For body or html element, i.e. in case of the html node - it will return itself\n\t//\n\t// but those exceptions were never presented as a real life use-cases\n\t// and might be considered as more preferable results.\n\t//\n\t// This logic, however, is not guaranteed and can change at any point in the future\n\toffsetParent: function() {\n\t\treturn this.map( function() {\n\t\t\tvar offsetParent = this.offsetParent;\n\n\t\t\twhile ( offsetParent && jQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\n\t\t\treturn offsetParent || documentElement;\n\t\t} );\n\t}\n} );\n\n// Create scrollLeft and scrollTop methods\njQuery.each( { scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\" }, function( method, prop ) {\n\tvar top = \"pageYOffset\" === prop;\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn access( this, function( elem, method, val ) {\n\n\t\t\t// Coalesce documents and windows\n\t\t\tvar win;\n\t\t\tif ( isWindow( elem ) ) {\n\t\t\t\twin = elem;\n\t\t\t} else if ( elem.nodeType === 9 ) {\n\t\t\t\twin = elem.defaultView;\n\t\t\t}\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? win[ prop ] : elem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : win.pageXOffset,\n\t\t\t\t\ttop ? val : win.pageYOffset\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length );\n\t};\n} );\n\n// Support: Safari <=7 - 9.1, Chrome <=37 - 49\n// Add the top/left cssHooks using jQuery.fn.position\n// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347\n// getComputedStyle returns percent when specified for top/left/bottom/right;\n// rather than make the css module depend on the offset module, just check for it here\njQuery.each( [ \"top\", \"left\" ], function( _i, prop ) {\n\tjQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,\n\t\tfunction( elem, computed ) {\n\t\t\tif ( computed ) {\n\t\t\t\tcomputed = curCSS( elem, prop );\n\n\t\t\t\t// If curCSS returns percentage, fallback to offset\n\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\tcomputed;\n\t\t\t}\n\t\t}\n\t);\n} );\n\n\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name },\n\t\tfunction( defaultExtra, funcName ) {\n\n\t\t// Margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( isWindow( elem ) ) {\n\n\t\t\t\t\t// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)\n\t\t\t\t\treturn funcName.indexOf( \"outer\" ) === 0 ?\n\t\t\t\t\t\telem[ \"inner\" + name ] :\n\t\t\t\t\t\telem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],\n\t\t\t\t\t// whichever is greatest\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable );\n\t\t};\n\t} );\n} );\n\n\njQuery.each( [\n\t\"ajaxStart\",\n\t\"ajaxStop\",\n\t\"ajaxComplete\",\n\t\"ajaxError\",\n\t\"ajaxSuccess\",\n\t\"ajaxSend\"\n], function( _i, type ) {\n\tjQuery.fn[ type ] = function( fn ) {\n\t\treturn this.on( type, fn );\n\t};\n} );\n\n\n\n\njQuery.fn.extend( {\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ?\n\t\t\tthis.off( selector, \"**\" ) :\n\t\t\tthis.off( types, selector || \"**\", fn );\n\t},\n\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t}\n} );\n\njQuery.each( ( \"blur focus focusin focusout resize scroll click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup contextmenu\" ).split( \" \" ),\n\tfunction( _i, name ) {\n\n\t\t// Handle event binding\n\t\tjQuery.fn[ name ] = function( data, fn ) {\n\t\t\treturn arguments.length > 0 ?\n\t\t\t\tthis.on( name, null, data, fn ) :\n\t\t\t\tthis.trigger( name );\n\t\t};\n\t} );\n\n\n\n\n// Support: Android <=4.0 only\n// Make sure we trim BOM and NBSP\nvar rtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g;\n\n// Bind a function to a context, optionally partially applying any\n// arguments.\n// jQuery.proxy is deprecated to promote standards (specifically Function#bind)\n// However, it is not slated for removal any time soon\njQuery.proxy = function( fn, context ) {\n\tvar tmp, args, proxy;\n\n\tif ( typeof context === \"string\" ) {\n\t\ttmp = fn[ context ];\n\t\tcontext = fn;\n\t\tfn = tmp;\n\t}\n\n\t// Quick check to determine if target is callable, in the spec\n\t// this throws a TypeError, but we will just return undefined.\n\tif ( !isFunction( fn ) ) {\n\t\treturn undefined;\n\t}\n\n\t// Simulated bind\n\targs = slice.call( arguments, 2 );\n\tproxy = function() {\n\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t};\n\n\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\treturn proxy;\n};\n\njQuery.holdReady = function( hold ) {\n\tif ( hold ) {\n\t\tjQuery.readyWait++;\n\t} else {\n\t\tjQuery.ready( true );\n\t}\n};\njQuery.isArray = Array.isArray;\njQuery.parseJSON = JSON.parse;\njQuery.nodeName = nodeName;\njQuery.isFunction = isFunction;\njQuery.isWindow = isWindow;\njQuery.camelCase = camelCase;\njQuery.type = toType;\n\njQuery.now = Date.now;\n\njQuery.isNumeric = function( obj ) {\n\n\t// As of jQuery 3.0, isNumeric is limited to\n\t// strings and numbers (primitives or objects)\n\t// that can be coerced to finite numbers (gh-2662)\n\tvar type = jQuery.type( obj );\n\treturn ( type === \"number\" || type === \"string\" ) &&\n\n\t\t// parseFloat NaNs numeric-cast false positives (\"\")\n\t\t// ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n\t\t// subtraction forces infinities to NaN\n\t\t!isNaN( obj - parseFloat( obj ) );\n};\n\njQuery.trim = function( text ) {\n\treturn text == null ?\n\t\t\"\" :\n\t\t( text + \"\" ).replace( rtrim, \"\" );\n};\n\n\n\n// Register as a named AMD module, since jQuery can be concatenated with other\n// files that may use define, but not via a proper concatenation script that\n// understands anonymous AMD modules. A named AMD is safest and most robust\n// way to register. Lowercase jquery is used because AMD module names are\n// derived from file names, and jQuery is normally delivered in a lowercase\n// file name. Do this after creating the global so that if an AMD module wants\n// to call noConflict to hide this version of jQuery, it will work.\n\n// Note that for maximum portability, libraries that are not jQuery should\n// declare themselves as anonymous modules, and avoid setting a global if an\n// AMD loader is present. jQuery is a special case. For more information, see\n// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon\n\nif ( typeof define === \"function\" && define.amd ) {\n\tdefine( \"jquery\", [], function() {\n\t\treturn jQuery;\n\t} );\n}\n\n\n\n\nvar\n\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$;\n\njQuery.noConflict = function( deep ) {\n\tif ( window.$ === jQuery ) {\n\t\twindow.$ = _$;\n\t}\n\n\tif ( deep && window.jQuery === jQuery ) {\n\t\twindow.jQuery = _jQuery;\n\t}\n\n\treturn jQuery;\n};\n\n// Expose jQuery and $ identifiers, even in AMD\n// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n// and CommonJS for browser emulators (#13566)\nif ( typeof noGlobal === \"undefined\" ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\n\n\n\nreturn jQuery;\n} );\n"
  },
  {
    "path": "docs/_static/jquery.js",
    "content": "/*! jQuery v3.5.1 | (c) JS Foundation and other contributors | jquery.org/license */\n!function(e,t){\"use strict\";\"object\"==typeof module&&\"object\"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error(\"jQuery requires a window with a document\");return t(e)}:t(e)}(\"undefined\"!=typeof window?window:this,function(C,e){\"use strict\";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return\"function\"==typeof e&&\"number\"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement(\"script\");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+\"\":\"object\"==typeof e||\"function\"==typeof e?n[o.call(e)]||\"object\":typeof e}var f=\"3.5.1\",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&\"length\"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&(\"array\"===n||0===t||\"number\"==typeof t&&0<t&&t-1 in e)}S.fn=S.prototype={jquery:f,constructor:S,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=S.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return S.each(this,e)},map:function(n){return this.pushStack(S.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(S.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(S.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},S.extend=S.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for(\"boolean\"==typeof a&&(l=a,a=arguments[s]||{},s++),\"object\"==typeof a||m(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],\"__proto__\"!==t&&a!==r&&(l&&r&&(S.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||S.isPlainObject(n)?n:{},i=!1,a[t]=S.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},S.extend({expando:\"jQuery\"+(f+Math.random()).replace(/\\D/g,\"\"),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||\"[object Object]\"!==o.call(e))&&(!(t=r(e))||\"function\"==typeof(n=v.call(t,\"constructor\")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){b(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(p(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},makeArray:function(e,t){var n=t||[];return null!=e&&(p(Object(e))?S.merge(n,\"string\"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(p(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g(a)},guid:1,support:y}),\"function\"==typeof Symbol&&(S.fn[Symbol.iterator]=t[Symbol.iterator]),S.each(\"Boolean Number String Function Array Date RegExp Object Error Symbol\".split(\" \"),function(e,t){n[\"[object \"+t+\"]\"]=t.toLowerCase()});var d=function(n){var e,d,b,o,i,h,f,g,w,u,l,T,C,a,E,v,s,c,y,S=\"sizzle\"+1*new Date,p=n.document,k=0,r=0,m=ue(),x=ue(),A=ue(),N=ue(),D=function(e,t){return e===t&&(l=!0),0},j={}.hasOwnProperty,t=[],q=t.pop,L=t.push,H=t.push,O=t.slice,P=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},R=\"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",M=\"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",I=\"(?:\\\\\\\\[\\\\da-fA-F]{1,6}\"+M+\"?|\\\\\\\\[^\\\\r\\\\n\\\\f]|[\\\\w-]|[^\\0-\\\\x7f])+\",W=\"\\\\[\"+M+\"*(\"+I+\")(?:\"+M+\"*([*^$|!~]?=)\"+M+\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\"+I+\"))|)\"+M+\"*\\\\]\",F=\":(\"+I+\")(?:\\\\((('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\"+W+\")*)|.*)\\\\)|)\",B=new RegExp(M+\"+\",\"g\"),$=new RegExp(\"^\"+M+\"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\"+M+\"+$\",\"g\"),_=new RegExp(\"^\"+M+\"*,\"+M+\"*\"),z=new RegExp(\"^\"+M+\"*([>+~]|\"+M+\")\"+M+\"*\"),U=new RegExp(M+\"|>\"),X=new RegExp(F),V=new RegExp(\"^\"+I+\"$\"),G={ID:new RegExp(\"^#(\"+I+\")\"),CLASS:new RegExp(\"^\\\\.(\"+I+\")\"),TAG:new RegExp(\"^(\"+I+\"|[*])\"),ATTR:new RegExp(\"^\"+W),PSEUDO:new RegExp(\"^\"+F),CHILD:new RegExp(\"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\"+M+\"*(even|odd|(([+-]|)(\\\\d*)n|)\"+M+\"*(?:([+-]|)\"+M+\"*(\\\\d+)|))\"+M+\"*\\\\)|)\",\"i\"),bool:new RegExp(\"^(?:\"+R+\")$\",\"i\"),needsContext:new RegExp(\"^\"+M+\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\"+M+\"*((?:-\\\\d)?\\\\d*)\"+M+\"*\\\\)|)(?=[^-]|$)\",\"i\")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\\d$/i,K=/^[^{]+\\{\\s*\\[native \\w/,Z=/^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,ee=/[+~]/,te=new RegExp(\"\\\\\\\\[\\\\da-fA-F]{1,6}\"+M+\"?|\\\\\\\\([^\\\\r\\\\n\\\\f])\",\"g\"),ne=function(e,t){var n=\"0x\"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\0-\\x1f\\x7f-\\uFFFF\\w-]/g,ie=function(e,t){return t?\"\\0\"===e?\"\\ufffd\":e.slice(0,-1)+\"\\\\\"+e.charCodeAt(e.length-1).toString(16)+\" \":\"\\\\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&\"fieldset\"===e.nodeName.toLowerCase()},{dir:\"parentNode\",next:\"legend\"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],\"string\"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+\" \"]&&(!v||!v.test(t))&&(1!==p||\"object\"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute(\"id\"))?s=s.replace(re,ie):e.setAttribute(\"id\",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?\"#\"+s:\":scope\")+\" \"+xe(l[o]);c=l.join(\",\")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute(\"id\")}}}return g(t.replace($,\"$1\"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+\" \")>b.cacheLength&&delete e[r.shift()],e[t+\" \"]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement(\"fieldset\");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split(\"|\"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return\"input\"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return(\"input\"===t||\"button\"===t)&&e.type===n}}function ge(t){return function(e){return\"form\"in e?e.parentNode&&!1===e.disabled?\"label\"in e?\"label\"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:\"label\"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&\"undefined\"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||\"HTML\")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener(\"unload\",oe,!1):n.attachEvent&&n.attachEvent(\"onunload\",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement(\"div\")),\"undefined\"!=typeof e.querySelectorAll&&!e.querySelectorAll(\":scope fieldset div\").length}),d.attributes=ce(function(e){return e.className=\"i\",!e.getAttribute(\"className\")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment(\"\")),!e.getElementsByTagName(\"*\").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute(\"id\")===t}},b.find.ID=function(e,t){if(\"undefined\"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t=\"undefined\"!=typeof e.getAttributeNode&&e.getAttributeNode(\"id\");return t&&t.value===n}},b.find.ID=function(e,t){if(\"undefined\"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode(\"id\"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode(\"id\"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return\"undefined\"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if(\"*\"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if(\"undefined\"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML=\"<a id='\"+S+\"'></a><select id='\"+S+\"-\\r\\\\' msallowcapture=''><option selected=''></option></select>\",e.querySelectorAll(\"[msallowcapture^='']\").length&&v.push(\"[*^$]=\"+M+\"*(?:''|\\\"\\\")\"),e.querySelectorAll(\"[selected]\").length||v.push(\"\\\\[\"+M+\"*(?:value|\"+R+\")\"),e.querySelectorAll(\"[id~=\"+S+\"-]\").length||v.push(\"~=\"),(t=C.createElement(\"input\")).setAttribute(\"name\",\"\"),e.appendChild(t),e.querySelectorAll(\"[name='']\").length||v.push(\"\\\\[\"+M+\"*name\"+M+\"*=\"+M+\"*(?:''|\\\"\\\")\"),e.querySelectorAll(\":checked\").length||v.push(\":checked\"),e.querySelectorAll(\"a#\"+S+\"+*\").length||v.push(\".#.+[+~]\"),e.querySelectorAll(\"\\\\\\f\"),v.push(\"[\\\\r\\\\n\\\\f]\")}),ce(function(e){e.innerHTML=\"<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>\";var t=C.createElement(\"input\");t.setAttribute(\"type\",\"hidden\"),e.appendChild(t).setAttribute(\"name\",\"D\"),e.querySelectorAll(\"[name=d]\").length&&v.push(\"name\"+M+\"*[*^$|!~]?=\"),2!==e.querySelectorAll(\":enabled\").length&&v.push(\":enabled\",\":disabled\"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(\":disabled\").length&&v.push(\":enabled\",\":disabled\"),e.querySelectorAll(\"*,:x\"),v.push(\",.*:\")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,\"*\"),c.call(e,\"[s!='']:x\"),s.push(\"!=\",F)}),v=v.length&&new RegExp(v.join(\"|\")),s=s.length&&new RegExp(s.join(\"|\")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+\" \"]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0<se(t,C,null,[e]).length},se.contains=function(e,t){return(e.ownerDocument||e)!=C&&T(e),y(e,t)},se.attr=function(e,t){(e.ownerDocument||e)!=C&&T(e);var n=b.attrHandle[t.toLowerCase()],r=n&&j.call(b.attrHandle,t.toLowerCase())?n(e,t,!E):void 0;return void 0!==r?r:d.attributes||!E?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},se.escape=function(e){return(e+\"\").replace(re,ie)},se.error=function(e){throw new Error(\"Syntax error, unrecognized expression: \"+e)},se.uniqueSort=function(e){var t,n=[],r=0,i=0;if(l=!d.detectDuplicates,u=!d.sortStable&&e.slice(0),e.sort(D),l){while(t=e[i++])t===e[i]&&(r=n.push(i));while(r--)e.splice(n[r],1)}return u=null,e},o=se.getText=function(e){var t,n=\"\",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if(\"string\"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else while(t=e[r++])n+=o(t);return n},(b=se.selectors={cacheLength:50,createPseudo:le,match:G,attrHandle:{},find:{},relative:{\">\":{dir:\"parentNode\",first:!0},\" \":{dir:\"parentNode\"},\"+\":{dir:\"previousSibling\",first:!0},\"~\":{dir:\"previousSibling\"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||\"\").replace(te,ne),\"~=\"===e[2]&&(e[3]=\" \"+e[3]+\" \"),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),\"nth\"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*(\"even\"===e[3]||\"odd\"===e[3])),e[5]=+(e[7]+e[8]||\"odd\"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||\"\":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(\")\",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return\"*\"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+\" \"];return t||(t=new RegExp(\"(^|\"+M+\")\"+e+\"(\"+M+\"|$)\"))&&m(e,function(e){return t.test(\"string\"==typeof e.className&&e.className||\"undefined\"!=typeof e.getAttribute&&e.getAttribute(\"class\")||\"\")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?\"!=\"===r:!r||(t+=\"\",\"=\"===r?t===i:\"!=\"===r?t!==i:\"^=\"===r?i&&0===t.indexOf(i):\"*=\"===r?i&&-1<t.indexOf(i):\"$=\"===r?i&&t.slice(-i.length)===i:\"~=\"===r?-1<(\" \"+t.replace(B,\" \")+\" \").indexOf(i):\"|=\"===r&&(t===i||t.slice(0,i.length+1)===i+\"-\"))}},CHILD:function(h,e,t,g,v){var y=\"nth\"!==h.slice(0,3),m=\"last\"!==h.slice(-4),x=\"of-type\"===e;return 1===g&&0===v?function(e){return!!e.parentNode}:function(e,t,n){var r,i,o,a,s,u,l=y!==m?\"nextSibling\":\"previousSibling\",c=e.parentNode,f=x&&e.nodeName.toLowerCase(),p=!n&&!x,d=!1;if(c){if(y){while(l){a=e;while(a=a[l])if(x?a.nodeName.toLowerCase()===f:1===a.nodeType)return!1;u=l=\"only\"===h&&!u&&\"nextSibling\"}return!0}if(u=[m?c.firstChild:c.lastChild],m&&p){d=(s=(r=(i=(o=(a=c)[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1])&&r[2],a=s&&c.childNodes[s];while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if(1===a.nodeType&&++d&&a===e){i[h]=[k,s,d];break}}else if(p&&(d=s=(r=(i=(o=(a=e)[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1]),!1===d)while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if((x?a.nodeName.toLowerCase()===f:1===a.nodeType)&&++d&&(p&&((i=(o=a[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]=[k,d]),a===e))break;return(d-=v)===g||d%g==0&&0<=d/g}}},PSEUDO:function(e,o){var t,a=b.pseudos[e]||b.setFilters[e.toLowerCase()]||se.error(\"unsupported pseudo: \"+e);return a[S]?a(o):1<a.length?(t=[e,e,\"\",o],b.setFilters.hasOwnProperty(e.toLowerCase())?le(function(e,t){var n,r=a(e,o),i=r.length;while(i--)e[n=P(e,r[i])]=!(t[n]=r[i])}):function(e){return a(e,0,t)}):a}},pseudos:{not:le(function(e){var r=[],i=[],s=f(e.replace($,\"$1\"));return s[S]?le(function(e,t,n,r){var i,o=s(e,null,r,[]),a=e.length;while(a--)(i=o[a])&&(e[a]=!(t[a]=i))}):function(e,t,n){return r[0]=e,s(r,null,n,i),r[0]=null,!i.pop()}}),has:le(function(t){return function(e){return 0<se(t,e).length}}),contains:le(function(t){return t=t.replace(te,ne),function(e){return-1<(e.textContent||o(e)).indexOf(t)}}),lang:le(function(n){return V.test(n||\"\")||se.error(\"unsupported lang: \"+n),n=n.replace(te,ne).toLowerCase(),function(e){var t;do{if(t=E?e.lang:e.getAttribute(\"xml:lang\")||e.getAttribute(\"lang\"))return(t=t.toLowerCase())===n||0===t.indexOf(n+\"-\")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=n.location&&n.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===a},focus:function(e){return e===C.activeElement&&(!C.hasFocus||C.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:ge(!1),disabled:ge(!0),checked:function(e){var t=e.nodeName.toLowerCase();return\"input\"===t&&!!e.checked||\"option\"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!b.pseudos.empty(e)},header:function(e){return J.test(e.nodeName)},input:function(e){return Q.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return\"input\"===t&&\"button\"===e.type||\"button\"===t},text:function(e){var t;return\"input\"===e.nodeName.toLowerCase()&&\"text\"===e.type&&(null==(t=e.getAttribute(\"type\"))||\"text\"===t.toLowerCase())},first:ve(function(){return[0]}),last:ve(function(e,t){return[t-1]}),eq:ve(function(e,t,n){return[n<0?n+t:n]}),even:ve(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:ve(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:ve(function(e,t,n){for(var r=n<0?n+t:t<n?t:n;0<=--r;)e.push(r);return e}),gt:ve(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=b.pseudos.eq,{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})b.pseudos[e]=de(e);for(e in{submit:!0,reset:!0})b.pseudos[e]=he(e);function me(){}function xe(e){for(var t=0,n=e.length,r=\"\";t<n;t++)r+=e[t].value;return r}function be(s,e,t){var u=e.dir,l=e.next,c=l||u,f=t&&\"parentNode\"===c,p=r++;return e.first?function(e,t,n){while(e=e[u])if(1===e.nodeType||f)return s(e,t,n);return!1}:function(e,t,n){var r,i,o,a=[k,p];if(n){while(e=e[u])if((1===e.nodeType||f)&&s(e,t,n))return!0}else while(e=e[u])if(1===e.nodeType||f)if(i=(o=e[S]||(e[S]={}))[e.uniqueID]||(o[e.uniqueID]={}),l&&l===e.nodeName.toLowerCase())e=e[u]||e;else{if((r=i[c])&&r[0]===k&&r[1]===p)return a[2]=r[2];if((i[c]=a)[2]=s(e,t,n))return!0}return!1}}function we(i){return 1<i.length?function(e,t,n){var r=i.length;while(r--)if(!i[r](e,t,n))return!1;return!0}:i[0]}function Te(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function Ce(d,h,g,v,y,e){return v&&!v[S]&&(v=Ce(v)),y&&!y[S]&&(y=Ce(y,e)),le(function(e,t,n,r){var i,o,a,s=[],u=[],l=t.length,c=e||function(e,t,n){for(var r=0,i=t.length;r<i;r++)se(e,t[r],n);return n}(h||\"*\",n.nodeType?[n]:n,[]),f=!d||!e&&h?c:Te(c,s,d,n,r),p=g?y||(e?d:l||v)?[]:t:f;if(g&&g(f,p,n,r),v){i=Te(p,u),v(i,[],n,r),o=i.length;while(o--)(a=i[o])&&(p[u[o]]=!(f[u[o]]=a))}if(e){if(y||d){if(y){i=[],o=p.length;while(o--)(a=p[o])&&i.push(f[o]=a);y(null,p=[],i,r)}o=p.length;while(o--)(a=p[o])&&-1<(i=y?P(e,a):s[o])&&(e[i]=!(t[i]=a))}}else p=Te(p===t?p.splice(l,p.length):p),y?y(null,t,p,r):H.apply(t,p)})}function Ee(e){for(var i,t,n,r=e.length,o=b.relative[e[0].type],a=o||b.relative[\" \"],s=o?1:0,u=be(function(e){return e===i},a,!0),l=be(function(e){return-1<P(i,e)},a,!0),c=[function(e,t,n){var r=!o&&(n||t!==w)||((i=t).nodeType?u(e,t,n):l(e,t,n));return i=null,r}];s<r;s++)if(t=b.relative[e[s].type])c=[be(we(c),t)];else{if((t=b.filter[e[s].type].apply(null,e[s].matches))[S]){for(n=++s;n<r;n++)if(b.relative[e[n].type])break;return Ce(1<s&&we(c),1<s&&xe(e.slice(0,s-1).concat({value:\" \"===e[s-2].type?\"*\":\"\"})).replace($,\"$1\"),t,s<n&&Ee(e.slice(s,n)),n<r&&Ee(e=e.slice(n)),n<r&&xe(e))}c.push(t)}return we(c)}return me.prototype=b.filters=b.pseudos,b.setFilters=new me,h=se.tokenize=function(e,t){var n,r,i,o,a,s,u,l=x[e+\" \"];if(l)return t?0:l.slice(0);a=e,s=[],u=b.preFilter;while(a){for(o in n&&!(r=_.exec(a))||(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=z.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace($,\" \")}),a=a.slice(n.length)),b.filter)!(r=G[o].exec(a))||u[o]&&!(r=u[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?se.error(e):x(e,s).slice(0)},f=se.compile=function(e,t){var n,v,y,m,x,r,i=[],o=[],a=A[e+\" \"];if(!a){t||(t=h(e)),n=t.length;while(n--)(a=Ee(t[n]))[S]?i.push(a):o.push(a);(a=A(e,(v=o,m=0<(y=i).length,x=0<v.length,r=function(e,t,n,r,i){var o,a,s,u=0,l=\"0\",c=e&&[],f=[],p=w,d=e||x&&b.find.TAG(\"*\",i),h=k+=null==p?1:Math.random()||.1,g=d.length;for(i&&(w=t==C||t||i);l!==g&&null!=(o=d[l]);l++){if(x&&o){a=0,t||o.ownerDocument==C||(T(o),n=!E);while(s=v[a++])if(s(o,t||C,n)){r.push(o);break}i&&(k=h)}m&&((o=!s&&o)&&u--,e&&c.push(o))}if(u+=l,m&&l!==u){a=0;while(s=y[a++])s(c,f,t,n);if(e){if(0<u)while(l--)c[l]||f[l]||(f[l]=q.call(r));f=Te(f)}H.apply(r,f),i&&!e&&0<f.length&&1<u+y.length&&se.uniqueSort(r)}return i&&(k=h,w=p),c},m?le(r):r))).selector=e}return a},g=se.select=function(e,t,n,r){var i,o,a,s,u,l=\"function\"==typeof e&&e,c=!r&&h(e=l.selector||e);if(n=n||[],1===c.length){if(2<(o=c[0]=c[0].slice(0)).length&&\"ID\"===(a=o[0]).type&&9===t.nodeType&&E&&b.relative[o[1].type]){if(!(t=(b.find.ID(a.matches[0].replace(te,ne),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}i=G.needsContext.test(e)?0:o.length;while(i--){if(a=o[i],b.relative[s=a.type])break;if((u=b.find[s])&&(r=u(a.matches[0].replace(te,ne),ee.test(o[0].type)&&ye(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&xe(o)))return H.apply(n,r),n;break}}}return(l||f(e,c))(r,t,!E,n,!t||ee.test(e)&&ye(t.parentNode)||t),n},d.sortStable=S.split(\"\").sort(D).join(\"\")===S,d.detectDuplicates=!!l,T(),d.sortDetached=ce(function(e){return 1&e.compareDocumentPosition(C.createElement(\"fieldset\"))}),ce(function(e){return e.innerHTML=\"<a href='#'></a>\",\"#\"===e.firstChild.getAttribute(\"href\")})||fe(\"type|href|height|width\",function(e,t,n){if(!n)return e.getAttribute(t,\"type\"===t.toLowerCase()?1:2)}),d.attributes&&ce(function(e){return e.innerHTML=\"<input/>\",e.firstChild.setAttribute(\"value\",\"\"),\"\"===e.firstChild.getAttribute(\"value\")})||fe(\"value\",function(e,t,n){if(!n&&\"input\"===e.nodeName.toLowerCase())return e.defaultValue}),ce(function(e){return null==e.getAttribute(\"disabled\")})||fe(R,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),se}(C);S.find=d,S.expr=d.selectors,S.expr[\":\"]=S.expr.pseudos,S.uniqueSort=S.unique=d.uniqueSort,S.text=d.getText,S.isXMLDoc=d.isXML,S.contains=d.contains,S.escapeSelector=d.escape;var h=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&S(e).is(n))break;r.push(e)}return r},T=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},k=S.expr.match.needsContext;function A(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var N=/^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i;function D(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):\"string\"!=typeof n?S.grep(e,function(e){return-1<i.call(n,e)!==r}):S.filter(n,e,r)}S.filter=function(e,t,n){var r=t[0];return n&&(e=\":not(\"+e+\")\"),1===t.length&&1===r.nodeType?S.find.matchesSelector(r,e)?[r]:[]:S.find.matches(e,S.grep(t,function(e){return 1===e.nodeType}))},S.fn.extend({find:function(e){var t,n,r=this.length,i=this;if(\"string\"!=typeof e)return this.pushStack(S(e).filter(function(){for(t=0;t<r;t++)if(S.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)S.find(e,i[t],n);return 1<r?S.uniqueSort(n):n},filter:function(e){return this.pushStack(D(this,e||[],!1))},not:function(e){return this.pushStack(D(this,e||[],!0))},is:function(e){return!!D(this,\"string\"==typeof e&&k.test(e)?S(e):e||[],!1).length}});var j,q=/^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,\"string\"==typeof e){if(!(r=\"<\"===e[0]&&\">\"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,j=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(S.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a=\"string\"!=typeof e&&S(e);if(!k.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?-1<a.index(n):1===n.nodeType&&S.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?S.uniqueSort(o):o)},index:function(e){return e?\"string\"==typeof e?i.call(S(e),this[0]):i.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(S.uniqueSort(S.merge(this.get(),S(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),S.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return h(e,\"parentNode\")},parentsUntil:function(e,t,n){return h(e,\"parentNode\",n)},next:function(e){return O(e,\"nextSibling\")},prev:function(e){return O(e,\"previousSibling\")},nextAll:function(e){return h(e,\"nextSibling\")},prevAll:function(e){return h(e,\"previousSibling\")},nextUntil:function(e,t,n){return h(e,\"nextSibling\",n)},prevUntil:function(e,t,n){return h(e,\"previousSibling\",n)},siblings:function(e){return T((e.parentNode||{}).firstChild,e)},children:function(e){return T(e.firstChild)},contents:function(e){return null!=e.contentDocument&&r(e.contentDocument)?e.contentDocument:(A(e,\"template\")&&(e=e.content||e),S.merge([],e.childNodes))}},function(r,i){S.fn[r]=function(e,t){var n=S.map(this,i,e);return\"Until\"!==r.slice(-5)&&(t=e),t&&\"string\"==typeof t&&(n=S.filter(t,n)),1<this.length&&(H[r]||S.uniqueSort(n),L.test(r)&&n.reverse()),this.pushStack(n)}});var P=/[^\\x20\\t\\r\\n\\f]+/g;function R(e){return e}function M(e){throw e}function I(e,t,n,r){var i;try{e&&m(i=e.promise)?i.call(e).done(t).fail(n):e&&m(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}S.Callbacks=function(r){var e,n;r=\"string\"==typeof r?(e=r,n={},S.each(e.match(P)||[],function(e,t){n[t]=!0}),n):S.extend({},r);var i,t,o,a,s=[],u=[],l=-1,c=function(){for(a=a||r.once,o=i=!0;u.length;l=-1){t=u.shift();while(++l<s.length)!1===s[l].apply(t[0],t[1])&&r.stopOnFalse&&(l=s.length,t=!1)}r.memory||(t=!1),i=!1,a&&(s=t?[]:\"\")},f={add:function(){return s&&(t&&!i&&(l=s.length-1,u.push(t)),function n(e){S.each(e,function(e,t){m(t)?r.unique&&f.has(t)||s.push(t):t&&t.length&&\"string\"!==w(t)&&n(t)})}(arguments),t&&!i&&c()),this},remove:function(){return S.each(arguments,function(e,t){var n;while(-1<(n=S.inArray(t,s,n)))s.splice(n,1),n<=l&&l--}),this},has:function(e){return e?-1<S.inArray(e,s):0<s.length},empty:function(){return s&&(s=[]),this},disable:function(){return a=u=[],s=t=\"\",this},disabled:function(){return!s},lock:function(){return a=u=[],t||i||(s=t=\"\"),this},locked:function(){return!!a},fireWith:function(e,t){return a||(t=[e,(t=t||[]).slice?t.slice():t],u.push(t),i||c()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!o}};return f},S.extend({Deferred:function(e){var o=[[\"notify\",\"progress\",S.Callbacks(\"memory\"),S.Callbacks(\"memory\"),2],[\"resolve\",\"done\",S.Callbacks(\"once memory\"),S.Callbacks(\"once memory\"),0,\"resolved\"],[\"reject\",\"fail\",S.Callbacks(\"once memory\"),S.Callbacks(\"once memory\"),1,\"rejected\"]],i=\"pending\",a={state:function(){return i},always:function(){return s.done(arguments).fail(arguments),this},\"catch\":function(e){return a.then(null,e)},pipe:function(){var i=arguments;return S.Deferred(function(r){S.each(o,function(e,t){var n=m(i[t[4]])&&i[t[4]];s[t[1]](function(){var e=n&&n.apply(this,arguments);e&&m(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[t[0]+\"With\"](this,n?[e]:arguments)})}),i=null}).promise()},then:function(t,n,r){var u=0;function l(i,o,a,s){return function(){var n=this,r=arguments,e=function(){var e,t;if(!(i<u)){if((e=a.apply(n,r))===o.promise())throw new TypeError(\"Thenable self-resolution\");t=e&&(\"object\"==typeof e||\"function\"==typeof e)&&e.then,m(t)?s?t.call(e,l(u,o,R,s),l(u,o,M,s)):(u++,t.call(e,l(u,o,R,s),l(u,o,M,s),l(u,o,R,o.notifyWith))):(a!==R&&(n=void 0,r=[e]),(s||o.resolveWith)(n,r))}},t=s?e:function(){try{e()}catch(e){S.Deferred.exceptionHook&&S.Deferred.exceptionHook(e,t.stackTrace),u<=i+1&&(a!==M&&(n=void 0,r=[e]),o.rejectWith(n,r))}};i?t():(S.Deferred.getStackHook&&(t.stackTrace=S.Deferred.getStackHook()),C.setTimeout(t))}}return S.Deferred(function(e){o[0][3].add(l(0,e,m(r)?r:R,e.notifyWith)),o[1][3].add(l(0,e,m(t)?t:R)),o[2][3].add(l(0,e,m(n)?n:M))}).promise()},promise:function(e){return null!=e?S.extend(e,a):a}},s={};return S.each(o,function(e,t){var n=t[2],r=t[5];a[t[1]]=n.add,r&&n.add(function(){i=r},o[3-e][2].disable,o[3-e][3].disable,o[0][2].lock,o[0][3].lock),n.add(t[3].fire),s[t[0]]=function(){return s[t[0]+\"With\"](this===s?void 0:this,arguments),this},s[t[0]+\"With\"]=n.fireWith}),a.promise(s),e&&e.call(s,s),s},when:function(e){var n=arguments.length,t=n,r=Array(t),i=s.call(arguments),o=S.Deferred(),a=function(t){return function(e){r[t]=this,i[t]=1<arguments.length?s.call(arguments):e,--n||o.resolveWith(r,i)}};if(n<=1&&(I(e,o.done(a(t)).resolve,o.reject,!n),\"pending\"===o.state()||m(i[t]&&i[t].then)))return o.then();while(t--)I(i[t],a(t),o.reject);return o.promise()}});var W=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;S.Deferred.exceptionHook=function(e,t){C.console&&C.console.warn&&e&&W.test(e.name)&&C.console.warn(\"jQuery.Deferred exception: \"+e.message,e.stack,t)},S.readyException=function(e){C.setTimeout(function(){throw e})};var F=S.Deferred();function B(){E.removeEventListener(\"DOMContentLoaded\",B),C.removeEventListener(\"load\",B),S.ready()}S.fn.ready=function(e){return F.then(e)[\"catch\"](function(e){S.readyException(e)}),this},S.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--S.readyWait:S.isReady)||(S.isReady=!0)!==e&&0<--S.readyWait||F.resolveWith(E,[S])}}),S.ready.then=F.then,\"complete\"===E.readyState||\"loading\"!==E.readyState&&!E.documentElement.doScroll?C.setTimeout(S.ready):(E.addEventListener(\"DOMContentLoaded\",B),C.addEventListener(\"load\",B));var $=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if(\"object\"===w(n))for(s in i=!0,n)$(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,m(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(S(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},_=/^-ms-/,z=/-([a-z])/g;function U(e,t){return t.toUpperCase()}function X(e){return e.replace(_,\"ms-\").replace(z,U)}var V=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function G(){this.expando=S.expando+G.uid++}G.uid=1,G.prototype={cache:function(e){var t=e[this.expando];return t||(t={},V(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if(\"string\"==typeof t)i[X(t)]=n;else for(r in t)i[X(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][X(t)]},access:function(e,t,n){return void 0===t||t&&\"string\"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(X):(t=X(t))in r?[t]:t.match(P)||[]).length;while(n--)delete r[t[n]]}(void 0===t||S.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!S.isEmptyObject(t)}};var Y=new G,Q=new G,J=/^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,K=/[A-Z]/g;function Z(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r=\"data-\"+t.replace(K,\"-$&\").toLowerCase(),\"string\"==typeof(n=e.getAttribute(r))){try{n=\"true\"===(i=n)||\"false\"!==i&&(\"null\"===i?null:i===+i+\"\"?+i:J.test(i)?JSON.parse(i):i)}catch(e){}Q.set(e,t,n)}else n=void 0;return n}S.extend({hasData:function(e){return Q.hasData(e)||Y.hasData(e)},data:function(e,t,n){return Q.access(e,t,n)},removeData:function(e,t){Q.remove(e,t)},_data:function(e,t,n){return Y.access(e,t,n)},_removeData:function(e,t){Y.remove(e,t)}}),S.fn.extend({data:function(n,e){var t,r,i,o=this[0],a=o&&o.attributes;if(void 0===n){if(this.length&&(i=Q.get(o),1===o.nodeType&&!Y.get(o,\"hasDataAttrs\"))){t=a.length;while(t--)a[t]&&0===(r=a[t].name).indexOf(\"data-\")&&(r=X(r.slice(5)),Z(o,r,i[r]));Y.set(o,\"hasDataAttrs\",!0)}return i}return\"object\"==typeof n?this.each(function(){Q.set(this,n)}):$(this,function(e){var t;if(o&&void 0===e)return void 0!==(t=Q.get(o,n))?t:void 0!==(t=Z(o,n))?t:void 0;this.each(function(){Q.set(this,n,e)})},null,e,1<arguments.length,null,!0)},removeData:function(e){return this.each(function(){Q.remove(this,e)})}}),S.extend({queue:function(e,t,n){var r;if(e)return t=(t||\"fx\")+\"queue\",r=Y.get(e,t),n&&(!r||Array.isArray(n)?r=Y.access(e,t,S.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||\"fx\";var n=S.queue(e,t),r=n.length,i=n.shift(),o=S._queueHooks(e,t);\"inprogress\"===i&&(i=n.shift(),r--),i&&(\"fx\"===t&&n.unshift(\"inprogress\"),delete o.stop,i.call(e,function(){S.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+\"queueHooks\";return Y.get(e,n)||Y.access(e,n,{empty:S.Callbacks(\"once memory\").add(function(){Y.remove(e,[t+\"queue\",n])})})}}),S.fn.extend({queue:function(t,n){var e=2;return\"string\"!=typeof t&&(n=t,t=\"fx\",e--),arguments.length<e?S.queue(this[0],t):void 0===n?this:this.each(function(){var e=S.queue(this,t,n);S._queueHooks(this,t),\"fx\"===t&&\"inprogress\"!==e[0]&&S.dequeue(this,t)})},dequeue:function(e){return this.each(function(){S.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||\"fx\",[])},promise:function(e,t){var n,r=1,i=S.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};\"string\"!=typeof e&&(t=e,e=void 0),e=e||\"fx\";while(a--)(n=Y.get(o[a],e+\"queueHooks\"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var ee=/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source,te=new RegExp(\"^(?:([+-])=|)(\"+ee+\")([a-z%]*)$\",\"i\"),ne=[\"Top\",\"Right\",\"Bottom\",\"Left\"],re=E.documentElement,ie=function(e){return S.contains(e.ownerDocument,e)},oe={composed:!0};re.getRootNode&&(ie=function(e){return S.contains(e.ownerDocument,e)||e.getRootNode(oe)===e.ownerDocument});var ae=function(e,t){return\"none\"===(e=t||e).style.display||\"\"===e.style.display&&ie(e)&&\"none\"===S.css(e,\"display\")};function se(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return S.css(e,t,\"\")},u=s(),l=n&&n[3]||(S.cssNumber[t]?\"\":\"px\"),c=e.nodeType&&(S.cssNumber[t]||\"px\"!==l&&+u)&&te.exec(S.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)S.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,S.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var ue={};function le(e,t){for(var n,r,i,o,a,s,u,l=[],c=0,f=e.length;c<f;c++)(r=e[c]).style&&(n=r.style.display,t?(\"none\"===n&&(l[c]=Y.get(r,\"display\")||null,l[c]||(r.style.display=\"\")),\"\"===r.style.display&&ae(r)&&(l[c]=(u=a=o=void 0,a=(i=r).ownerDocument,s=i.nodeName,(u=ue[s])||(o=a.body.appendChild(a.createElement(s)),u=S.css(o,\"display\"),o.parentNode.removeChild(o),\"none\"===u&&(u=\"block\"),ue[s]=u)))):\"none\"!==n&&(l[c]=\"none\",Y.set(r,\"display\",n)));for(c=0;c<f;c++)null!=l[c]&&(e[c].style.display=l[c]);return e}S.fn.extend({show:function(){return le(this,!0)},hide:function(){return le(this)},toggle:function(e){return\"boolean\"==typeof e?e?this.show():this.hide():this.each(function(){ae(this)?S(this).show():S(this).hide()})}});var ce,fe,pe=/^(?:checkbox|radio)$/i,de=/<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)/i,he=/^$|^module$|\\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement(\"div\")),(fe=E.createElement(\"input\")).setAttribute(\"type\",\"radio\"),fe.setAttribute(\"checked\",\"checked\"),fe.setAttribute(\"name\",\"t\"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML=\"<textarea>x</textarea>\",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML=\"<option></option>\",y.option=!!ce.lastChild;var ge={thead:[1,\"<table>\",\"</table>\"],col:[2,\"<table><colgroup>\",\"</colgroup></table>\"],tr:[2,\"<table><tbody>\",\"</tbody></table>\"],td:[3,\"<table><tbody><tr>\",\"</tr></tbody></table>\"],_default:[0,\"\",\"\"]};function ve(e,t){var n;return n=\"undefined\"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||\"*\"):\"undefined\"!=typeof e.querySelectorAll?e.querySelectorAll(t||\"*\"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n<r;n++)Y.set(e[n],\"globalEval\",!t||Y.get(t[n],\"globalEval\"))}ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td,y.option||(ge.optgroup=ge.option=[1,\"<select multiple='multiple'>\",\"</select>\"]);var me=/<|&#?\\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d<h;d++)if((o=e[d])||0===o)if(\"object\"===w(o))S.merge(p,o.nodeType?[o]:o);else if(me.test(o)){a=a||f.appendChild(t.createElement(\"div\")),s=(de.exec(o)||[\"\",\"\"])[1].toLowerCase(),u=ge[s]||ge._default,a.innerHTML=u[1]+S.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;S.merge(p,a.childNodes),(a=f.firstChild).textContent=\"\"}else p.push(t.createTextNode(o));f.textContent=\"\",d=0;while(o=p[d++])if(r&&-1<S.inArray(o,r))i&&i.push(o);else if(l=ie(o),a=ve(f.appendChild(o),\"script\"),l&&ye(a),n){c=0;while(o=a[c++])he.test(o.type||\"\")&&n.push(o)}return f}var be=/^key/,we=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Te=/^([^.]*)(?:\\.(.+)|)/;function Ce(){return!0}function Ee(){return!1}function Se(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==(\"focus\"===t)}function ke(e,t,n,r,i,o){var a,s;if(\"object\"==typeof t){for(s in\"string\"!=typeof n&&(r=r||n,n=void 0),t)ke(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&(\"string\"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Ee;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return S().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=S.guid++)),e.each(function(){S.event.add(this,t,i,r,n)})}function Ae(e,i,o){o?(Y.set(e,i,!1),S.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Y.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(S.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Y.set(this,i,r),t=o(this,i),this[i](),r!==(n=Y.get(this,i))||t?Y.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Y.set(this,i,{value:S.event.trigger(S.extend(r[0],S.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Y.get(e,i)&&S.event.add(e,i,Ce)}S.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Y.get(t);if(V(t)){n.handler&&(n=(o=n).handler,i=o.selector),i&&S.find.matchesSelector(re,i),n.guid||(n.guid=S.guid++),(u=v.events)||(u=v.events=Object.create(null)),(a=v.handle)||(a=v.handle=function(e){return\"undefined\"!=typeof S&&S.event.triggered!==e.type?S.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||\"\").match(P)||[\"\"]).length;while(l--)d=g=(s=Te.exec(e[l])||[])[1],h=(s[2]||\"\").split(\".\").sort(),d&&(f=S.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=S.event.special[d]||{},c=S.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&S.expr.match.needsContext.test(i),namespace:h.join(\".\")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),S.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Y.hasData(e)&&Y.get(e);if(v&&(u=v.events)){l=(t=(t||\"\").match(P)||[\"\"]).length;while(l--)if(d=g=(s=Te.exec(t[l])||[])[1],h=(s[2]||\"\").split(\".\").sort(),d){f=S.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp(\"(^|\\\\.)\"+h.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&(\"**\"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||S.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)S.event.remove(e,d+t[l],n,r,!0);S.isEmptyObject(u)&&Y.remove(e,\"handle events\")}},dispatch:function(e){var t,n,r,i,o,a,s=new Array(arguments.length),u=S.event.fix(e),l=(Y.get(this,\"events\")||Object.create(null))[u.type]||[],c=S.event.special[u.type]||{};for(s[0]=u,t=1;t<arguments.length;t++)s[t]=arguments[t];if(u.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,u)){a=S.event.handlers.call(this,u,l),t=0;while((i=a[t++])&&!u.isPropagationStopped()){u.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!u.isImmediatePropagationStopped())u.rnamespace&&!1!==o.namespace&&!u.rnamespace.test(o.namespace)||(u.handleObj=o,u.data=o.data,void 0!==(r=((S.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,s))&&!1===(u.result=r)&&(u.preventDefault(),u.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,u),u.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!(\"click\"===e.type&&1<=e.button))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&(\"click\"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+\" \"]&&(a[i]=r.needsContext?-1<S(i,this).index(l):S.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(t,e){Object.defineProperty(S.Event.prototype,t,{enumerable:!0,configurable:!0,get:m(e)?function(){if(this.originalEvent)return e(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[t]},set:function(e){Object.defineProperty(this,t,{enumerable:!0,configurable:!0,writable:!0,value:e})}})},fix:function(e){return e[S.expando]?e:new S.Event(e)},special:{load:{noBubble:!0},click:{setup:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,\"input\")&&Ae(t,\"click\",Ce),!1},trigger:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,\"input\")&&Ae(t,\"click\"),!0},_default:function(e){var t=e.target;return pe.test(t.type)&&t.click&&A(t,\"input\")&&Y.get(t,\"click\")||A(t,\"a\")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},S.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},S.Event=function(e,t){if(!(this instanceof S.Event))return new S.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?Ce:Ee,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&S.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[S.expando]=!0},S.Event.prototype={constructor:S.Event,isDefaultPrevented:Ee,isPropagationStopped:Ee,isImmediatePropagationStopped:Ee,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=Ce,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=Ce,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=Ce,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},S.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,\"char\":!0,code:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(e){var t=e.button;return null==e.which&&be.test(e.type)?null!=e.charCode?e.charCode:e.keyCode:!e.which&&void 0!==t&&we.test(e.type)?1&t?1:2&t?3:4&t?2:0:e.which}},S.event.addProp),S.each({focus:\"focusin\",blur:\"focusout\"},function(e,t){S.event.special[e]={setup:function(){return Ae(this,e,Se),!1},trigger:function(){return Ae(this,e),!0},delegateType:t}}),S.each({mouseenter:\"mouseover\",mouseleave:\"mouseout\",pointerenter:\"pointerover\",pointerleave:\"pointerout\"},function(e,i){S.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||S.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),S.fn.extend({on:function(e,t,n,r){return ke(this,e,t,n,r)},one:function(e,t,n,r){return ke(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,S(e.delegateTarget).off(r.namespace?r.origType+\".\"+r.namespace:r.origType,r.selector,r.handler),this;if(\"object\"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&\"function\"!=typeof t||(n=t,t=void 0),!1===n&&(n=Ee),this.each(function(){S.event.remove(this,e,n,t)})}});var Ne=/<script|<style|<link/i,De=/checked\\s*(?:[^=]|=\\s*.checked.)/i,je=/^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g;function qe(e,t){return A(e,\"table\")&&A(11!==t.nodeType?t:t.firstChild,\"tr\")&&S(e).children(\"tbody\")[0]||e}function Le(e){return e.type=(null!==e.getAttribute(\"type\"))+\"/\"+e.type,e}function He(e){return\"true/\"===(e.type||\"\").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute(\"type\"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,\"handle events\"),s)for(n=0,r=s[i].length;n<r;n++)S.event.add(t,i,s[i][n]);Q.hasData(e)&&(o=Q.access(e),a=S.extend({},o),Q.set(t,a))}}function Pe(n,r,i,o){r=g(r);var e,t,a,s,u,l,c=0,f=n.length,p=f-1,d=r[0],h=m(d);if(h||1<f&&\"string\"==typeof d&&!y.checkClone&&De.test(d))return n.each(function(e){var t=n.eq(e);h&&(r[0]=d.call(this,e,t.html())),Pe(t,r,i,o)});if(f&&(t=(e=xe(r,n[0].ownerDocument,!1,n,o)).firstChild,1===e.childNodes.length&&(e=t),t||o)){for(s=(a=S.map(ve(e,\"script\"),Le)).length;c<f;c++)u=e,c!==p&&(u=S.clone(u,!0,!0),s&&S.merge(a,ve(u,\"script\"))),i.call(n[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,S.map(a,He),c=0;c<s;c++)u=a[c],he.test(u.type||\"\")&&!Y.access(u,\"globalEval\")&&S.contains(l,u)&&(u.src&&\"module\"!==(u.type||\"\").toLowerCase()?S._evalUrl&&!u.noModule&&S._evalUrl(u.src,{nonce:u.nonce||u.getAttribute(\"nonce\")},l):b(u.textContent.replace(je,\"\"),u,l))}return n}function Re(e,t,n){for(var r,i=t?S.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||S.cleanData(ve(r)),r.parentNode&&(n&&ie(r)&&ye(ve(r,\"script\")),r.parentNode.removeChild(r));return e}S.extend({htmlPrefilter:function(e){return e},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=ie(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||S.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r<i;r++)s=o[r],u=a[r],void 0,\"input\"===(l=u.nodeName.toLowerCase())&&pe.test(s.type)?u.checked=s.checked:\"input\"!==l&&\"textarea\"!==l||(u.defaultValue=s.defaultValue);if(t)if(n)for(o=o||ve(e),a=a||ve(c),r=0,i=o.length;r<i;r++)Oe(o[r],a[r]);else Oe(e,c);return 0<(a=ve(c,\"script\")).length&&ye(a,!f&&ve(e,\"script\")),c},cleanData:function(e){for(var t,n,r,i=S.event.special,o=0;void 0!==(n=e[o]);o++)if(V(n)){if(t=n[Y.expando]){if(t.events)for(r in t.events)i[r]?S.event.remove(n,r):S.removeEvent(n,r,t.handle);n[Y.expando]=void 0}n[Q.expando]&&(n[Q.expando]=void 0)}}}),S.fn.extend({detach:function(e){return Re(this,e,!0)},remove:function(e){return Re(this,e)},text:function(e){return $(this,function(e){return void 0===e?S.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Pe(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||qe(this,e).appendChild(e)})},prepend:function(){return Pe(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=qe(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Pe(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Pe(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(S.cleanData(ve(e,!1)),e.textContent=\"\");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return S.clone(this,e,t)})},html:function(e){return $(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if(\"string\"==typeof e&&!Ne.test(e)&&!ge[(de.exec(e)||[\"\",\"\"])[1].toLowerCase()]){e=S.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(S.cleanData(ve(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var n=[];return Pe(this,arguments,function(e){var t=this.parentNode;S.inArray(this,n)<0&&(S.cleanData(ve(this)),t&&t.replaceChild(e,this))},n)}}),S.each({appendTo:\"append\",prependTo:\"prepend\",insertBefore:\"before\",insertAfter:\"after\",replaceAll:\"replaceWith\"},function(e,a){S.fn[e]=function(e){for(var t,n=[],r=S(e),i=r.length-1,o=0;o<=i;o++)t=o===i?this:this.clone(!0),S(r[o])[a](t),u.apply(n,t.get());return this.pushStack(n)}});var Me=new RegExp(\"^(\"+ee+\")(?!px)[a-z%]+$\",\"i\"),Ie=function(e){var t=e.ownerDocument.defaultView;return t&&t.opener||(t=C),t.getComputedStyle(e)},We=function(e,t,n){var r,i,o={};for(i in t)o[i]=e.style[i],e.style[i]=t[i];for(i in r=n.call(e),t)e.style[i]=o[i];return r},Fe=new RegExp(ne.join(\"|\"),\"i\");function Be(e,t,n){var r,i,o,a,s=e.style;return(n=n||Ie(e))&&(\"\"!==(a=n.getPropertyValue(t)||n[t])||ie(e)||(a=S.style(e,t)),!y.pixelBoxStyles()&&Me.test(a)&&Fe.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o)),void 0!==a?a+\"\":a}function $e(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}!function(){function e(){if(l){u.style.cssText=\"position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0\",l.style.cssText=\"position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%\",re.appendChild(u).appendChild(l);var e=C.getComputedStyle(l);n=\"1%\"!==e.top,s=12===t(e.marginLeft),l.style.right=\"60%\",o=36===t(e.right),r=36===t(e.width),l.style.position=\"absolute\",i=12===t(l.offsetWidth/3),re.removeChild(u),l=null}}function t(e){return Math.round(parseFloat(e))}var n,r,i,o,a,s,u=E.createElement(\"div\"),l=E.createElement(\"div\");l.style&&(l.style.backgroundClip=\"content-box\",l.cloneNode(!0).style.backgroundClip=\"\",y.clearCloneStyle=\"content-box\"===l.style.backgroundClip,S.extend(y,{boxSizingReliable:function(){return e(),r},pixelBoxStyles:function(){return e(),o},pixelPosition:function(){return e(),n},reliableMarginLeft:function(){return e(),s},scrollboxSize:function(){return e(),i},reliableTrDimensions:function(){var e,t,n,r;return null==a&&(e=E.createElement(\"table\"),t=E.createElement(\"tr\"),n=E.createElement(\"div\"),e.style.cssText=\"position:absolute;left:-11111px\",t.style.height=\"1px\",n.style.height=\"9px\",re.appendChild(e).appendChild(t).appendChild(n),r=C.getComputedStyle(t),a=3<parseInt(r.height),re.removeChild(e)),a}}))}();var _e=[\"Webkit\",\"Moz\",\"ms\"],ze=E.createElement(\"div\").style,Ue={};function Xe(e){var t=S.cssProps[e]||Ue[e];return t||(e in ze?e:Ue[e]=function(e){var t=e[0].toUpperCase()+e.slice(1),n=_e.length;while(n--)if((e=_e[n]+t)in ze)return e}(e)||e)}var Ve=/^(none|table(?!-c[ea]).+)/,Ge=/^--/,Ye={position:\"absolute\",visibility:\"hidden\",display:\"block\"},Qe={letterSpacing:\"0\",fontWeight:\"400\"};function Je(e,t,n){var r=te.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||\"px\"):t}function Ke(e,t,n,r,i,o){var a=\"width\"===t?1:0,s=0,u=0;if(n===(r?\"border\":\"content\"))return 0;for(;a<4;a+=2)\"margin\"===n&&(u+=S.css(e,n+ne[a],!0,i)),r?(\"content\"===n&&(u-=S.css(e,\"padding\"+ne[a],!0,i)),\"margin\"!==n&&(u-=S.css(e,\"border\"+ne[a]+\"Width\",!0,i))):(u+=S.css(e,\"padding\"+ne[a],!0,i),\"padding\"!==n?u+=S.css(e,\"border\"+ne[a]+\"Width\",!0,i):s+=S.css(e,\"border\"+ne[a]+\"Width\",!0,i));return!r&&0<=o&&(u+=Math.max(0,Math.ceil(e[\"offset\"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))||0),u}function Ze(e,t,n){var r=Ie(e),i=(!y.boxSizingReliable()||n)&&\"border-box\"===S.css(e,\"boxSizing\",!1,r),o=i,a=Be(e,t,r),s=\"offset\"+t[0].toUpperCase()+t.slice(1);if(Me.test(a)){if(!n)return a;a=\"auto\"}return(!y.boxSizingReliable()&&i||!y.reliableTrDimensions()&&A(e,\"tr\")||\"auto\"===a||!parseFloat(a)&&\"inline\"===S.css(e,\"display\",!1,r))&&e.getClientRects().length&&(i=\"border-box\"===S.css(e,\"boxSizing\",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+Ke(e,t,n||(i?\"border\":\"content\"),o,r,a)+\"px\"}function et(e,t,n,r,i){return new et.prototype.init(e,t,n,r,i)}S.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Be(e,\"opacity\");return\"\"===n?\"1\":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=X(t),u=Ge.test(t),l=e.style;if(u||(t=Xe(s)),a=S.cssHooks[t]||S.cssHooks[s],void 0===n)return a&&\"get\"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];\"string\"===(o=typeof n)&&(i=te.exec(n))&&i[1]&&(n=se(e,t,i),o=\"number\"),null!=n&&n==n&&(\"number\"!==o||u||(n+=i&&i[3]||(S.cssNumber[s]?\"\":\"px\")),y.clearCloneStyle||\"\"!==n||0!==t.indexOf(\"background\")||(l[t]=\"inherit\"),a&&\"set\"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=X(t);return Ge.test(t)||(t=Xe(s)),(a=S.cssHooks[t]||S.cssHooks[s])&&\"get\"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Be(e,t,r)),\"normal\"===i&&t in Qe&&(i=Qe[t]),\"\"===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),S.each([\"height\",\"width\"],function(e,u){S.cssHooks[u]={get:function(e,t,n){if(t)return!Ve.test(S.css(e,\"display\"))||e.getClientRects().length&&e.getBoundingClientRect().width?Ze(e,u,n):We(e,Ye,function(){return Ze(e,u,n)})},set:function(e,t,n){var r,i=Ie(e),o=!y.scrollboxSize()&&\"absolute\"===i.position,a=(o||n)&&\"border-box\"===S.css(e,\"boxSizing\",!1,i),s=n?Ke(e,u,n,a,i):0;return a&&o&&(s-=Math.ceil(e[\"offset\"+u[0].toUpperCase()+u.slice(1)]-parseFloat(i[u])-Ke(e,u,\"border\",!1,i)-.5)),s&&(r=te.exec(t))&&\"px\"!==(r[3]||\"px\")&&(e.style[u]=t,t=S.css(e,u)),Je(0,t,s)}}}),S.cssHooks.marginLeft=$e(y.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Be(e,\"marginLeft\"))||e.getBoundingClientRect().left-We(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+\"px\"}),S.each({margin:\"\",padding:\"\",border:\"Width\"},function(i,o){S.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r=\"string\"==typeof e?e.split(\" \"):[e];t<4;t++)n[i+ne[t]+o]=r[t]||r[t-2]||r[0];return n}},\"margin\"!==i&&(S.cssHooks[i+o].set=Je)}),S.fn.extend({css:function(e,t){return $(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Ie(e),i=t.length;a<i;a++)o[t[a]]=S.css(e,t[a],!1,r);return o}return void 0!==n?S.style(e,t,n):S.css(e,t)},e,t,1<arguments.length)}}),((S.Tween=et).prototype={constructor:et,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||S.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(S.cssNumber[n]?\"\":\"px\")},cur:function(){var e=et.propHooks[this.prop];return e&&e.get?e.get(this):et.propHooks._default.get(this)},run:function(e){var t,n=et.propHooks[this.prop];return this.options.duration?this.pos=t=S.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):et.propHooks._default.set(this),this}}).init.prototype=et.prototype,(et.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=S.css(e.elem,e.prop,\"\"))&&\"auto\"!==t?t:0},set:function(e){S.fx.step[e.prop]?S.fx.step[e.prop](e):1!==e.elem.nodeType||!S.cssHooks[e.prop]&&null==e.elem.style[Xe(e.prop)]?e.elem[e.prop]=e.now:S.style(e.elem,e.prop,e.now+e.unit)}}}).scrollTop=et.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},S.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:\"swing\"},S.fx=et.prototype.init,S.fx.step={};var tt,nt,rt,it,ot=/^(?:toggle|show|hide)$/,at=/queueHooks$/;function st(){nt&&(!1===E.hidden&&C.requestAnimationFrame?C.requestAnimationFrame(st):C.setTimeout(st,S.fx.interval),S.fx.tick())}function ut(){return C.setTimeout(function(){tt=void 0}),tt=Date.now()}function lt(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i[\"margin\"+(n=ne[r])]=i[\"padding\"+n]=e;return t&&(i.opacity=i.width=e),i}function ct(e,t,n){for(var r,i=(ft.tweeners[t]||[]).concat(ft.tweeners[\"*\"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function ft(o,e,t){var n,a,r=0,i=ft.prefilters.length,s=S.Deferred().always(function(){delete u.elem}),u=function(){if(a)return!1;for(var e=tt||ut(),t=Math.max(0,l.startTime+l.duration-e),n=1-(t/l.duration||0),r=0,i=l.tweens.length;r<i;r++)l.tweens[r].run(n);return s.notifyWith(o,[l,n,t]),n<1&&i?t:(i||s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l]),!1)},l=s.promise({elem:o,props:S.extend({},e),opts:S.extend(!0,{specialEasing:{},easing:S.easing._default},t),originalProperties:e,originalOptions:t,startTime:tt||ut(),duration:t.duration,tweens:[],createTween:function(e,t){var n=S.Tween(o,l.opts,e,t,l.opts.specialEasing[e]||l.opts.easing);return l.tweens.push(n),n},stop:function(e){var t=0,n=e?l.tweens.length:0;if(a)return this;for(a=!0;t<n;t++)l.tweens[t].run(1);return e?(s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l,e])):s.rejectWith(o,[l,e]),this}}),c=l.props;for(!function(e,t){var n,r,i,o,a;for(n in e)if(i=t[r=X(n)],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=S.cssHooks[r])&&\"expand\"in a)for(n in o=a.expand(o),delete e[r],o)n in e||(e[n]=o[n],t[n]=i);else t[r]=i}(c,l.opts.specialEasing);r<i;r++)if(n=ft.prefilters[r].call(l,o,c,l.opts))return m(n.stop)&&(S._queueHooks(l.elem,l.opts.queue).stop=n.stop.bind(n)),n;return S.map(c,ct,l),m(l.opts.start)&&l.opts.start.call(o,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),S.fx.timer(S.extend(u,{elem:o,anim:l,queue:l.opts.queue})),l}S.Animation=S.extend(ft,{tweeners:{\"*\":[function(e,t){var n=this.createTween(e,t);return se(n.elem,e,te.exec(t),n),n}]},tweener:function(e,t){m(e)?(t=e,e=[\"*\"]):e=e.match(P);for(var n,r=0,i=e.length;r<i;r++)n=e[r],ft.tweeners[n]=ft.tweeners[n]||[],ft.tweeners[n].unshift(t)},prefilters:[function(e,t,n){var r,i,o,a,s,u,l,c,f=\"width\"in t||\"height\"in t,p=this,d={},h=e.style,g=e.nodeType&&ae(e),v=Y.get(e,\"fxshow\");for(r in n.queue||(null==(a=S._queueHooks(e,\"fx\")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,S.queue(e,\"fx\").length||a.empty.fire()})})),t)if(i=t[r],ot.test(i)){if(delete t[r],o=o||\"toggle\"===i,i===(g?\"hide\":\"show\")){if(\"show\"!==i||!v||void 0===v[r])continue;g=!0}d[r]=v&&v[r]||S.style(e,r)}if((u=!S.isEmptyObject(t))||!S.isEmptyObject(d))for(r in f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=v&&v.display)&&(l=Y.get(e,\"display\")),\"none\"===(c=S.css(e,\"display\"))&&(l?c=l:(le([e],!0),l=e.style.display||l,c=S.css(e,\"display\"),le([e]))),(\"inline\"===c||\"inline-block\"===c&&null!=l)&&\"none\"===S.css(e,\"float\")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l=\"none\"===c?\"\":c)),h.display=\"inline-block\")),n.overflow&&(h.overflow=\"hidden\",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1,d)u||(v?\"hidden\"in v&&(g=v.hidden):v=Y.access(e,\"fxshow\",{display:l}),o&&(v.hidden=!g),g&&le([e],!0),p.done(function(){for(r in g||le([e]),Y.remove(e,\"fxshow\"),d)S.style(e,r,d[r])})),u=ct(g?v[r]:0,r,p),r in v||(v[r]=u.start,g&&(u.end=u.start,u.start=0))}],prefilter:function(e,t){t?ft.prefilters.unshift(e):ft.prefilters.push(e)}}),S.speed=function(e,t,n){var r=e&&\"object\"==typeof e?S.extend({},e):{complete:n||!n&&t||m(e)&&e,duration:e,easing:n&&t||t&&!m(t)&&t};return S.fx.off?r.duration=0:\"number\"!=typeof r.duration&&(r.duration in S.fx.speeds?r.duration=S.fx.speeds[r.duration]:r.duration=S.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue=\"fx\"),r.old=r.complete,r.complete=function(){m(r.old)&&r.old.call(this),r.queue&&S.dequeue(this,r.queue)},r},S.fn.extend({fadeTo:function(e,t,n,r){return this.filter(ae).css(\"opacity\",0).show().end().animate({opacity:t},e,n,r)},animate:function(t,e,n,r){var i=S.isEmptyObject(t),o=S.speed(e,n,r),a=function(){var e=ft(this,S.extend({},t),o);(i||Y.get(this,\"finish\"))&&e.stop(!0)};return a.finish=a,i||!1===o.queue?this.each(a):this.queue(o.queue,a)},stop:function(i,e,o){var a=function(e){var t=e.stop;delete e.stop,t(o)};return\"string\"!=typeof i&&(o=e,e=i,i=void 0),e&&this.queue(i||\"fx\",[]),this.each(function(){var e=!0,t=null!=i&&i+\"queueHooks\",n=S.timers,r=Y.get(this);if(t)r[t]&&r[t].stop&&a(r[t]);else for(t in r)r[t]&&r[t].stop&&at.test(t)&&a(r[t]);for(t=n.length;t--;)n[t].elem!==this||null!=i&&n[t].queue!==i||(n[t].anim.stop(o),e=!1,n.splice(t,1));!e&&o||S.dequeue(this,i)})},finish:function(a){return!1!==a&&(a=a||\"fx\"),this.each(function(){var e,t=Y.get(this),n=t[a+\"queue\"],r=t[a+\"queueHooks\"],i=S.timers,o=n?n.length:0;for(t.finish=!0,S.queue(this,a,[]),r&&r.stop&&r.stop.call(this,!0),e=i.length;e--;)i[e].elem===this&&i[e].queue===a&&(i[e].anim.stop(!0),i.splice(e,1));for(e=0;e<o;e++)n[e]&&n[e].finish&&n[e].finish.call(this);delete t.finish})}}),S.each([\"toggle\",\"show\",\"hide\"],function(e,r){var i=S.fn[r];S.fn[r]=function(e,t,n){return null==e||\"boolean\"==typeof e?i.apply(this,arguments):this.animate(lt(r,!0),e,t,n)}}),S.each({slideDown:lt(\"show\"),slideUp:lt(\"hide\"),slideToggle:lt(\"toggle\"),fadeIn:{opacity:\"show\"},fadeOut:{opacity:\"hide\"},fadeToggle:{opacity:\"toggle\"}},function(e,r){S.fn[e]=function(e,t,n){return this.animate(r,e,t,n)}}),S.timers=[],S.fx.tick=function(){var e,t=0,n=S.timers;for(tt=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||S.fx.stop(),tt=void 0},S.fx.timer=function(e){S.timers.push(e),S.fx.start()},S.fx.interval=13,S.fx.start=function(){nt||(nt=!0,st())},S.fx.stop=function(){nt=null},S.fx.speeds={slow:600,fast:200,_default:400},S.fn.delay=function(r,e){return r=S.fx&&S.fx.speeds[r]||r,e=e||\"fx\",this.queue(e,function(e,t){var n=C.setTimeout(e,r);t.stop=function(){C.clearTimeout(n)}})},rt=E.createElement(\"input\"),it=E.createElement(\"select\").appendChild(E.createElement(\"option\")),rt.type=\"checkbox\",y.checkOn=\"\"!==rt.value,y.optSelected=it.selected,(rt=E.createElement(\"input\")).value=\"t\",rt.type=\"radio\",y.radioValue=\"t\"===rt.value;var pt,dt=S.expr.attrHandle;S.fn.extend({attr:function(e,t){return $(this,S.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){S.removeAttr(this,e)})}}),S.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return\"undefined\"==typeof e.getAttribute?S.prop(e,t,n):(1===o&&S.isXMLDoc(e)||(i=S.attrHooks[t.toLowerCase()]||(S.expr.match.bool.test(t)?pt:void 0)),void 0!==n?null===n?void S.removeAttr(e,t):i&&\"set\"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+\"\"),n):i&&\"get\"in i&&null!==(r=i.get(e,t))?r:null==(r=S.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!y.radioValue&&\"radio\"===t&&A(e,\"input\")){var n=e.value;return e.setAttribute(\"type\",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(P);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),pt={set:function(e,t,n){return!1===t?S.removeAttr(e,n):e.setAttribute(n,n),n}},S.each(S.expr.match.bool.source.match(/\\w+/g),function(e,t){var a=dt[t]||S.find.attr;dt[t]=function(e,t,n){var r,i,o=t.toLowerCase();return n||(i=dt[o],dt[o]=r,r=null!=a(e,t,n)?o:null,dt[o]=i),r}});var ht=/^(?:input|select|textarea|button)$/i,gt=/^(?:a|area)$/i;function vt(e){return(e.match(P)||[]).join(\" \")}function yt(e){return e.getAttribute&&e.getAttribute(\"class\")||\"\"}function mt(e){return Array.isArray(e)?e:\"string\"==typeof e&&e.match(P)||[]}S.fn.extend({prop:function(e,t){return $(this,S.prop,e,t,1<arguments.length)},removeProp:function(e){return this.each(function(){delete this[S.propFix[e]||e]})}}),S.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&S.isXMLDoc(e)||(t=S.propFix[t]||t,i=S.propHooks[t]),void 0!==n?i&&\"set\"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&\"get\"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=S.find.attr(e,\"tabindex\");return t?parseInt(t,10):ht.test(e.nodeName)||gt.test(e.nodeName)&&e.href?0:-1}}},propFix:{\"for\":\"htmlFor\",\"class\":\"className\"}}),y.optSelected||(S.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),S.each([\"tabIndex\",\"readOnly\",\"maxLength\",\"cellSpacing\",\"cellPadding\",\"rowSpan\",\"colSpan\",\"useMap\",\"frameBorder\",\"contentEditable\"],function(){S.propFix[this.toLowerCase()]=this}),S.fn.extend({addClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){S(this).addClass(t.call(this,e,yt(this)))});if((e=mt(t)).length)while(n=this[u++])if(i=yt(n),r=1===n.nodeType&&\" \"+vt(i)+\" \"){a=0;while(o=e[a++])r.indexOf(\" \"+o+\" \")<0&&(r+=o+\" \");i!==(s=vt(r))&&n.setAttribute(\"class\",s)}return this},removeClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){S(this).removeClass(t.call(this,e,yt(this)))});if(!arguments.length)return this.attr(\"class\",\"\");if((e=mt(t)).length)while(n=this[u++])if(i=yt(n),r=1===n.nodeType&&\" \"+vt(i)+\" \"){a=0;while(o=e[a++])while(-1<r.indexOf(\" \"+o+\" \"))r=r.replace(\" \"+o+\" \",\" \");i!==(s=vt(r))&&n.setAttribute(\"class\",s)}return this},toggleClass:function(i,t){var o=typeof i,a=\"string\"===o||Array.isArray(i);return\"boolean\"==typeof t&&a?t?this.addClass(i):this.removeClass(i):m(i)?this.each(function(e){S(this).toggleClass(i.call(this,e,yt(this),t),t)}):this.each(function(){var e,t,n,r;if(a){t=0,n=S(this),r=mt(i);while(e=r[t++])n.hasClass(e)?n.removeClass(e):n.addClass(e)}else void 0!==i&&\"boolean\"!==o||((e=yt(this))&&Y.set(this,\"__className__\",e),this.setAttribute&&this.setAttribute(\"class\",e||!1===i?\"\":Y.get(this,\"__className__\")||\"\"))})},hasClass:function(e){var t,n,r=0;t=\" \"+e+\" \";while(n=this[r++])if(1===n.nodeType&&-1<(\" \"+vt(yt(n))+\" \").indexOf(t))return!0;return!1}});var xt=/\\r/g;S.fn.extend({val:function(n){var r,e,i,t=this[0];return arguments.length?(i=m(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=i?n.call(this,e,S(this).val()):n)?t=\"\":\"number\"==typeof t?t+=\"\":Array.isArray(t)&&(t=S.map(t,function(e){return null==e?\"\":e+\"\"})),(r=S.valHooks[this.type]||S.valHooks[this.nodeName.toLowerCase()])&&\"set\"in r&&void 0!==r.set(this,t,\"value\")||(this.value=t))})):t?(r=S.valHooks[t.type]||S.valHooks[t.nodeName.toLowerCase()])&&\"get\"in r&&void 0!==(e=r.get(t,\"value\"))?e:\"string\"==typeof(e=t.value)?e.replace(xt,\"\"):null==e?\"\":e:void 0}}),S.extend({valHooks:{option:{get:function(e){var t=S.find.attr(e,\"value\");return null!=t?t:vt(S.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a=\"select-one\"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!A(n.parentNode,\"optgroup\"))){if(t=S(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=S.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=-1<S.inArray(S.valHooks.option.get(r),o))&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),S.each([\"radio\",\"checkbox\"],function(){S.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=-1<S.inArray(S(e).val(),t)}},y.checkOn||(S.valHooks[this].get=function(e){return null===e.getAttribute(\"value\")?\"on\":e.value})}),y.focusin=\"onfocusin\"in C;var bt=/^(?:focusinfocus|focusoutblur)$/,wt=function(e){e.stopPropagation()};S.extend(S.event,{trigger:function(e,t,n,r){var i,o,a,s,u,l,c,f,p=[n||E],d=v.call(e,\"type\")?e.type:e,h=v.call(e,\"namespace\")?e.namespace.split(\".\"):[];if(o=f=a=n=n||E,3!==n.nodeType&&8!==n.nodeType&&!bt.test(d+S.event.triggered)&&(-1<d.indexOf(\".\")&&(d=(h=d.split(\".\")).shift(),h.sort()),u=d.indexOf(\":\")<0&&\"on\"+d,(e=e[S.expando]?e:new S.Event(d,\"object\"==typeof e&&e)).isTrigger=r?2:3,e.namespace=h.join(\".\"),e.rnamespace=e.namespace?new RegExp(\"(^|\\\\.)\"+h.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:S.makeArray(t,[e]),c=S.event.special[d]||{},r||!c.trigger||!1!==c.trigger.apply(n,t))){if(!r&&!c.noBubble&&!x(n)){for(s=c.delegateType||d,bt.test(s+d)||(o=o.parentNode);o;o=o.parentNode)p.push(o),a=o;a===(n.ownerDocument||E)&&p.push(a.defaultView||a.parentWindow||C)}i=0;while((o=p[i++])&&!e.isPropagationStopped())f=o,e.type=1<i?s:c.bindType||d,(l=(Y.get(o,\"events\")||Object.create(null))[e.type]&&Y.get(o,\"handle\"))&&l.apply(o,t),(l=u&&o[u])&&l.apply&&V(o)&&(e.result=l.apply(o,t),!1===e.result&&e.preventDefault());return e.type=d,r||e.isDefaultPrevented()||c._default&&!1!==c._default.apply(p.pop(),t)||!V(n)||u&&m(n[d])&&!x(n)&&((a=n[u])&&(n[u]=null),S.event.triggered=d,e.isPropagationStopped()&&f.addEventListener(d,wt),n[d](),e.isPropagationStopped()&&f.removeEventListener(d,wt),S.event.triggered=void 0,a&&(n[u]=a)),e.result}},simulate:function(e,t,n){var r=S.extend(new S.Event,n,{type:e,isSimulated:!0});S.event.trigger(r,null,t)}}),S.fn.extend({trigger:function(e,t){return this.each(function(){S.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return S.event.trigger(e,t,n,!0)}}),y.focusin||S.each({focus:\"focusin\",blur:\"focusout\"},function(n,r){var i=function(e){S.event.simulate(r,e.target,S.event.fix(e))};S.event.special[r]={setup:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r);t||e.addEventListener(n,i,!0),Y.access(e,r,(t||0)+1)},teardown:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r)-1;t?Y.access(e,r,t):(e.removeEventListener(n,i,!0),Y.remove(e,r))}}});var Tt=C.location,Ct={guid:Date.now()},Et=/\\?/;S.parseXML=function(e){var t;if(!e||\"string\"!=typeof e)return null;try{t=(new C.DOMParser).parseFromString(e,\"text/xml\")}catch(e){t=void 0}return t&&!t.getElementsByTagName(\"parsererror\").length||S.error(\"Invalid XML: \"+e),t};var St=/\\[\\]$/,kt=/\\r?\\n/g,At=/^(?:submit|button|image|reset|file)$/i,Nt=/^(?:input|select|textarea|keygen)/i;function Dt(n,e,r,i){var t;if(Array.isArray(e))S.each(e,function(e,t){r||St.test(n)?i(n,t):Dt(n+\"[\"+(\"object\"==typeof t&&null!=t?e:\"\")+\"]\",t,r,i)});else if(r||\"object\"!==w(e))i(n,e);else for(t in e)Dt(n+\"[\"+t+\"]\",e[t],r,i)}S.param=function(e,t){var n,r=[],i=function(e,t){var n=m(t)?t():t;r[r.length]=encodeURIComponent(e)+\"=\"+encodeURIComponent(null==n?\"\":n)};if(null==e)return\"\";if(Array.isArray(e)||e.jquery&&!S.isPlainObject(e))S.each(e,function(){i(this.name,this.value)});else for(n in e)Dt(n,e[n],t,i);return r.join(\"&\")},S.fn.extend({serialize:function(){return S.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=S.prop(this,\"elements\");return e?S.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!S(this).is(\":disabled\")&&Nt.test(this.nodeName)&&!At.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=S(this).val();return null==n?null:Array.isArray(n)?S.map(n,function(e){return{name:t.name,value:e.replace(kt,\"\\r\\n\")}}):{name:t.name,value:n.replace(kt,\"\\r\\n\")}}).get()}});var jt=/%20/g,qt=/#.*$/,Lt=/([?&])_=[^&]*/,Ht=/^(.*?):[ \\t]*([^\\r\\n]*)$/gm,Ot=/^(?:GET|HEAD)$/,Pt=/^\\/\\//,Rt={},Mt={},It=\"*/\".concat(\"*\"),Wt=E.createElement(\"a\");function Ft(o){return function(e,t){\"string\"!=typeof e&&(t=e,e=\"*\");var n,r=0,i=e.toLowerCase().match(P)||[];if(m(t))while(n=i[r++])\"+\"===n[0]?(n=n.slice(1)||\"*\",(o[n]=o[n]||[]).unshift(t)):(o[n]=o[n]||[]).push(t)}}function Bt(t,i,o,a){var s={},u=t===Mt;function l(e){var r;return s[e]=!0,S.each(t[e]||[],function(e,t){var n=t(i,o,a);return\"string\"!=typeof n||u||s[n]?u?!(r=n):void 0:(i.dataTypes.unshift(n),l(n),!1)}),r}return l(i.dataTypes[0])||!s[\"*\"]&&l(\"*\")}function $t(e,t){var n,r,i=S.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&S.extend(!0,e,r),e}Wt.href=Tt.href,S.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Tt.href,type:\"GET\",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(Tt.protocol),global:!0,processData:!0,async:!0,contentType:\"application/x-www-form-urlencoded; charset=UTF-8\",accepts:{\"*\":It,text:\"text/plain\",html:\"text/html\",xml:\"application/xml, text/xml\",json:\"application/json, text/javascript\"},contents:{xml:/\\bxml\\b/,html:/\\bhtml/,json:/\\bjson\\b/},responseFields:{xml:\"responseXML\",text:\"responseText\",json:\"responseJSON\"},converters:{\"* text\":String,\"text html\":!0,\"text json\":JSON.parse,\"text xml\":S.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?$t($t(e,S.ajaxSettings),t):$t(S.ajaxSettings,e)},ajaxPrefilter:Ft(Rt),ajaxTransport:Ft(Mt),ajax:function(e,t){\"object\"==typeof e&&(t=e,e=void 0),t=t||{};var c,f,p,n,d,r,h,g,i,o,v=S.ajaxSetup({},t),y=v.context||v,m=v.context&&(y.nodeType||y.jquery)?S(y):S.event,x=S.Deferred(),b=S.Callbacks(\"once memory\"),w=v.statusCode||{},a={},s={},u=\"canceled\",T={readyState:0,getResponseHeader:function(e){var t;if(h){if(!n){n={};while(t=Ht.exec(p))n[t[1].toLowerCase()+\" \"]=(n[t[1].toLowerCase()+\" \"]||[]).concat(t[2])}t=n[e.toLowerCase()+\" \"]}return null==t?null:t.join(\", \")},getAllResponseHeaders:function(){return h?p:null},setRequestHeader:function(e,t){return null==h&&(e=s[e.toLowerCase()]=s[e.toLowerCase()]||e,a[e]=t),this},overrideMimeType:function(e){return null==h&&(v.mimeType=e),this},statusCode:function(e){var t;if(e)if(h)T.always(e[T.status]);else for(t in e)w[t]=[w[t],e[t]];return this},abort:function(e){var t=e||u;return c&&c.abort(t),l(0,t),this}};if(x.promise(T),v.url=((e||v.url||Tt.href)+\"\").replace(Pt,Tt.protocol+\"//\"),v.type=t.method||t.type||v.method||v.type,v.dataTypes=(v.dataType||\"*\").toLowerCase().match(P)||[\"\"],null==v.crossDomain){r=E.createElement(\"a\");try{r.href=v.url,r.href=r.href,v.crossDomain=Wt.protocol+\"//\"+Wt.host!=r.protocol+\"//\"+r.host}catch(e){v.crossDomain=!0}}if(v.data&&v.processData&&\"string\"!=typeof v.data&&(v.data=S.param(v.data,v.traditional)),Bt(Rt,v,t,T),h)return T;for(i in(g=S.event&&v.global)&&0==S.active++&&S.event.trigger(\"ajaxStart\"),v.type=v.type.toUpperCase(),v.hasContent=!Ot.test(v.type),f=v.url.replace(qt,\"\"),v.hasContent?v.data&&v.processData&&0===(v.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&(v.data=v.data.replace(jt,\"+\")):(o=v.url.slice(f.length),v.data&&(v.processData||\"string\"==typeof v.data)&&(f+=(Et.test(f)?\"&\":\"?\")+v.data,delete v.data),!1===v.cache&&(f=f.replace(Lt,\"$1\"),o=(Et.test(f)?\"&\":\"?\")+\"_=\"+Ct.guid+++o),v.url=f+o),v.ifModified&&(S.lastModified[f]&&T.setRequestHeader(\"If-Modified-Since\",S.lastModified[f]),S.etag[f]&&T.setRequestHeader(\"If-None-Match\",S.etag[f])),(v.data&&v.hasContent&&!1!==v.contentType||t.contentType)&&T.setRequestHeader(\"Content-Type\",v.contentType),T.setRequestHeader(\"Accept\",v.dataTypes[0]&&v.accepts[v.dataTypes[0]]?v.accepts[v.dataTypes[0]]+(\"*\"!==v.dataTypes[0]?\", \"+It+\"; q=0.01\":\"\"):v.accepts[\"*\"]),v.headers)T.setRequestHeader(i,v.headers[i]);if(v.beforeSend&&(!1===v.beforeSend.call(y,T,v)||h))return T.abort();if(u=\"abort\",b.add(v.complete),T.done(v.success),T.fail(v.error),c=Bt(Mt,v,t,T)){if(T.readyState=1,g&&m.trigger(\"ajaxSend\",[T,v]),h)return T;v.async&&0<v.timeout&&(d=C.setTimeout(function(){T.abort(\"timeout\")},v.timeout));try{h=!1,c.send(a,l)}catch(e){if(h)throw e;l(-1,e)}}else l(-1,\"No Transport\");function l(e,t,n,r){var i,o,a,s,u,l=t;h||(h=!0,d&&C.clearTimeout(d),c=void 0,p=r||\"\",T.readyState=0<e?4:0,i=200<=e&&e<300||304===e,n&&(s=function(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while(\"*\"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader(\"Content-Type\"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+\" \"+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}(v,T,n)),!i&&-1<S.inArray(\"script\",v.dataTypes)&&(v.converters[\"text script\"]=function(){}),s=function(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if(\"*\"===o)o=u;else if(\"*\"!==u&&u!==o){if(!(a=l[u+\" \"+o]||l[\"* \"+o]))for(i in l)if((s=i.split(\" \"))[1]===o&&(a=l[u+\" \"+s[0]]||l[\"* \"+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e[\"throws\"])t=a(t);else try{t=a(t)}catch(e){return{state:\"parsererror\",error:a?e:\"No conversion from \"+u+\" to \"+o}}}return{state:\"success\",data:t}}(v,s,T,i),i?(v.ifModified&&((u=T.getResponseHeader(\"Last-Modified\"))&&(S.lastModified[f]=u),(u=T.getResponseHeader(\"etag\"))&&(S.etag[f]=u)),204===e||\"HEAD\"===v.type?l=\"nocontent\":304===e?l=\"notmodified\":(l=s.state,o=s.data,i=!(a=s.error))):(a=l,!e&&l||(l=\"error\",e<0&&(e=0))),T.status=e,T.statusText=(t||l)+\"\",i?x.resolveWith(y,[o,l,T]):x.rejectWith(y,[T,l,a]),T.statusCode(w),w=void 0,g&&m.trigger(i?\"ajaxSuccess\":\"ajaxError\",[T,v,i?o:a]),b.fireWith(y,[T,l]),g&&(m.trigger(\"ajaxComplete\",[T,v]),--S.active||S.event.trigger(\"ajaxStop\")))}return T},getJSON:function(e,t,n){return S.get(e,t,n,\"json\")},getScript:function(e,t){return S.get(e,void 0,t,\"script\")}}),S.each([\"get\",\"post\"],function(e,i){S[i]=function(e,t,n,r){return m(t)&&(r=r||n,n=t,t=void 0),S.ajax(S.extend({url:e,type:i,dataType:r,data:t,success:n},S.isPlainObject(e)&&e))}}),S.ajaxPrefilter(function(e){var t;for(t in e.headers)\"content-type\"===t.toLowerCase()&&(e.contentType=e.headers[t]||\"\")}),S._evalUrl=function(e,t,n){return S.ajax({url:e,type:\"GET\",dataType:\"script\",cache:!0,async:!1,global:!1,converters:{\"text script\":function(){}},dataFilter:function(e){S.globalEval(e,t,n)}})},S.fn.extend({wrapAll:function(e){var t;return this[0]&&(m(e)&&(e=e.call(this[0])),t=S(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(n){return m(n)?this.each(function(e){S(this).wrapInner(n.call(this,e))}):this.each(function(){var e=S(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=m(t);return this.each(function(e){S(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(e){return this.parent(e).not(\"body\").each(function(){S(this).replaceWith(this.childNodes)}),this}}),S.expr.pseudos.hidden=function(e){return!S.expr.pseudos.visible(e)},S.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},S.ajaxSettings.xhr=function(){try{return new C.XMLHttpRequest}catch(e){}};var _t={0:200,1223:204},zt=S.ajaxSettings.xhr();y.cors=!!zt&&\"withCredentials\"in zt,y.ajax=zt=!!zt,S.ajaxTransport(function(i){var o,a;if(y.cors||zt&&!i.crossDomain)return{send:function(e,t){var n,r=i.xhr();if(r.open(i.type,i.url,i.async,i.username,i.password),i.xhrFields)for(n in i.xhrFields)r[n]=i.xhrFields[n];for(n in i.mimeType&&r.overrideMimeType&&r.overrideMimeType(i.mimeType),i.crossDomain||e[\"X-Requested-With\"]||(e[\"X-Requested-With\"]=\"XMLHttpRequest\"),e)r.setRequestHeader(n,e[n]);o=function(e){return function(){o&&(o=a=r.onload=r.onerror=r.onabort=r.ontimeout=r.onreadystatechange=null,\"abort\"===e?r.abort():\"error\"===e?\"number\"!=typeof r.status?t(0,\"error\"):t(r.status,r.statusText):t(_t[r.status]||r.status,r.statusText,\"text\"!==(r.responseType||\"text\")||\"string\"!=typeof r.responseText?{binary:r.response}:{text:r.responseText},r.getAllResponseHeaders()))}},r.onload=o(),a=r.onerror=r.ontimeout=o(\"error\"),void 0!==r.onabort?r.onabort=a:r.onreadystatechange=function(){4===r.readyState&&C.setTimeout(function(){o&&a()})},o=o(\"abort\");try{r.send(i.hasContent&&i.data||null)}catch(e){if(o)throw e}},abort:function(){o&&o()}}}),S.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),S.ajaxSetup({accepts:{script:\"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"},contents:{script:/\\b(?:java|ecma)script\\b/},converters:{\"text script\":function(e){return S.globalEval(e),e}}}),S.ajaxPrefilter(\"script\",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type=\"GET\")}),S.ajaxTransport(\"script\",function(n){var r,i;if(n.crossDomain||n.scriptAttrs)return{send:function(e,t){r=S(\"<script>\").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on(\"load error\",i=function(e){r.remove(),i=null,e&&t(\"error\"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\\?(?=&|$)|\\?\\?/;S.ajaxSetup({jsonp:\"callback\",jsonpCallback:function(){var e=Xt.pop()||S.expando+\"_\"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter(\"json jsonp\",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?\"url\":\"string\"==typeof e.data&&0===(e.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&Vt.test(e.data)&&\"data\");if(a||\"jsonp\"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,\"$1\"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?\"&\":\"?\")+e.jsonp+\"=\"+r),e.converters[\"script json\"]=function(){return o||S.error(r+\" was not called\"),o[0]},e.dataTypes[0]=\"json\",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),\"script\"}),y.createHTMLDocument=((Ut=E.implementation.createHTMLDocument(\"\").body).innerHTML=\"<form></form><form></form>\",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return\"string\"!=typeof e?[]:(\"boolean\"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument(\"\")).createElement(\"base\")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(\" \");return-1<s&&(r=vt(e.slice(s)),e=e.slice(0,s)),m(t)?(n=t,t=void 0):t&&\"object\"==typeof t&&(i=\"POST\"),0<a.length&&S.ajax({url:e,type:i||\"GET\",dataType:\"html\",data:t}).done(function(e){o=arguments,a.html(r?S(\"<div>\").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,\"position\"),c=S(e),f={};\"static\"===l&&(e.style.position=\"relative\"),s=c.offset(),o=S.css(e,\"top\"),u=S.css(e,\"left\"),(\"absolute\"===l||\"fixed\"===l)&&-1<(o+u).indexOf(\"auto\")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),\"using\"in t?t.using.call(e,f):(\"number\"==typeof f.top&&(f.top+=\"px\"),\"number\"==typeof f.left&&(f.left+=\"px\"),c.css(f))}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if(\"fixed\"===S.css(r,\"position\"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&\"static\"===S.css(e,\"position\"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,\"borderTopWidth\",!0),i.left+=S.css(e,\"borderLeftWidth\",!0))}return{top:t.top-i.top-S.css(r,\"marginTop\",!0),left:t.left-i.left-S.css(r,\"marginLeft\",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&\"static\"===S.css(e,\"position\"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:\"pageXOffset\",scrollTop:\"pageYOffset\"},function(t,i){var o=\"pageYOffset\"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each([\"top\",\"left\"],function(e,n){S.cssHooks[n]=$e(y.pixelPosition,function(e,t){if(t)return t=Be(e,n),Me.test(t)?S(e).position()[n]+\"px\":t})}),S.each({Height:\"height\",Width:\"width\"},function(a,s){S.each({padding:\"inner\"+a,content:s,\"\":\"outer\"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||\"boolean\"!=typeof e),i=r||(!0===e||!0===t?\"margin\":\"border\");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf(\"outer\")?e[\"inner\"+a]:e.document.documentElement[\"client\"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body[\"scroll\"+a],r[\"scroll\"+a],e.body[\"offset\"+a],r[\"offset\"+a],r[\"client\"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each([\"ajaxStart\",\"ajaxStop\",\"ajaxComplete\",\"ajaxError\",\"ajaxSuccess\",\"ajaxSend\"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,\"**\"):this.off(t,e||\"**\",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each(\"blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu\".split(\" \"),function(e,n){S.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}});var Gt=/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g;S.proxy=function(e,t){var n,r,i;if(\"string\"==typeof t&&(n=e[t],t=e,e=n),m(e))return r=s.call(arguments,2),(i=function(){return e.apply(t||this,r.concat(s.call(arguments)))}).guid=e.guid=e.guid||S.guid++,i},S.holdReady=function(e){e?S.readyWait++:S.ready(!0)},S.isArray=Array.isArray,S.parseJSON=JSON.parse,S.nodeName=A,S.isFunction=m,S.isWindow=x,S.camelCase=X,S.type=w,S.now=Date.now,S.isNumeric=function(e){var t=S.type(e);return(\"number\"===t||\"string\"===t)&&!isNaN(e-parseFloat(e))},S.trim=function(e){return null==e?\"\":(e+\"\").replace(Gt,\"\")},\"function\"==typeof define&&define.amd&&define(\"jquery\",[],function(){return S});var Yt=C.jQuery,Qt=C.$;return S.noConflict=function(e){return C.$===S&&(C.$=Qt),e&&C.jQuery===S&&(C.jQuery=Yt),S},\"undefined\"==typeof e&&(C.jQuery=C.$=S),S});\n"
  },
  {
    "path": "docs/_static/js/badge_only.js",
    "content": "!function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){\"undefined\"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:\"Module\"}),Object.defineProperty(e,\"__esModule\",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&\"object\"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,\"default\",{enumerable:!0,value:e}),2&t&&\"string\"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,\"a\",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p=\"\",r(r.s=4)}({4:function(e,t,r){}});"
  },
  {
    "path": "docs/_static/js/theme.js",
    "content": "!function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){\"undefined\"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:\"Module\"}),Object.defineProperty(n,\"__esModule\",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&\"object\"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,\"default\",{enumerable:!0,value:n}),2&e&&\"string\"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,\"a\",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p=\"\",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e=\"undefined\"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on(\"hashchange\",t.reset),n&&t.win.on(\"scroll\",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on(\"resize\",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n(\"div.wy-side-scroll:first\"),this.win=n(window),n(document).on(\"click\",\"[data-toggle='wy-nav-top']\",(function(){n(\"[data-toggle='wy-nav-shift']\").toggleClass(\"shift\"),n(\"[data-toggle='rst-versions']\").toggleClass(\"shift\")})).on(\"click\",\".wy-menu-vertical .current ul li a\",(function(){var t=n(this);n(\"[data-toggle='wy-nav-shift']\").removeClass(\"shift\"),n(\"[data-toggle='rst-versions']\").toggleClass(\"shift\"),e.toggleCurrent(t),e.hashChange()})).on(\"click\",\"[data-toggle='rst-current-version']\",(function(){n(\"[data-toggle='rst-versions']\").toggleClass(\"shift-up\")})),n(\"table.docutils:not(.field-list,.footnote,.citation)\").wrap(\"<div class='wy-table-responsive'></div>\"),n(\"table.docutils.footnote\").wrap(\"<div class='wy-table-responsive footnote'></div>\"),n(\"table.docutils.citation\").wrap(\"<div class='wy-table-responsive citation'></div>\"),n(\".wy-menu-vertical ul\").not(\".simple\").siblings(\"a\").each((function(){var t=n(this);expand=n('<span class=\"toctree-expand\"></span>'),expand.on(\"click\",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||\"#\";try{var e=$(\".wy-menu-vertical\"),t=e.find('[href=\"'+n+'\"]');if(0===t.length){var i=$('.document [id=\"'+n.substring(1)+'\"]').closest(\"div.section\");0===(t=e.find('[href=\"#'+i.attr(\"id\")+'\"]')).length&&(t=e.find('[href=\"#\"]'))}t.length>0&&($(\".wy-menu-vertical .current\").removeClass(\"current\"),t.addClass(\"current\"),t.closest(\"li.toctree-l1\").addClass(\"current\"),t.closest(\"li.toctree-l1\").parent().addClass(\"current\"),t.closest(\"li.toctree-l1\").addClass(\"current\"),t.closest(\"li.toctree-l2\").addClass(\"current\"),t.closest(\"li.toctree-l3\").addClass(\"current\"),t.closest(\"li.toctree-l4\").addClass(\"current\"),t.closest(\"li.toctree-l5\").addClass(\"current\"),t[0].scrollIntoView())}catch(n){console.log(\"Error expanding nav for anchor\",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one(\"hashchange\",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest(\"li\");e.siblings(\"li.current\").removeClass(\"current\"),e.siblings().find(\"li.current\").removeClass(\"current\"),e.find(\"> ul li.current\").removeClass(\"current\"),e.toggleClass(\"current\")}},\"undefined\"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=[\"ms\",\"moz\",\"webkit\",\"o\"],t=0;t<e.length&&!window.requestAnimationFrame;++t)window.requestAnimationFrame=window[e[t]+\"RequestAnimationFrame\"],window.cancelAnimationFrame=window[e[t]+\"CancelAnimationFrame\"]||window[e[t]+\"CancelRequestAnimationFrame\"];window.requestAnimationFrame||(window.requestAnimationFrame=function(e,t){var i=(new Date).getTime(),o=Math.max(0,16-(i-n)),r=window.setTimeout((function(){e(i+o)}),o);return n=i+o,r}),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(n){clearTimeout(n)})}()}).call(window)},function(n,e){n.exports=jQuery},function(n,e,t){}]);"
  },
  {
    "path": "docs/_static/language_data.js",
    "content": "/*\n * language_data.js\n * ~~~~~~~~~~~~~~~~\n *\n * This script contains the language-specific data used by searchtools.js,\n * namely the list of stopwords, stemmer, scorer and splitter.\n *\n * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.\n * :license: BSD, see LICENSE for details.\n *\n */\n\nvar stopwords = [\"a\",\"and\",\"are\",\"as\",\"at\",\"be\",\"but\",\"by\",\"for\",\"if\",\"in\",\"into\",\"is\",\"it\",\"near\",\"no\",\"not\",\"of\",\"on\",\"or\",\"such\",\"that\",\"the\",\"their\",\"then\",\"there\",\"these\",\"they\",\"this\",\"to\",\"was\",\"will\",\"with\"];\n\n\n/* Non-minified version is copied as a separate JS file, is available */\n\n/**\n * Porter Stemmer\n */\nvar Stemmer = function() {\n\n  var step2list = {\n    ational: 'ate',\n    tional: 'tion',\n    enci: 'ence',\n    anci: 'ance',\n    izer: 'ize',\n    bli: 'ble',\n    alli: 'al',\n    entli: 'ent',\n    eli: 'e',\n    ousli: 'ous',\n    ization: 'ize',\n    ation: 'ate',\n    ator: 'ate',\n    alism: 'al',\n    iveness: 'ive',\n    fulness: 'ful',\n    ousness: 'ous',\n    aliti: 'al',\n    iviti: 'ive',\n    biliti: 'ble',\n    logi: 'log'\n  };\n\n  var step3list = {\n    icate: 'ic',\n    ative: '',\n    alize: 'al',\n    iciti: 'ic',\n    ical: 'ic',\n    ful: '',\n    ness: ''\n  };\n\n  var c = \"[^aeiou]\";          // consonant\n  var v = \"[aeiouy]\";          // vowel\n  var C = c + \"[^aeiouy]*\";    // consonant sequence\n  var V = v + \"[aeiou]*\";      // vowel sequence\n\n  var mgr0 = \"^(\" + C + \")?\" + V + C;                      // [C]VC... is m>0\n  var meq1 = \"^(\" + C + \")?\" + V + C + \"(\" + V + \")?$\";    // [C]VC[V] is m=1\n  var mgr1 = \"^(\" + C + \")?\" + V + C + V + C;              // [C]VCVC... is m>1\n  var s_v   = \"^(\" + C + \")?\" + v;                         // vowel in stem\n\n  this.stemWord = function (w) {\n    var stem;\n    var suffix;\n    var firstch;\n    var origword = w;\n\n    if (w.length < 3)\n      return w;\n\n    var re;\n    var re2;\n    var re3;\n    var re4;\n\n    firstch = w.substr(0,1);\n    if (firstch == \"y\")\n      w = firstch.toUpperCase() + w.substr(1);\n\n    // Step 1a\n    re = /^(.+?)(ss|i)es$/;\n    re2 = /^(.+?)([^s])s$/;\n\n    if (re.test(w))\n      w = w.replace(re,\"$1$2\");\n    else if (re2.test(w))\n      w = w.replace(re2,\"$1$2\");\n\n    // Step 1b\n    re = /^(.+?)eed$/;\n    re2 = /^(.+?)(ed|ing)$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      re = new RegExp(mgr0);\n      if (re.test(fp[1])) {\n        re = /.$/;\n        w = w.replace(re,\"\");\n      }\n    }\n    else if (re2.test(w)) {\n      var fp = re2.exec(w);\n      stem = fp[1];\n      re2 = new RegExp(s_v);\n      if (re2.test(stem)) {\n        w = stem;\n        re2 = /(at|bl|iz)$/;\n        re3 = new RegExp(\"([^aeiouylsz])\\\\1$\");\n        re4 = new RegExp(\"^\" + C + v + \"[^aeiouwxy]$\");\n        if (re2.test(w))\n          w = w + \"e\";\n        else if (re3.test(w)) {\n          re = /.$/;\n          w = w.replace(re,\"\");\n        }\n        else if (re4.test(w))\n          w = w + \"e\";\n      }\n    }\n\n    // Step 1c\n    re = /^(.+?)y$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      re = new RegExp(s_v);\n      if (re.test(stem))\n        w = stem + \"i\";\n    }\n\n    // Step 2\n    re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      suffix = fp[2];\n      re = new RegExp(mgr0);\n      if (re.test(stem))\n        w = stem + step2list[suffix];\n    }\n\n    // Step 3\n    re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      suffix = fp[2];\n      re = new RegExp(mgr0);\n      if (re.test(stem))\n        w = stem + step3list[suffix];\n    }\n\n    // Step 4\n    re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;\n    re2 = /^(.+?)(s|t)(ion)$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      re = new RegExp(mgr1);\n      if (re.test(stem))\n        w = stem;\n    }\n    else if (re2.test(w)) {\n      var fp = re2.exec(w);\n      stem = fp[1] + fp[2];\n      re2 = new RegExp(mgr1);\n      if (re2.test(stem))\n        w = stem;\n    }\n\n    // Step 5\n    re = /^(.+?)e$/;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      re = new RegExp(mgr1);\n      re2 = new RegExp(meq1);\n      re3 = new RegExp(\"^\" + C + v + \"[^aeiouwxy]$\");\n      if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))\n        w = stem;\n    }\n    re = /ll$/;\n    re2 = new RegExp(mgr1);\n    if (re.test(w) && re2.test(w)) {\n      re = /.$/;\n      w = w.replace(re,\"\");\n    }\n\n    // and turn initial Y back to y\n    if (firstch == \"y\")\n      w = firstch.toLowerCase() + w.substr(1);\n    return w;\n  }\n}\n\n\n\n\nvar splitChars = (function() {\n    var result = {};\n    var singles = [96, 180, 187, 191, 215, 247, 749, 885, 903, 907, 909, 930, 1014, 1648,\n         1748, 1809, 2416, 2473, 2481, 2526, 2601, 2609, 2612, 2615, 2653, 2702,\n         2706, 2729, 2737, 2740, 2857, 2865, 2868, 2910, 2928, 2948, 2961, 2971,\n         2973, 3085, 3089, 3113, 3124, 3213, 3217, 3241, 3252, 3295, 3341, 3345,\n         3369, 3506, 3516, 3633, 3715, 3721, 3736, 3744, 3748, 3750, 3756, 3761,\n         3781, 3912, 4239, 4347, 4681, 4695, 4697, 4745, 4785, 4799, 4801, 4823,\n         4881, 5760, 5901, 5997, 6313, 7405, 8024, 8026, 8028, 8030, 8117, 8125,\n         8133, 8181, 8468, 8485, 8487, 8489, 8494, 8527, 11311, 11359, 11687, 11695,\n         11703, 11711, 11719, 11727, 11735, 12448, 12539, 43010, 43014, 43019, 43587,\n         43696, 43713, 64286, 64297, 64311, 64317, 64319, 64322, 64325, 65141];\n    var i, j, start, end;\n    for (i = 0; i < singles.length; i++) {\n        result[singles[i]] = true;\n    }\n    var ranges = [[0, 47], [58, 64], [91, 94], [123, 169], [171, 177], [182, 184], [706, 709],\n         [722, 735], [741, 747], [751, 879], [888, 889], [894, 901], [1154, 1161],\n         [1318, 1328], [1367, 1368], [1370, 1376], [1416, 1487], [1515, 1519], [1523, 1568],\n         [1611, 1631], [1642, 1645], [1750, 1764], [1767, 1773], [1789, 1790], [1792, 1807],\n         [1840, 1868], [1958, 1968], [1970, 1983], [2027, 2035], [2038, 2041], [2043, 2047],\n         [2070, 2073], [2075, 2083], [2085, 2087], [2089, 2307], [2362, 2364], [2366, 2383],\n         [2385, 2391], [2402, 2405], [2419, 2424], [2432, 2436], [2445, 2446], [2449, 2450],\n         [2483, 2485], [2490, 2492], [2494, 2509], [2511, 2523], [2530, 2533], [2546, 2547],\n         [2554, 2564], [2571, 2574], [2577, 2578], [2618, 2648], [2655, 2661], [2672, 2673],\n         [2677, 2692], [2746, 2748], [2750, 2767], [2769, 2783], [2786, 2789], [2800, 2820],\n         [2829, 2830], [2833, 2834], [2874, 2876], [2878, 2907], [2914, 2917], [2930, 2946],\n         [2955, 2957], [2966, 2968], [2976, 2978], [2981, 2983], [2987, 2989], [3002, 3023],\n         [3025, 3045], [3059, 3076], [3130, 3132], [3134, 3159], [3162, 3167], [3170, 3173],\n         [3184, 3191], [3199, 3204], [3258, 3260], [3262, 3293], [3298, 3301], [3312, 3332],\n         [3386, 3388], [3390, 3423], [3426, 3429], [3446, 3449], [3456, 3460], [3479, 3481],\n         [3518, 3519], [3527, 3584], [3636, 3647], [3655, 3663], [3674, 3712], [3717, 3718],\n         [3723, 3724], [3726, 3731], [3752, 3753], [3764, 3772], [3774, 3775], [3783, 3791],\n         [3802, 3803], [3806, 3839], [3841, 3871], [3892, 3903], [3949, 3975], [3980, 4095],\n         [4139, 4158], [4170, 4175], [4182, 4185], [4190, 4192], [4194, 4196], [4199, 4205],\n         [4209, 4212], [4226, 4237], [4250, 4255], [4294, 4303], [4349, 4351], [4686, 4687],\n         [4702, 4703], [4750, 4751], [4790, 4791], [4806, 4807], [4886, 4887], [4955, 4968],\n         [4989, 4991], [5008, 5023], [5109, 5120], [5741, 5742], [5787, 5791], [5867, 5869],\n         [5873, 5887], [5906, 5919], [5938, 5951], [5970, 5983], [6001, 6015], [6068, 6102],\n         [6104, 6107], [6109, 6111], [6122, 6127], [6138, 6159], [6170, 6175], [6264, 6271],\n         [6315, 6319], [6390, 6399], [6429, 6469], [6510, 6511], [6517, 6527], [6572, 6592],\n         [6600, 6607], [6619, 6655], [6679, 6687], [6741, 6783], [6794, 6799], [6810, 6822],\n         [6824, 6916], [6964, 6980], [6988, 6991], [7002, 7042], [7073, 7085], [7098, 7167],\n         [7204, 7231], [7242, 7244], [7294, 7400], [7410, 7423], [7616, 7679], [7958, 7959],\n         [7966, 7967], [8006, 8007], [8014, 8015], [8062, 8063], [8127, 8129], [8141, 8143],\n         [8148, 8149], [8156, 8159], [8173, 8177], [8189, 8303], [8306, 8307], [8314, 8318],\n         [8330, 8335], [8341, 8449], [8451, 8454], [8456, 8457], [8470, 8472], [8478, 8483],\n         [8506, 8507], [8512, 8516], [8522, 8525], [8586, 9311], [9372, 9449], [9472, 10101],\n         [10132, 11263], [11493, 11498], [11503, 11516], [11518, 11519], [11558, 11567],\n         [11622, 11630], [11632, 11647], [11671, 11679], [11743, 11822], [11824, 12292],\n         [12296, 12320], [12330, 12336], [12342, 12343], [12349, 12352], [12439, 12444],\n         [12544, 12548], [12590, 12592], [12687, 12689], [12694, 12703], [12728, 12783],\n         [12800, 12831], [12842, 12880], [12896, 12927], [12938, 12976], [12992, 13311],\n         [19894, 19967], [40908, 40959], [42125, 42191], [42238, 42239], [42509, 42511],\n         [42540, 42559], [42592, 42593], [42607, 42622], [42648, 42655], [42736, 42774],\n         [42784, 42785], [42889, 42890], [42893, 43002], [43043, 43055], [43062, 43071],\n         [43124, 43137], [43188, 43215], [43226, 43249], [43256, 43258], [43260, 43263],\n         [43302, 43311], [43335, 43359], [43389, 43395], [43443, 43470], [43482, 43519],\n         [43561, 43583], [43596, 43599], [43610, 43615], [43639, 43641], [43643, 43647],\n         [43698, 43700], [43703, 43704], [43710, 43711], [43715, 43738], [43742, 43967],\n         [44003, 44015], [44026, 44031], [55204, 55215], [55239, 55242], [55292, 55295],\n         [57344, 63743], [64046, 64047], [64110, 64111], [64218, 64255], [64263, 64274],\n         [64280, 64284], [64434, 64466], [64830, 64847], [64912, 64913], [64968, 65007],\n         [65020, 65135], [65277, 65295], [65306, 65312], [65339, 65344], [65371, 65381],\n         [65471, 65473], [65480, 65481], [65488, 65489], [65496, 65497]];\n    for (i = 0; i < ranges.length; i++) {\n        start = ranges[i][0];\n        end = ranges[i][1];\n        for (j = start; j <= end; j++) {\n            result[j] = true;\n        }\n    }\n    return result;\n})();\n\nfunction splitQuery(query) {\n    var result = [];\n    var start = -1;\n    for (var i = 0; i < query.length; i++) {\n        if (splitChars[query.charCodeAt(i)]) {\n            if (start !== -1) {\n                result.push(query.slice(start, i));\n                start = -1;\n            }\n        } else if (start === -1) {\n            start = i;\n        }\n    }\n    if (start !== -1) {\n        result.push(query.slice(start));\n    }\n    return result;\n}\n\n\n"
  },
  {
    "path": "docs/_static/pygments.css",
    "content": "pre { line-height: 125%; }\ntd.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\nspan.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\ntd.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\nspan.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n.highlight .hll { background-color: #ffffcc }\n.highlight { background: #f8f8f8; }\n.highlight .c { color: #408080; font-style: italic } /* Comment */\n.highlight .err { border: 1px solid #FF0000 } /* Error */\n.highlight .k { color: #008000; font-weight: bold } /* Keyword */\n.highlight .o { color: #666666 } /* Operator */\n.highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n.highlight .cp { color: #BC7A00 } /* Comment.Preproc */\n.highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */\n.highlight .cs { color: #408080; font-style: italic } /* Comment.Special */\n.highlight .gd { color: #A00000 } /* Generic.Deleted */\n.highlight .ge { font-style: italic } /* Generic.Emph */\n.highlight .gr { color: #FF0000 } /* Generic.Error */\n.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n.highlight .gi { color: #00A000 } /* Generic.Inserted */\n.highlight .go { color: #888888 } /* Generic.Output */\n.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n.highlight .gs { font-weight: bold } /* Generic.Strong */\n.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n.highlight .gt { color: #0044DD } /* Generic.Traceback */\n.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n.highlight .kp { color: #008000 } /* Keyword.Pseudo */\n.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n.highlight .kt { color: #B00040 } /* Keyword.Type */\n.highlight .m { color: #666666 } /* Literal.Number */\n.highlight .s { color: #BA2121 } /* Literal.String */\n.highlight .na { color: #7D9029 } /* Name.Attribute */\n.highlight .nb { color: #008000 } /* Name.Builtin */\n.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n.highlight .no { color: #880000 } /* Name.Constant */\n.highlight .nd { color: #AA22FF } /* Name.Decorator */\n.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */\n.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n.highlight .nf { color: #0000FF } /* Name.Function */\n.highlight .nl { color: #A0A000 } /* Name.Label */\n.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */\n.highlight .nv { color: #19177C } /* Name.Variable */\n.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n.highlight .w { color: #bbbbbb } /* Text.Whitespace */\n.highlight .mb { color: #666666 } /* Literal.Number.Bin */\n.highlight .mf { color: #666666 } /* Literal.Number.Float */\n.highlight .mh { color: #666666 } /* Literal.Number.Hex */\n.highlight .mi { color: #666666 } /* Literal.Number.Integer */\n.highlight .mo { color: #666666 } /* Literal.Number.Oct */\n.highlight .sa { color: #BA2121 } /* Literal.String.Affix */\n.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */\n.highlight .sc { color: #BA2121 } /* Literal.String.Char */\n.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */\n.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n.highlight .s2 { color: #BA2121 } /* Literal.String.Double */\n.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */\n.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n.highlight .sx { color: #008000 } /* Literal.String.Other */\n.highlight .sr { color: #BB6688 } /* Literal.String.Regex */\n.highlight .s1 { color: #BA2121 } /* Literal.String.Single */\n.highlight .ss { color: #19177C } /* Literal.String.Symbol */\n.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */\n.highlight .fm { color: #0000FF } /* Name.Function.Magic */\n.highlight .vc { color: #19177C } /* Name.Variable.Class */\n.highlight .vg { color: #19177C } /* Name.Variable.Global */\n.highlight .vi { color: #19177C } /* Name.Variable.Instance */\n.highlight .vm { color: #19177C } /* Name.Variable.Magic */\n.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */"
  },
  {
    "path": "docs/_static/searchtools.js",
    "content": "/*\n * searchtools.js\n * ~~~~~~~~~~~~~~~~\n *\n * Sphinx JavaScript utilities for the full-text search.\n *\n * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.\n * :license: BSD, see LICENSE for details.\n *\n */\n\nif (!Scorer) {\n  /**\n   * Simple result scoring code.\n   */\n  var Scorer = {\n    // Implement the following function to further tweak the score for each result\n    // The function takes a result array [filename, title, anchor, descr, score]\n    // and returns the new score.\n    /*\n    score: function(result) {\n      return result[4];\n    },\n    */\n\n    // query matches the full name of an object\n    objNameMatch: 11,\n    // or matches in the last dotted part of the object name\n    objPartialMatch: 6,\n    // Additive scores depending on the priority of the object\n    objPrio: {0:  15,   // used to be importantResults\n              1:  5,   // used to be objectResults\n              2: -5},  // used to be unimportantResults\n    //  Used when the priority is not in the mapping.\n    objPrioDefault: 0,\n\n    // query found in title\n    title: 15,\n    partialTitle: 7,\n    // query found in terms\n    term: 5,\n    partialTerm: 2\n  };\n}\n\nif (!splitQuery) {\n  function splitQuery(query) {\n    return query.split(/\\s+/);\n  }\n}\n\n/**\n * Search Module\n */\nvar Search = {\n\n  _index : null,\n  _queued_query : null,\n  _pulse_status : -1,\n\n  htmlToText : function(htmlString) {\n      var virtualDocument = document.implementation.createHTMLDocument('virtual');\n      var htmlElement = $(htmlString, virtualDocument);\n      htmlElement.find('.headerlink').remove();\n      docContent = htmlElement.find('[role=main]')[0];\n      if(docContent === undefined) {\n          console.warn(\"Content block not found. Sphinx search tries to obtain it \" +\n                       \"via '[role=main]'. Could you check your theme or template.\");\n          return \"\";\n      }\n      return docContent.textContent || docContent.innerText;\n  },\n\n  init : function() {\n      var params = $.getQueryParameters();\n      if (params.q) {\n          var query = params.q[0];\n          $('input[name=\"q\"]')[0].value = query;\n          this.performSearch(query);\n      }\n  },\n\n  loadIndex : function(url) {\n    $.ajax({type: \"GET\", url: url, data: null,\n            dataType: \"script\", cache: true,\n            complete: function(jqxhr, textstatus) {\n              if (textstatus != \"success\") {\n                document.getElementById(\"searchindexloader\").src = url;\n              }\n            }});\n  },\n\n  setIndex : function(index) {\n    var q;\n    this._index = index;\n    if ((q = this._queued_query) !== null) {\n      this._queued_query = null;\n      Search.query(q);\n    }\n  },\n\n  hasIndex : function() {\n      return this._index !== null;\n  },\n\n  deferQuery : function(query) {\n      this._queued_query = query;\n  },\n\n  stopPulse : function() {\n      this._pulse_status = 0;\n  },\n\n  startPulse : function() {\n    if (this._pulse_status >= 0)\n        return;\n    function pulse() {\n      var i;\n      Search._pulse_status = (Search._pulse_status + 1) % 4;\n      var dotString = '';\n      for (i = 0; i < Search._pulse_status; i++)\n        dotString += '.';\n      Search.dots.text(dotString);\n      if (Search._pulse_status > -1)\n        window.setTimeout(pulse, 500);\n    }\n    pulse();\n  },\n\n  /**\n   * perform a search for something (or wait until index is loaded)\n   */\n  performSearch : function(query) {\n    // create the required interface elements\n    this.out = $('#search-results');\n    this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);\n    this.dots = $('<span></span>').appendTo(this.title);\n    this.status = $('<p class=\"search-summary\">&nbsp;</p>').appendTo(this.out);\n    this.output = $('<ul class=\"search\"/>').appendTo(this.out);\n\n    $('#search-progress').text(_('Preparing search...'));\n    this.startPulse();\n\n    // index already loaded, the browser was quick!\n    if (this.hasIndex())\n      this.query(query);\n    else\n      this.deferQuery(query);\n  },\n\n  /**\n   * execute search (requires search index to be loaded)\n   */\n  query : function(query) {\n    var i;\n\n    // stem the searchterms and add them to the correct list\n    var stemmer = new Stemmer();\n    var searchterms = [];\n    var excluded = [];\n    var hlterms = [];\n    var tmp = splitQuery(query);\n    var objectterms = [];\n    for (i = 0; i < tmp.length; i++) {\n      if (tmp[i] !== \"\") {\n          objectterms.push(tmp[i].toLowerCase());\n      }\n\n      if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i] === \"\") {\n        // skip this \"word\"\n        continue;\n      }\n      // stem the word\n      var word = stemmer.stemWord(tmp[i].toLowerCase());\n      // prevent stemmer from cutting word smaller than two chars\n      if(word.length < 3 && tmp[i].length >= 3) {\n        word = tmp[i];\n      }\n      var toAppend;\n      // select the correct list\n      if (word[0] == '-') {\n        toAppend = excluded;\n        word = word.substr(1);\n      }\n      else {\n        toAppend = searchterms;\n        hlterms.push(tmp[i].toLowerCase());\n      }\n      // only add if not already in the list\n      if (!$u.contains(toAppend, word))\n        toAppend.push(word);\n    }\n    var highlightstring = '?highlight=' + $.urlencode(hlterms.join(\" \"));\n\n    // console.debug('SEARCH: searching for:');\n    // console.info('required: ', searchterms);\n    // console.info('excluded: ', excluded);\n\n    // prepare search\n    var terms = this._index.terms;\n    var titleterms = this._index.titleterms;\n\n    // array of [filename, title, anchor, descr, score]\n    var results = [];\n    $('#search-progress').empty();\n\n    // lookup as object\n    for (i = 0; i < objectterms.length; i++) {\n      var others = [].concat(objectterms.slice(0, i),\n                             objectterms.slice(i+1, objectterms.length));\n      results = results.concat(this.performObjectSearch(objectterms[i], others));\n    }\n\n    // lookup as search terms in fulltext\n    results = results.concat(this.performTermsSearch(searchterms, excluded, terms, titleterms));\n\n    // let the scorer override scores with a custom scoring function\n    if (Scorer.score) {\n      for (i = 0; i < results.length; i++)\n        results[i][4] = Scorer.score(results[i]);\n    }\n\n    // now sort the results by score (in opposite order of appearance, since the\n    // display function below uses pop() to retrieve items) and then\n    // alphabetically\n    results.sort(function(a, b) {\n      var left = a[4];\n      var right = b[4];\n      if (left > right) {\n        return 1;\n      } else if (left < right) {\n        return -1;\n      } else {\n        // same score: sort alphabetically\n        left = a[1].toLowerCase();\n        right = b[1].toLowerCase();\n        return (left > right) ? -1 : ((left < right) ? 1 : 0);\n      }\n    });\n\n    // for debugging\n    //Search.lastresults = results.slice();  // a copy\n    //console.info('search results:', Search.lastresults);\n\n    // print the results\n    var resultCount = results.length;\n    function displayNextItem() {\n      // results left, load the summary and display it\n      if (results.length) {\n        var item = results.pop();\n        var listItem = $('<li></li>');\n        var requestUrl = \"\";\n        var linkUrl = \"\";\n        if (DOCUMENTATION_OPTIONS.BUILDER === 'dirhtml') {\n          // dirhtml builder\n          var dirname = item[0] + '/';\n          if (dirname.match(/\\/index\\/$/)) {\n            dirname = dirname.substring(0, dirname.length-6);\n          } else if (dirname == 'index/') {\n            dirname = '';\n          }\n          requestUrl = DOCUMENTATION_OPTIONS.URL_ROOT + dirname;\n          linkUrl = requestUrl;\n\n        } else {\n          // normal html builders\n          requestUrl = DOCUMENTATION_OPTIONS.URL_ROOT + item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX;\n          linkUrl = item[0] + DOCUMENTATION_OPTIONS.LINK_SUFFIX;\n        }\n        listItem.append($('<a/>').attr('href',\n            linkUrl +\n            highlightstring + item[2]).html(item[1]));\n        if (item[3]) {\n          listItem.append($('<span> (' + item[3] + ')</span>'));\n          Search.output.append(listItem);\n          setTimeout(function() {\n            displayNextItem();\n          }, 5);\n        } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {\n          $.ajax({url: requestUrl,\n                  dataType: \"text\",\n                  complete: function(jqxhr, textstatus) {\n                    var data = jqxhr.responseText;\n                    if (data !== '' && data !== undefined) {\n                      listItem.append(Search.makeSearchSummary(data, searchterms, hlterms));\n                    }\n                    Search.output.append(listItem);\n                    setTimeout(function() {\n                      displayNextItem();\n                    }, 5);\n                  }});\n        } else {\n          // no source available, just display title\n          Search.output.append(listItem);\n          setTimeout(function() {\n            displayNextItem();\n          }, 5);\n        }\n      }\n      // search finished, update title and status message\n      else {\n        Search.stopPulse();\n        Search.title.text(_('Search Results'));\n        if (!resultCount)\n          Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\\'ve selected enough categories.'));\n        else\n            Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));\n        Search.status.fadeIn(500);\n      }\n    }\n    displayNextItem();\n  },\n\n  /**\n   * search for object names\n   */\n  performObjectSearch : function(object, otherterms) {\n    var filenames = this._index.filenames;\n    var docnames = this._index.docnames;\n    var objects = this._index.objects;\n    var objnames = this._index.objnames;\n    var titles = this._index.titles;\n\n    var i;\n    var results = [];\n\n    for (var prefix in objects) {\n      for (var name in objects[prefix]) {\n        var fullname = (prefix ? prefix + '.' : '') + name;\n        var fullnameLower = fullname.toLowerCase()\n        if (fullnameLower.indexOf(object) > -1) {\n          var score = 0;\n          var parts = fullnameLower.split('.');\n          // check for different match types: exact matches of full name or\n          // \"last name\" (i.e. last dotted part)\n          if (fullnameLower == object || parts[parts.length - 1] == object) {\n            score += Scorer.objNameMatch;\n          // matches in last name\n          } else if (parts[parts.length - 1].indexOf(object) > -1) {\n            score += Scorer.objPartialMatch;\n          }\n          var match = objects[prefix][name];\n          var objname = objnames[match[1]][2];\n          var title = titles[match[0]];\n          // If more than one term searched for, we require other words to be\n          // found in the name/title/description\n          if (otherterms.length > 0) {\n            var haystack = (prefix + ' ' + name + ' ' +\n                            objname + ' ' + title).toLowerCase();\n            var allfound = true;\n            for (i = 0; i < otherterms.length; i++) {\n              if (haystack.indexOf(otherterms[i]) == -1) {\n                allfound = false;\n                break;\n              }\n            }\n            if (!allfound) {\n              continue;\n            }\n          }\n          var descr = objname + _(', in ') + title;\n\n          var anchor = match[3];\n          if (anchor === '')\n            anchor = fullname;\n          else if (anchor == '-')\n            anchor = objnames[match[1]][1] + '-' + fullname;\n          // add custom score for some objects according to scorer\n          if (Scorer.objPrio.hasOwnProperty(match[2])) {\n            score += Scorer.objPrio[match[2]];\n          } else {\n            score += Scorer.objPrioDefault;\n          }\n          results.push([docnames[match[0]], fullname, '#'+anchor, descr, score, filenames[match[0]]]);\n        }\n      }\n    }\n\n    return results;\n  },\n\n  /**\n   * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions\n   */\n  escapeRegExp : function(string) {\n    return string.replace(/[.*+\\-?^${}()|[\\]\\\\]/g, '\\\\$&'); // $& means the whole matched string\n  },\n\n  /**\n   * search for full-text terms in the index\n   */\n  performTermsSearch : function(searchterms, excluded, terms, titleterms) {\n    var docnames = this._index.docnames;\n    var filenames = this._index.filenames;\n    var titles = this._index.titles;\n\n    var i, j, file;\n    var fileMap = {};\n    var scoreMap = {};\n    var results = [];\n\n    // perform the search on the required terms\n    for (i = 0; i < searchterms.length; i++) {\n      var word = searchterms[i];\n      var files = [];\n      var _o = [\n        {files: terms[word], score: Scorer.term},\n        {files: titleterms[word], score: Scorer.title}\n      ];\n      // add support for partial matches\n      if (word.length > 2) {\n        var word_regex = this.escapeRegExp(word);\n        for (var w in terms) {\n          if (w.match(word_regex) && !terms[word]) {\n            _o.push({files: terms[w], score: Scorer.partialTerm})\n          }\n        }\n        for (var w in titleterms) {\n          if (w.match(word_regex) && !titleterms[word]) {\n              _o.push({files: titleterms[w], score: Scorer.partialTitle})\n          }\n        }\n      }\n\n      // no match but word was a required one\n      if ($u.every(_o, function(o){return o.files === undefined;})) {\n        break;\n      }\n      // found search word in contents\n      $u.each(_o, function(o) {\n        var _files = o.files;\n        if (_files === undefined)\n          return\n\n        if (_files.length === undefined)\n          _files = [_files];\n        files = files.concat(_files);\n\n        // set score for the word in each file to Scorer.term\n        for (j = 0; j < _files.length; j++) {\n          file = _files[j];\n          if (!(file in scoreMap))\n            scoreMap[file] = {};\n          scoreMap[file][word] = o.score;\n        }\n      });\n\n      // create the mapping\n      for (j = 0; j < files.length; j++) {\n        file = files[j];\n        if (file in fileMap && fileMap[file].indexOf(word) === -1)\n          fileMap[file].push(word);\n        else\n          fileMap[file] = [word];\n      }\n    }\n\n    // now check if the files don't contain excluded terms\n    for (file in fileMap) {\n      var valid = true;\n\n      // check if all requirements are matched\n      var filteredTermCount = // as search terms with length < 3 are discarded: ignore\n        searchterms.filter(function(term){return term.length > 2}).length\n      if (\n        fileMap[file].length != searchterms.length &&\n        fileMap[file].length != filteredTermCount\n      ) continue;\n\n      // ensure that none of the excluded terms is in the search result\n      for (i = 0; i < excluded.length; i++) {\n        if (terms[excluded[i]] == file ||\n            titleterms[excluded[i]] == file ||\n            $u.contains(terms[excluded[i]] || [], file) ||\n            $u.contains(titleterms[excluded[i]] || [], file)) {\n          valid = false;\n          break;\n        }\n      }\n\n      // if we have still a valid result we can add it to the result list\n      if (valid) {\n        // select one (max) score for the file.\n        // for better ranking, we should calculate ranking by using words statistics like basic tf-idf...\n        var score = $u.max($u.map(fileMap[file], function(w){return scoreMap[file][w]}));\n        results.push([docnames[file], titles[file], '', null, score, filenames[file]]);\n      }\n    }\n    return results;\n  },\n\n  /**\n   * helper function to return a node containing the\n   * search summary for a given text. keywords is a list\n   * of stemmed words, hlwords is the list of normal, unstemmed\n   * words. the first one is used to find the occurrence, the\n   * latter for highlighting it.\n   */\n  makeSearchSummary : function(htmlText, keywords, hlwords) {\n    var text = Search.htmlToText(htmlText);\n    var textLower = text.toLowerCase();\n    var start = 0;\n    $.each(keywords, function() {\n      var i = textLower.indexOf(this.toLowerCase());\n      if (i > -1)\n        start = i;\n    });\n    start = Math.max(start - 120, 0);\n    var excerpt = ((start > 0) ? '...' : '') +\n      $.trim(text.substr(start, 240)) +\n      ((start + 240 - text.length) ? '...' : '');\n    var rv = $('<p class=\"context\"></p>').text(excerpt);\n    $.each(hlwords, function() {\n      rv = rv.highlightText(this, 'highlighted');\n    });\n    return rv;\n  }\n};\n\n$(document).ready(function() {\n  Search.init();\n});\n"
  },
  {
    "path": "docs/_static/underscore-1.12.0.js",
    "content": "(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n  typeof define === 'function' && define.amd ? define('underscore', factory) :\n  (global = global || self, (function () {\n    var current = global._;\n    var exports = global._ = factory();\n    exports.noConflict = function () { global._ = current; return exports; };\n  }()));\n}(this, (function () {\n  //     Underscore.js 1.12.0\n  //     https://underscorejs.org\n  //     (c) 2009-2020 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n  //     Underscore may be freely distributed under the MIT license.\n\n  // Current version.\n  var VERSION = '1.12.0';\n\n  // Establish the root object, `window` (`self`) in the browser, `global`\n  // on the server, or `this` in some virtual machines. We use `self`\n  // instead of `window` for `WebWorker` support.\n  var root = typeof self == 'object' && self.self === self && self ||\n            typeof global == 'object' && global.global === global && global ||\n            Function('return this')() ||\n            {};\n\n  // Save bytes in the minified (but not gzipped) version:\n  var ArrayProto = Array.prototype, ObjProto = Object.prototype;\n  var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null;\n\n  // Create quick reference variables for speed access to core prototypes.\n  var push = ArrayProto.push,\n      slice = ArrayProto.slice,\n      toString = ObjProto.toString,\n      hasOwnProperty = ObjProto.hasOwnProperty;\n\n  // Modern feature detection.\n  var supportsArrayBuffer = typeof ArrayBuffer !== 'undefined',\n      supportsDataView = typeof DataView !== 'undefined';\n\n  // All **ECMAScript 5+** native function implementations that we hope to use\n  // are declared here.\n  var nativeIsArray = Array.isArray,\n      nativeKeys = Object.keys,\n      nativeCreate = Object.create,\n      nativeIsView = supportsArrayBuffer && ArrayBuffer.isView;\n\n  // Create references to these builtin functions because we override them.\n  var _isNaN = isNaN,\n      _isFinite = isFinite;\n\n  // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.\n  var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');\n  var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',\n    'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];\n\n  // The largest integer that can be represented exactly.\n  var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;\n\n  // Some functions take a variable number of arguments, or a few expected\n  // arguments at the beginning and then a variable number of values to operate\n  // on. This helper accumulates all remaining arguments past the function’s\n  // argument length (or an explicit `startIndex`), into an array that becomes\n  // the last argument. Similar to ES6’s \"rest parameter\".\n  function restArguments(func, startIndex) {\n    startIndex = startIndex == null ? func.length - 1 : +startIndex;\n    return function() {\n      var length = Math.max(arguments.length - startIndex, 0),\n          rest = Array(length),\n          index = 0;\n      for (; index < length; index++) {\n        rest[index] = arguments[index + startIndex];\n      }\n      switch (startIndex) {\n        case 0: return func.call(this, rest);\n        case 1: return func.call(this, arguments[0], rest);\n        case 2: return func.call(this, arguments[0], arguments[1], rest);\n      }\n      var args = Array(startIndex + 1);\n      for (index = 0; index < startIndex; index++) {\n        args[index] = arguments[index];\n      }\n      args[startIndex] = rest;\n      return func.apply(this, args);\n    };\n  }\n\n  // Is a given variable an object?\n  function isObject(obj) {\n    var type = typeof obj;\n    return type === 'function' || type === 'object' && !!obj;\n  }\n\n  // Is a given value equal to null?\n  function isNull(obj) {\n    return obj === null;\n  }\n\n  // Is a given variable undefined?\n  function isUndefined(obj) {\n    return obj === void 0;\n  }\n\n  // Is a given value a boolean?\n  function isBoolean(obj) {\n    return obj === true || obj === false || toString.call(obj) === '[object Boolean]';\n  }\n\n  // Is a given value a DOM element?\n  function isElement(obj) {\n    return !!(obj && obj.nodeType === 1);\n  }\n\n  // Internal function for creating a `toString`-based type tester.\n  function tagTester(name) {\n    var tag = '[object ' + name + ']';\n    return function(obj) {\n      return toString.call(obj) === tag;\n    };\n  }\n\n  var isString = tagTester('String');\n\n  var isNumber = tagTester('Number');\n\n  var isDate = tagTester('Date');\n\n  var isRegExp = tagTester('RegExp');\n\n  var isError = tagTester('Error');\n\n  var isSymbol = tagTester('Symbol');\n\n  var isArrayBuffer = tagTester('ArrayBuffer');\n\n  var isFunction = tagTester('Function');\n\n  // Optimize `isFunction` if appropriate. Work around some `typeof` bugs in old\n  // v8, IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236).\n  var nodelist = root.document && root.document.childNodes;\n  if (typeof /./ != 'function' && typeof Int8Array != 'object' && typeof nodelist != 'function') {\n    isFunction = function(obj) {\n      return typeof obj == 'function' || false;\n    };\n  }\n\n  var isFunction$1 = isFunction;\n\n  var hasObjectTag = tagTester('Object');\n\n  // In IE 10 - Edge 13, `DataView` has string tag `'[object Object]'`.\n  // In IE 11, the most common among them, this problem also applies to\n  // `Map`, `WeakMap` and `Set`.\n  var hasStringTagBug = (\n        supportsDataView && hasObjectTag(new DataView(new ArrayBuffer(8)))\n      ),\n      isIE11 = (typeof Map !== 'undefined' && hasObjectTag(new Map));\n\n  var isDataView = tagTester('DataView');\n\n  // In IE 10 - Edge 13, we need a different heuristic\n  // to determine whether an object is a `DataView`.\n  function ie10IsDataView(obj) {\n    return obj != null && isFunction$1(obj.getInt8) && isArrayBuffer(obj.buffer);\n  }\n\n  var isDataView$1 = (hasStringTagBug ? ie10IsDataView : isDataView);\n\n  // Is a given value an array?\n  // Delegates to ECMA5's native `Array.isArray`.\n  var isArray = nativeIsArray || tagTester('Array');\n\n  // Internal function to check whether `key` is an own property name of `obj`.\n  function has(obj, key) {\n    return obj != null && hasOwnProperty.call(obj, key);\n  }\n\n  var isArguments = tagTester('Arguments');\n\n  // Define a fallback version of the method in browsers (ahem, IE < 9), where\n  // there isn't any inspectable \"Arguments\" type.\n  (function() {\n    if (!isArguments(arguments)) {\n      isArguments = function(obj) {\n        return has(obj, 'callee');\n      };\n    }\n  }());\n\n  var isArguments$1 = isArguments;\n\n  // Is a given object a finite number?\n  function isFinite$1(obj) {\n    return !isSymbol(obj) && _isFinite(obj) && !isNaN(parseFloat(obj));\n  }\n\n  // Is the given value `NaN`?\n  function isNaN$1(obj) {\n    return isNumber(obj) && _isNaN(obj);\n  }\n\n  // Predicate-generating function. Often useful outside of Underscore.\n  function constant(value) {\n    return function() {\n      return value;\n    };\n  }\n\n  // Common internal logic for `isArrayLike` and `isBufferLike`.\n  function createSizePropertyCheck(getSizeProperty) {\n    return function(collection) {\n      var sizeProperty = getSizeProperty(collection);\n      return typeof sizeProperty == 'number' && sizeProperty >= 0 && sizeProperty <= MAX_ARRAY_INDEX;\n    }\n  }\n\n  // Internal helper to generate a function to obtain property `key` from `obj`.\n  function shallowProperty(key) {\n    return function(obj) {\n      return obj == null ? void 0 : obj[key];\n    };\n  }\n\n  // Internal helper to obtain the `byteLength` property of an object.\n  var getByteLength = shallowProperty('byteLength');\n\n  // Internal helper to determine whether we should spend extensive checks against\n  // `ArrayBuffer` et al.\n  var isBufferLike = createSizePropertyCheck(getByteLength);\n\n  // Is a given value a typed array?\n  var typedArrayPattern = /\\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\\]/;\n  function isTypedArray(obj) {\n    // `ArrayBuffer.isView` is the most future-proof, so use it when available.\n    // Otherwise, fall back on the above regular expression.\n    return nativeIsView ? (nativeIsView(obj) && !isDataView$1(obj)) :\n                  isBufferLike(obj) && typedArrayPattern.test(toString.call(obj));\n  }\n\n  var isTypedArray$1 = supportsArrayBuffer ? isTypedArray : constant(false);\n\n  // Internal helper to obtain the `length` property of an object.\n  var getLength = shallowProperty('length');\n\n  // Internal helper to create a simple lookup structure.\n  // `collectNonEnumProps` used to depend on `_.contains`, but this led to\n  // circular imports. `emulatedSet` is a one-off solution that only works for\n  // arrays of strings.\n  function emulatedSet(keys) {\n    var hash = {};\n    for (var l = keys.length, i = 0; i < l; ++i) hash[keys[i]] = true;\n    return {\n      contains: function(key) { return hash[key]; },\n      push: function(key) {\n        hash[key] = true;\n        return keys.push(key);\n      }\n    };\n  }\n\n  // Internal helper. Checks `keys` for the presence of keys in IE < 9 that won't\n  // be iterated by `for key in ...` and thus missed. Extends `keys` in place if\n  // needed.\n  function collectNonEnumProps(obj, keys) {\n    keys = emulatedSet(keys);\n    var nonEnumIdx = nonEnumerableProps.length;\n    var constructor = obj.constructor;\n    var proto = isFunction$1(constructor) && constructor.prototype || ObjProto;\n\n    // Constructor is a special case.\n    var prop = 'constructor';\n    if (has(obj, prop) && !keys.contains(prop)) keys.push(prop);\n\n    while (nonEnumIdx--) {\n      prop = nonEnumerableProps[nonEnumIdx];\n      if (prop in obj && obj[prop] !== proto[prop] && !keys.contains(prop)) {\n        keys.push(prop);\n      }\n    }\n  }\n\n  // Retrieve the names of an object's own properties.\n  // Delegates to **ECMAScript 5**'s native `Object.keys`.\n  function keys(obj) {\n    if (!isObject(obj)) return [];\n    if (nativeKeys) return nativeKeys(obj);\n    var keys = [];\n    for (var key in obj) if (has(obj, key)) keys.push(key);\n    // Ahem, IE < 9.\n    if (hasEnumBug) collectNonEnumProps(obj, keys);\n    return keys;\n  }\n\n  // Is a given array, string, or object empty?\n  // An \"empty\" object has no enumerable own-properties.\n  function isEmpty(obj) {\n    if (obj == null) return true;\n    // Skip the more expensive `toString`-based type checks if `obj` has no\n    // `.length`.\n    var length = getLength(obj);\n    if (typeof length == 'number' && (\n      isArray(obj) || isString(obj) || isArguments$1(obj)\n    )) return length === 0;\n    return getLength(keys(obj)) === 0;\n  }\n\n  // Returns whether an object has a given set of `key:value` pairs.\n  function isMatch(object, attrs) {\n    var _keys = keys(attrs), length = _keys.length;\n    if (object == null) return !length;\n    var obj = Object(object);\n    for (var i = 0; i < length; i++) {\n      var key = _keys[i];\n      if (attrs[key] !== obj[key] || !(key in obj)) return false;\n    }\n    return true;\n  }\n\n  // If Underscore is called as a function, it returns a wrapped object that can\n  // be used OO-style. This wrapper holds altered versions of all functions added\n  // through `_.mixin`. Wrapped objects may be chained.\n  function _(obj) {\n    if (obj instanceof _) return obj;\n    if (!(this instanceof _)) return new _(obj);\n    this._wrapped = obj;\n  }\n\n  _.VERSION = VERSION;\n\n  // Extracts the result from a wrapped and chained object.\n  _.prototype.value = function() {\n    return this._wrapped;\n  };\n\n  // Provide unwrapping proxies for some methods used in engine operations\n  // such as arithmetic and JSON stringification.\n  _.prototype.valueOf = _.prototype.toJSON = _.prototype.value;\n\n  _.prototype.toString = function() {\n    return String(this._wrapped);\n  };\n\n  // Internal function to wrap or shallow-copy an ArrayBuffer,\n  // typed array or DataView to a new view, reusing the buffer.\n  function toBufferView(bufferSource) {\n    return new Uint8Array(\n      bufferSource.buffer || bufferSource,\n      bufferSource.byteOffset || 0,\n      getByteLength(bufferSource)\n    );\n  }\n\n  // We use this string twice, so give it a name for minification.\n  var tagDataView = '[object DataView]';\n\n  // Internal recursive comparison function for `_.isEqual`.\n  function eq(a, b, aStack, bStack) {\n    // Identical objects are equal. `0 === -0`, but they aren't identical.\n    // See the [Harmony `egal` proposal](https://wiki.ecmascript.org/doku.php?id=harmony:egal).\n    if (a === b) return a !== 0 || 1 / a === 1 / b;\n    // `null` or `undefined` only equal to itself (strict comparison).\n    if (a == null || b == null) return false;\n    // `NaN`s are equivalent, but non-reflexive.\n    if (a !== a) return b !== b;\n    // Exhaust primitive checks\n    var type = typeof a;\n    if (type !== 'function' && type !== 'object' && typeof b != 'object') return false;\n    return deepEq(a, b, aStack, bStack);\n  }\n\n  // Internal recursive comparison function for `_.isEqual`.\n  function deepEq(a, b, aStack, bStack) {\n    // Unwrap any wrapped objects.\n    if (a instanceof _) a = a._wrapped;\n    if (b instanceof _) b = b._wrapped;\n    // Compare `[[Class]]` names.\n    var className = toString.call(a);\n    if (className !== toString.call(b)) return false;\n    // Work around a bug in IE 10 - Edge 13.\n    if (hasStringTagBug && className == '[object Object]' && isDataView$1(a)) {\n      if (!isDataView$1(b)) return false;\n      className = tagDataView;\n    }\n    switch (className) {\n      // These types are compared by value.\n      case '[object RegExp]':\n        // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')\n      case '[object String]':\n        // Primitives and their corresponding object wrappers are equivalent; thus, `\"5\"` is\n        // equivalent to `new String(\"5\")`.\n        return '' + a === '' + b;\n      case '[object Number]':\n        // `NaN`s are equivalent, but non-reflexive.\n        // Object(NaN) is equivalent to NaN.\n        if (+a !== +a) return +b !== +b;\n        // An `egal` comparison is performed for other numeric values.\n        return +a === 0 ? 1 / +a === 1 / b : +a === +b;\n      case '[object Date]':\n      case '[object Boolean]':\n        // Coerce dates and booleans to numeric primitive values. Dates are compared by their\n        // millisecond representations. Note that invalid dates with millisecond representations\n        // of `NaN` are not equivalent.\n        return +a === +b;\n      case '[object Symbol]':\n        return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b);\n      case '[object ArrayBuffer]':\n      case tagDataView:\n        // Coerce to typed array so we can fall through.\n        return deepEq(toBufferView(a), toBufferView(b), aStack, bStack);\n    }\n\n    var areArrays = className === '[object Array]';\n    if (!areArrays && isTypedArray$1(a)) {\n        var byteLength = getByteLength(a);\n        if (byteLength !== getByteLength(b)) return false;\n        if (a.buffer === b.buffer && a.byteOffset === b.byteOffset) return true;\n        areArrays = true;\n    }\n    if (!areArrays) {\n      if (typeof a != 'object' || typeof b != 'object') return false;\n\n      // Objects with different constructors are not equivalent, but `Object`s or `Array`s\n      // from different frames are.\n      var aCtor = a.constructor, bCtor = b.constructor;\n      if (aCtor !== bCtor && !(isFunction$1(aCtor) && aCtor instanceof aCtor &&\n                               isFunction$1(bCtor) && bCtor instanceof bCtor)\n                          && ('constructor' in a && 'constructor' in b)) {\n        return false;\n      }\n    }\n    // Assume equality for cyclic structures. The algorithm for detecting cyclic\n    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.\n\n    // Initializing stack of traversed objects.\n    // It's done here since we only need them for objects and arrays comparison.\n    aStack = aStack || [];\n    bStack = bStack || [];\n    var length = aStack.length;\n    while (length--) {\n      // Linear search. Performance is inversely proportional to the number of\n      // unique nested structures.\n      if (aStack[length] === a) return bStack[length] === b;\n    }\n\n    // Add the first object to the stack of traversed objects.\n    aStack.push(a);\n    bStack.push(b);\n\n    // Recursively compare objects and arrays.\n    if (areArrays) {\n      // Compare array lengths to determine if a deep comparison is necessary.\n      length = a.length;\n      if (length !== b.length) return false;\n      // Deep compare the contents, ignoring non-numeric properties.\n      while (length--) {\n        if (!eq(a[length], b[length], aStack, bStack)) return false;\n      }\n    } else {\n      // Deep compare objects.\n      var _keys = keys(a), key;\n      length = _keys.length;\n      // Ensure that both objects contain the same number of properties before comparing deep equality.\n      if (keys(b).length !== length) return false;\n      while (length--) {\n        // Deep compare each member\n        key = _keys[length];\n        if (!(has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;\n      }\n    }\n    // Remove the first object from the stack of traversed objects.\n    aStack.pop();\n    bStack.pop();\n    return true;\n  }\n\n  // Perform a deep comparison to check if two objects are equal.\n  function isEqual(a, b) {\n    return eq(a, b);\n  }\n\n  // Retrieve all the enumerable property names of an object.\n  function allKeys(obj) {\n    if (!isObject(obj)) return [];\n    var keys = [];\n    for (var key in obj) keys.push(key);\n    // Ahem, IE < 9.\n    if (hasEnumBug) collectNonEnumProps(obj, keys);\n    return keys;\n  }\n\n  // Since the regular `Object.prototype.toString` type tests don't work for\n  // some types in IE 11, we use a fingerprinting heuristic instead, based\n  // on the methods. It's not great, but it's the best we got.\n  // The fingerprint method lists are defined below.\n  function ie11fingerprint(methods) {\n    var length = getLength(methods);\n    return function(obj) {\n      if (obj == null) return false;\n      // `Map`, `WeakMap` and `Set` have no enumerable keys.\n      var keys = allKeys(obj);\n      if (getLength(keys)) return false;\n      for (var i = 0; i < length; i++) {\n        if (!isFunction$1(obj[methods[i]])) return false;\n      }\n      // If we are testing against `WeakMap`, we need to ensure that\n      // `obj` doesn't have a `forEach` method in order to distinguish\n      // it from a regular `Map`.\n      return methods !== weakMapMethods || !isFunction$1(obj[forEachName]);\n    };\n  }\n\n  // In the interest of compact minification, we write\n  // each string in the fingerprints only once.\n  var forEachName = 'forEach',\n      hasName = 'has',\n      commonInit = ['clear', 'delete'],\n      mapTail = ['get', hasName, 'set'];\n\n  // `Map`, `WeakMap` and `Set` each have slightly different\n  // combinations of the above sublists.\n  var mapMethods = commonInit.concat(forEachName, mapTail),\n      weakMapMethods = commonInit.concat(mapTail),\n      setMethods = ['add'].concat(commonInit, forEachName, hasName);\n\n  var isMap = isIE11 ? ie11fingerprint(mapMethods) : tagTester('Map');\n\n  var isWeakMap = isIE11 ? ie11fingerprint(weakMapMethods) : tagTester('WeakMap');\n\n  var isSet = isIE11 ? ie11fingerprint(setMethods) : tagTester('Set');\n\n  var isWeakSet = tagTester('WeakSet');\n\n  // Retrieve the values of an object's properties.\n  function values(obj) {\n    var _keys = keys(obj);\n    var length = _keys.length;\n    var values = Array(length);\n    for (var i = 0; i < length; i++) {\n      values[i] = obj[_keys[i]];\n    }\n    return values;\n  }\n\n  // Convert an object into a list of `[key, value]` pairs.\n  // The opposite of `_.object` with one argument.\n  function pairs(obj) {\n    var _keys = keys(obj);\n    var length = _keys.length;\n    var pairs = Array(length);\n    for (var i = 0; i < length; i++) {\n      pairs[i] = [_keys[i], obj[_keys[i]]];\n    }\n    return pairs;\n  }\n\n  // Invert the keys and values of an object. The values must be serializable.\n  function invert(obj) {\n    var result = {};\n    var _keys = keys(obj);\n    for (var i = 0, length = _keys.length; i < length; i++) {\n      result[obj[_keys[i]]] = _keys[i];\n    }\n    return result;\n  }\n\n  // Return a sorted list of the function names available on the object.\n  function functions(obj) {\n    var names = [];\n    for (var key in obj) {\n      if (isFunction$1(obj[key])) names.push(key);\n    }\n    return names.sort();\n  }\n\n  // An internal function for creating assigner functions.\n  function createAssigner(keysFunc, defaults) {\n    return function(obj) {\n      var length = arguments.length;\n      if (defaults) obj = Object(obj);\n      if (length < 2 || obj == null) return obj;\n      for (var index = 1; index < length; index++) {\n        var source = arguments[index],\n            keys = keysFunc(source),\n            l = keys.length;\n        for (var i = 0; i < l; i++) {\n          var key = keys[i];\n          if (!defaults || obj[key] === void 0) obj[key] = source[key];\n        }\n      }\n      return obj;\n    };\n  }\n\n  // Extend a given object with all the properties in passed-in object(s).\n  var extend = createAssigner(allKeys);\n\n  // Assigns a given object with all the own properties in the passed-in\n  // object(s).\n  // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)\n  var extendOwn = createAssigner(keys);\n\n  // Fill in a given object with default properties.\n  var defaults = createAssigner(allKeys, true);\n\n  // Create a naked function reference for surrogate-prototype-swapping.\n  function ctor() {\n    return function(){};\n  }\n\n  // An internal function for creating a new object that inherits from another.\n  function baseCreate(prototype) {\n    if (!isObject(prototype)) return {};\n    if (nativeCreate) return nativeCreate(prototype);\n    var Ctor = ctor();\n    Ctor.prototype = prototype;\n    var result = new Ctor;\n    Ctor.prototype = null;\n    return result;\n  }\n\n  // Creates an object that inherits from the given prototype object.\n  // If additional properties are provided then they will be added to the\n  // created object.\n  function create(prototype, props) {\n    var result = baseCreate(prototype);\n    if (props) extendOwn(result, props);\n    return result;\n  }\n\n  // Create a (shallow-cloned) duplicate of an object.\n  function clone(obj) {\n    if (!isObject(obj)) return obj;\n    return isArray(obj) ? obj.slice() : extend({}, obj);\n  }\n\n  // Invokes `interceptor` with the `obj` and then returns `obj`.\n  // The primary purpose of this method is to \"tap into\" a method chain, in\n  // order to perform operations on intermediate results within the chain.\n  function tap(obj, interceptor) {\n    interceptor(obj);\n    return obj;\n  }\n\n  // Normalize a (deep) property `path` to array.\n  // Like `_.iteratee`, this function can be customized.\n  function toPath(path) {\n    return isArray(path) ? path : [path];\n  }\n  _.toPath = toPath;\n\n  // Internal wrapper for `_.toPath` to enable minification.\n  // Similar to `cb` for `_.iteratee`.\n  function toPath$1(path) {\n    return _.toPath(path);\n  }\n\n  // Internal function to obtain a nested property in `obj` along `path`.\n  function deepGet(obj, path) {\n    var length = path.length;\n    for (var i = 0; i < length; i++) {\n      if (obj == null) return void 0;\n      obj = obj[path[i]];\n    }\n    return length ? obj : void 0;\n  }\n\n  // Get the value of the (deep) property on `path` from `object`.\n  // If any property in `path` does not exist or if the value is\n  // `undefined`, return `defaultValue` instead.\n  // The `path` is normalized through `_.toPath`.\n  function get(object, path, defaultValue) {\n    var value = deepGet(object, toPath$1(path));\n    return isUndefined(value) ? defaultValue : value;\n  }\n\n  // Shortcut function for checking if an object has a given property directly on\n  // itself (in other words, not on a prototype). Unlike the internal `has`\n  // function, this public version can also traverse nested properties.\n  function has$1(obj, path) {\n    path = toPath$1(path);\n    var length = path.length;\n    for (var i = 0; i < length; i++) {\n      var key = path[i];\n      if (!has(obj, key)) return false;\n      obj = obj[key];\n    }\n    return !!length;\n  }\n\n  // Keep the identity function around for default iteratees.\n  function identity(value) {\n    return value;\n  }\n\n  // Returns a predicate for checking whether an object has a given set of\n  // `key:value` pairs.\n  function matcher(attrs) {\n    attrs = extendOwn({}, attrs);\n    return function(obj) {\n      return isMatch(obj, attrs);\n    };\n  }\n\n  // Creates a function that, when passed an object, will traverse that object’s\n  // properties down the given `path`, specified as an array of keys or indices.\n  function property(path) {\n    path = toPath$1(path);\n    return function(obj) {\n      return deepGet(obj, path);\n    };\n  }\n\n  // Internal function that returns an efficient (for current engines) version\n  // of the passed-in callback, to be repeatedly applied in other Underscore\n  // functions.\n  function optimizeCb(func, context, argCount) {\n    if (context === void 0) return func;\n    switch (argCount == null ? 3 : argCount) {\n      case 1: return function(value) {\n        return func.call(context, value);\n      };\n      // The 2-argument case is omitted because we’re not using it.\n      case 3: return function(value, index, collection) {\n        return func.call(context, value, index, collection);\n      };\n      case 4: return function(accumulator, value, index, collection) {\n        return func.call(context, accumulator, value, index, collection);\n      };\n    }\n    return function() {\n      return func.apply(context, arguments);\n    };\n  }\n\n  // An internal function to generate callbacks that can be applied to each\n  // element in a collection, returning the desired result — either `_.identity`,\n  // an arbitrary callback, a property matcher, or a property accessor.\n  function baseIteratee(value, context, argCount) {\n    if (value == null) return identity;\n    if (isFunction$1(value)) return optimizeCb(value, context, argCount);\n    if (isObject(value) && !isArray(value)) return matcher(value);\n    return property(value);\n  }\n\n  // External wrapper for our callback generator. Users may customize\n  // `_.iteratee` if they want additional predicate/iteratee shorthand styles.\n  // This abstraction hides the internal-only `argCount` argument.\n  function iteratee(value, context) {\n    return baseIteratee(value, context, Infinity);\n  }\n  _.iteratee = iteratee;\n\n  // The function we call internally to generate a callback. It invokes\n  // `_.iteratee` if overridden, otherwise `baseIteratee`.\n  function cb(value, context, argCount) {\n    if (_.iteratee !== iteratee) return _.iteratee(value, context);\n    return baseIteratee(value, context, argCount);\n  }\n\n  // Returns the results of applying the `iteratee` to each element of `obj`.\n  // In contrast to `_.map` it returns an object.\n  function mapObject(obj, iteratee, context) {\n    iteratee = cb(iteratee, context);\n    var _keys = keys(obj),\n        length = _keys.length,\n        results = {};\n    for (var index = 0; index < length; index++) {\n      var currentKey = _keys[index];\n      results[currentKey] = iteratee(obj[currentKey], currentKey, obj);\n    }\n    return results;\n  }\n\n  // Predicate-generating function. Often useful outside of Underscore.\n  function noop(){}\n\n  // Generates a function for a given object that returns a given property.\n  function propertyOf(obj) {\n    if (obj == null) return noop;\n    return function(path) {\n      return get(obj, path);\n    };\n  }\n\n  // Run a function **n** times.\n  function times(n, iteratee, context) {\n    var accum = Array(Math.max(0, n));\n    iteratee = optimizeCb(iteratee, context, 1);\n    for (var i = 0; i < n; i++) accum[i] = iteratee(i);\n    return accum;\n  }\n\n  // Return a random integer between `min` and `max` (inclusive).\n  function random(min, max) {\n    if (max == null) {\n      max = min;\n      min = 0;\n    }\n    return min + Math.floor(Math.random() * (max - min + 1));\n  }\n\n  // A (possibly faster) way to get the current timestamp as an integer.\n  var now = Date.now || function() {\n    return new Date().getTime();\n  };\n\n  // Internal helper to generate functions for escaping and unescaping strings\n  // to/from HTML interpolation.\n  function createEscaper(map) {\n    var escaper = function(match) {\n      return map[match];\n    };\n    // Regexes for identifying a key that needs to be escaped.\n    var source = '(?:' + keys(map).join('|') + ')';\n    var testRegexp = RegExp(source);\n    var replaceRegexp = RegExp(source, 'g');\n    return function(string) {\n      string = string == null ? '' : '' + string;\n      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;\n    };\n  }\n\n  // Internal list of HTML entities for escaping.\n  var escapeMap = {\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#x27;',\n    '`': '&#x60;'\n  };\n\n  // Function for escaping strings to HTML interpolation.\n  var _escape = createEscaper(escapeMap);\n\n  // Internal list of HTML entities for unescaping.\n  var unescapeMap = invert(escapeMap);\n\n  // Function for unescaping strings from HTML interpolation.\n  var _unescape = createEscaper(unescapeMap);\n\n  // By default, Underscore uses ERB-style template delimiters. Change the\n  // following template settings to use alternative delimiters.\n  var templateSettings = _.templateSettings = {\n    evaluate: /<%([\\s\\S]+?)%>/g,\n    interpolate: /<%=([\\s\\S]+?)%>/g,\n    escape: /<%-([\\s\\S]+?)%>/g\n  };\n\n  // When customizing `_.templateSettings`, if you don't want to define an\n  // interpolation, evaluation or escaping regex, we need one that is\n  // guaranteed not to match.\n  var noMatch = /(.)^/;\n\n  // Certain characters need to be escaped so that they can be put into a\n  // string literal.\n  var escapes = {\n    \"'\": \"'\",\n    '\\\\': '\\\\',\n    '\\r': 'r',\n    '\\n': 'n',\n    '\\u2028': 'u2028',\n    '\\u2029': 'u2029'\n  };\n\n  var escapeRegExp = /\\\\|'|\\r|\\n|\\u2028|\\u2029/g;\n\n  function escapeChar(match) {\n    return '\\\\' + escapes[match];\n  }\n\n  // JavaScript micro-templating, similar to John Resig's implementation.\n  // Underscore templating handles arbitrary delimiters, preserves whitespace,\n  // and correctly escapes quotes within interpolated code.\n  // NB: `oldSettings` only exists for backwards compatibility.\n  function template(text, settings, oldSettings) {\n    if (!settings && oldSettings) settings = oldSettings;\n    settings = defaults({}, settings, _.templateSettings);\n\n    // Combine delimiters into one regular expression via alternation.\n    var matcher = RegExp([\n      (settings.escape || noMatch).source,\n      (settings.interpolate || noMatch).source,\n      (settings.evaluate || noMatch).source\n    ].join('|') + '|$', 'g');\n\n    // Compile the template source, escaping string literals appropriately.\n    var index = 0;\n    var source = \"__p+='\";\n    text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {\n      source += text.slice(index, offset).replace(escapeRegExp, escapeChar);\n      index = offset + match.length;\n\n      if (escape) {\n        source += \"'+\\n((__t=(\" + escape + \"))==null?'':_.escape(__t))+\\n'\";\n      } else if (interpolate) {\n        source += \"'+\\n((__t=(\" + interpolate + \"))==null?'':__t)+\\n'\";\n      } else if (evaluate) {\n        source += \"';\\n\" + evaluate + \"\\n__p+='\";\n      }\n\n      // Adobe VMs need the match returned to produce the correct offset.\n      return match;\n    });\n    source += \"';\\n\";\n\n    // If a variable is not specified, place data values in local scope.\n    if (!settings.variable) source = 'with(obj||{}){\\n' + source + '}\\n';\n\n    source = \"var __t,__p='',__j=Array.prototype.join,\" +\n      \"print=function(){__p+=__j.call(arguments,'');};\\n\" +\n      source + 'return __p;\\n';\n\n    var render;\n    try {\n      render = new Function(settings.variable || 'obj', '_', source);\n    } catch (e) {\n      e.source = source;\n      throw e;\n    }\n\n    var template = function(data) {\n      return render.call(this, data, _);\n    };\n\n    // Provide the compiled source as a convenience for precompilation.\n    var argument = settings.variable || 'obj';\n    template.source = 'function(' + argument + '){\\n' + source + '}';\n\n    return template;\n  }\n\n  // Traverses the children of `obj` along `path`. If a child is a function, it\n  // is invoked with its parent as context. Returns the value of the final\n  // child, or `fallback` if any child is undefined.\n  function result(obj, path, fallback) {\n    path = toPath$1(path);\n    var length = path.length;\n    if (!length) {\n      return isFunction$1(fallback) ? fallback.call(obj) : fallback;\n    }\n    for (var i = 0; i < length; i++) {\n      var prop = obj == null ? void 0 : obj[path[i]];\n      if (prop === void 0) {\n        prop = fallback;\n        i = length; // Ensure we don't continue iterating.\n      }\n      obj = isFunction$1(prop) ? prop.call(obj) : prop;\n    }\n    return obj;\n  }\n\n  // Generate a unique integer id (unique within the entire client session).\n  // Useful for temporary DOM ids.\n  var idCounter = 0;\n  function uniqueId(prefix) {\n    var id = ++idCounter + '';\n    return prefix ? prefix + id : id;\n  }\n\n  // Start chaining a wrapped Underscore object.\n  function chain(obj) {\n    var instance = _(obj);\n    instance._chain = true;\n    return instance;\n  }\n\n  // Internal function to execute `sourceFunc` bound to `context` with optional\n  // `args`. Determines whether to execute a function as a constructor or as a\n  // normal function.\n  function executeBound(sourceFunc, boundFunc, context, callingContext, args) {\n    if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);\n    var self = baseCreate(sourceFunc.prototype);\n    var result = sourceFunc.apply(self, args);\n    if (isObject(result)) return result;\n    return self;\n  }\n\n  // Partially apply a function by creating a version that has had some of its\n  // arguments pre-filled, without changing its dynamic `this` context. `_` acts\n  // as a placeholder by default, allowing any combination of arguments to be\n  // pre-filled. Set `_.partial.placeholder` for a custom placeholder argument.\n  var partial = restArguments(function(func, boundArgs) {\n    var placeholder = partial.placeholder;\n    var bound = function() {\n      var position = 0, length = boundArgs.length;\n      var args = Array(length);\n      for (var i = 0; i < length; i++) {\n        args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i];\n      }\n      while (position < arguments.length) args.push(arguments[position++]);\n      return executeBound(func, bound, this, this, args);\n    };\n    return bound;\n  });\n\n  partial.placeholder = _;\n\n  // Create a function bound to a given object (assigning `this`, and arguments,\n  // optionally).\n  var bind = restArguments(function(func, context, args) {\n    if (!isFunction$1(func)) throw new TypeError('Bind must be called on a function');\n    var bound = restArguments(function(callArgs) {\n      return executeBound(func, bound, context, this, args.concat(callArgs));\n    });\n    return bound;\n  });\n\n  // Internal helper for collection methods to determine whether a collection\n  // should be iterated as an array or as an object.\n  // Related: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength\n  // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094\n  var isArrayLike = createSizePropertyCheck(getLength);\n\n  // Internal implementation of a recursive `flatten` function.\n  function flatten(input, depth, strict, output) {\n    output = output || [];\n    if (!depth && depth !== 0) {\n      depth = Infinity;\n    } else if (depth <= 0) {\n      return output.concat(input);\n    }\n    var idx = output.length;\n    for (var i = 0, length = getLength(input); i < length; i++) {\n      var value = input[i];\n      if (isArrayLike(value) && (isArray(value) || isArguments$1(value))) {\n        // Flatten current level of array or arguments object.\n        if (depth > 1) {\n          flatten(value, depth - 1, strict, output);\n          idx = output.length;\n        } else {\n          var j = 0, len = value.length;\n          while (j < len) output[idx++] = value[j++];\n        }\n      } else if (!strict) {\n        output[idx++] = value;\n      }\n    }\n    return output;\n  }\n\n  // Bind a number of an object's methods to that object. Remaining arguments\n  // are the method names to be bound. Useful for ensuring that all callbacks\n  // defined on an object belong to it.\n  var bindAll = restArguments(function(obj, keys) {\n    keys = flatten(keys, false, false);\n    var index = keys.length;\n    if (index < 1) throw new Error('bindAll must be passed function names');\n    while (index--) {\n      var key = keys[index];\n      obj[key] = bind(obj[key], obj);\n    }\n    return obj;\n  });\n\n  // Memoize an expensive function by storing its results.\n  function memoize(func, hasher) {\n    var memoize = function(key) {\n      var cache = memoize.cache;\n      var address = '' + (hasher ? hasher.apply(this, arguments) : key);\n      if (!has(cache, address)) cache[address] = func.apply(this, arguments);\n      return cache[address];\n    };\n    memoize.cache = {};\n    return memoize;\n  }\n\n  // Delays a function for the given number of milliseconds, and then calls\n  // it with the arguments supplied.\n  var delay = restArguments(function(func, wait, args) {\n    return setTimeout(function() {\n      return func.apply(null, args);\n    }, wait);\n  });\n\n  // Defers a function, scheduling it to run after the current call stack has\n  // cleared.\n  var defer = partial(delay, _, 1);\n\n  // Returns a function, that, when invoked, will only be triggered at most once\n  // during a given window of time. Normally, the throttled function will run\n  // as much as it can, without ever going more than once per `wait` duration;\n  // but if you'd like to disable the execution on the leading edge, pass\n  // `{leading: false}`. To disable execution on the trailing edge, ditto.\n  function throttle(func, wait, options) {\n    var timeout, context, args, result;\n    var previous = 0;\n    if (!options) options = {};\n\n    var later = function() {\n      previous = options.leading === false ? 0 : now();\n      timeout = null;\n      result = func.apply(context, args);\n      if (!timeout) context = args = null;\n    };\n\n    var throttled = function() {\n      var _now = now();\n      if (!previous && options.leading === false) previous = _now;\n      var remaining = wait - (_now - previous);\n      context = this;\n      args = arguments;\n      if (remaining <= 0 || remaining > wait) {\n        if (timeout) {\n          clearTimeout(timeout);\n          timeout = null;\n        }\n        previous = _now;\n        result = func.apply(context, args);\n        if (!timeout) context = args = null;\n      } else if (!timeout && options.trailing !== false) {\n        timeout = setTimeout(later, remaining);\n      }\n      return result;\n    };\n\n    throttled.cancel = function() {\n      clearTimeout(timeout);\n      previous = 0;\n      timeout = context = args = null;\n    };\n\n    return throttled;\n  }\n\n  // When a sequence of calls of the returned function ends, the argument\n  // function is triggered. The end of a sequence is defined by the `wait`\n  // parameter. If `immediate` is passed, the argument function will be\n  // triggered at the beginning of the sequence instead of at the end.\n  function debounce(func, wait, immediate) {\n    var timeout, previous, args, result, context;\n\n    var later = function() {\n      var passed = now() - previous;\n      if (wait > passed) {\n        timeout = setTimeout(later, wait - passed);\n      } else {\n        timeout = null;\n        if (!immediate) result = func.apply(context, args);\n        // This check is needed because `func` can recursively invoke `debounced`.\n        if (!timeout) args = context = null;\n      }\n    };\n\n    var debounced = restArguments(function(_args) {\n      context = this;\n      args = _args;\n      previous = now();\n      if (!timeout) {\n        timeout = setTimeout(later, wait);\n        if (immediate) result = func.apply(context, args);\n      }\n      return result;\n    });\n\n    debounced.cancel = function() {\n      clearTimeout(timeout);\n      timeout = args = context = null;\n    };\n\n    return debounced;\n  }\n\n  // Returns the first function passed as an argument to the second,\n  // allowing you to adjust arguments, run code before and after, and\n  // conditionally execute the original function.\n  function wrap(func, wrapper) {\n    return partial(wrapper, func);\n  }\n\n  // Returns a negated version of the passed-in predicate.\n  function negate(predicate) {\n    return function() {\n      return !predicate.apply(this, arguments);\n    };\n  }\n\n  // Returns a function that is the composition of a list of functions, each\n  // consuming the return value of the function that follows.\n  function compose() {\n    var args = arguments;\n    var start = args.length - 1;\n    return function() {\n      var i = start;\n      var result = args[start].apply(this, arguments);\n      while (i--) result = args[i].call(this, result);\n      return result;\n    };\n  }\n\n  // Returns a function that will only be executed on and after the Nth call.\n  function after(times, func) {\n    return function() {\n      if (--times < 1) {\n        return func.apply(this, arguments);\n      }\n    };\n  }\n\n  // Returns a function that will only be executed up to (but not including) the\n  // Nth call.\n  function before(times, func) {\n    var memo;\n    return function() {\n      if (--times > 0) {\n        memo = func.apply(this, arguments);\n      }\n      if (times <= 1) func = null;\n      return memo;\n    };\n  }\n\n  // Returns a function that will be executed at most one time, no matter how\n  // often you call it. Useful for lazy initialization.\n  var once = partial(before, 2);\n\n  // Returns the first key on an object that passes a truth test.\n  function findKey(obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var _keys = keys(obj), key;\n    for (var i = 0, length = _keys.length; i < length; i++) {\n      key = _keys[i];\n      if (predicate(obj[key], key, obj)) return key;\n    }\n  }\n\n  // Internal function to generate `_.findIndex` and `_.findLastIndex`.\n  function createPredicateIndexFinder(dir) {\n    return function(array, predicate, context) {\n      predicate = cb(predicate, context);\n      var length = getLength(array);\n      var index = dir > 0 ? 0 : length - 1;\n      for (; index >= 0 && index < length; index += dir) {\n        if (predicate(array[index], index, array)) return index;\n      }\n      return -1;\n    };\n  }\n\n  // Returns the first index on an array-like that passes a truth test.\n  var findIndex = createPredicateIndexFinder(1);\n\n  // Returns the last index on an array-like that passes a truth test.\n  var findLastIndex = createPredicateIndexFinder(-1);\n\n  // Use a comparator function to figure out the smallest index at which\n  // an object should be inserted so as to maintain order. Uses binary search.\n  function sortedIndex(array, obj, iteratee, context) {\n    iteratee = cb(iteratee, context, 1);\n    var value = iteratee(obj);\n    var low = 0, high = getLength(array);\n    while (low < high) {\n      var mid = Math.floor((low + high) / 2);\n      if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;\n    }\n    return low;\n  }\n\n  // Internal function to generate the `_.indexOf` and `_.lastIndexOf` functions.\n  function createIndexFinder(dir, predicateFind, sortedIndex) {\n    return function(array, item, idx) {\n      var i = 0, length = getLength(array);\n      if (typeof idx == 'number') {\n        if (dir > 0) {\n          i = idx >= 0 ? idx : Math.max(idx + length, i);\n        } else {\n          length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;\n        }\n      } else if (sortedIndex && idx && length) {\n        idx = sortedIndex(array, item);\n        return array[idx] === item ? idx : -1;\n      }\n      if (item !== item) {\n        idx = predicateFind(slice.call(array, i, length), isNaN$1);\n        return idx >= 0 ? idx + i : -1;\n      }\n      for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {\n        if (array[idx] === item) return idx;\n      }\n      return -1;\n    };\n  }\n\n  // Return the position of the first occurrence of an item in an array,\n  // or -1 if the item is not included in the array.\n  // If the array is large and already in sort order, pass `true`\n  // for **isSorted** to use binary search.\n  var indexOf = createIndexFinder(1, findIndex, sortedIndex);\n\n  // Return the position of the last occurrence of an item in an array,\n  // or -1 if the item is not included in the array.\n  var lastIndexOf = createIndexFinder(-1, findLastIndex);\n\n  // Return the first value which passes a truth test.\n  function find(obj, predicate, context) {\n    var keyFinder = isArrayLike(obj) ? findIndex : findKey;\n    var key = keyFinder(obj, predicate, context);\n    if (key !== void 0 && key !== -1) return obj[key];\n  }\n\n  // Convenience version of a common use case of `_.find`: getting the first\n  // object containing specific `key:value` pairs.\n  function findWhere(obj, attrs) {\n    return find(obj, matcher(attrs));\n  }\n\n  // The cornerstone for collection functions, an `each`\n  // implementation, aka `forEach`.\n  // Handles raw objects in addition to array-likes. Treats all\n  // sparse array-likes as if they were dense.\n  function each(obj, iteratee, context) {\n    iteratee = optimizeCb(iteratee, context);\n    var i, length;\n    if (isArrayLike(obj)) {\n      for (i = 0, length = obj.length; i < length; i++) {\n        iteratee(obj[i], i, obj);\n      }\n    } else {\n      var _keys = keys(obj);\n      for (i = 0, length = _keys.length; i < length; i++) {\n        iteratee(obj[_keys[i]], _keys[i], obj);\n      }\n    }\n    return obj;\n  }\n\n  // Return the results of applying the iteratee to each element.\n  function map(obj, iteratee, context) {\n    iteratee = cb(iteratee, context);\n    var _keys = !isArrayLike(obj) && keys(obj),\n        length = (_keys || obj).length,\n        results = Array(length);\n    for (var index = 0; index < length; index++) {\n      var currentKey = _keys ? _keys[index] : index;\n      results[index] = iteratee(obj[currentKey], currentKey, obj);\n    }\n    return results;\n  }\n\n  // Internal helper to create a reducing function, iterating left or right.\n  function createReduce(dir) {\n    // Wrap code that reassigns argument variables in a separate function than\n    // the one that accesses `arguments.length` to avoid a perf hit. (#1991)\n    var reducer = function(obj, iteratee, memo, initial) {\n      var _keys = !isArrayLike(obj) && keys(obj),\n          length = (_keys || obj).length,\n          index = dir > 0 ? 0 : length - 1;\n      if (!initial) {\n        memo = obj[_keys ? _keys[index] : index];\n        index += dir;\n      }\n      for (; index >= 0 && index < length; index += dir) {\n        var currentKey = _keys ? _keys[index] : index;\n        memo = iteratee(memo, obj[currentKey], currentKey, obj);\n      }\n      return memo;\n    };\n\n    return function(obj, iteratee, memo, context) {\n      var initial = arguments.length >= 3;\n      return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial);\n    };\n  }\n\n  // **Reduce** builds up a single result from a list of values, aka `inject`,\n  // or `foldl`.\n  var reduce = createReduce(1);\n\n  // The right-associative version of reduce, also known as `foldr`.\n  var reduceRight = createReduce(-1);\n\n  // Return all the elements that pass a truth test.\n  function filter(obj, predicate, context) {\n    var results = [];\n    predicate = cb(predicate, context);\n    each(obj, function(value, index, list) {\n      if (predicate(value, index, list)) results.push(value);\n    });\n    return results;\n  }\n\n  // Return all the elements for which a truth test fails.\n  function reject(obj, predicate, context) {\n    return filter(obj, negate(cb(predicate)), context);\n  }\n\n  // Determine whether all of the elements pass a truth test.\n  function every(obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var _keys = !isArrayLike(obj) && keys(obj),\n        length = (_keys || obj).length;\n    for (var index = 0; index < length; index++) {\n      var currentKey = _keys ? _keys[index] : index;\n      if (!predicate(obj[currentKey], currentKey, obj)) return false;\n    }\n    return true;\n  }\n\n  // Determine if at least one element in the object passes a truth test.\n  function some(obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var _keys = !isArrayLike(obj) && keys(obj),\n        length = (_keys || obj).length;\n    for (var index = 0; index < length; index++) {\n      var currentKey = _keys ? _keys[index] : index;\n      if (predicate(obj[currentKey], currentKey, obj)) return true;\n    }\n    return false;\n  }\n\n  // Determine if the array or object contains a given item (using `===`).\n  function contains(obj, item, fromIndex, guard) {\n    if (!isArrayLike(obj)) obj = values(obj);\n    if (typeof fromIndex != 'number' || guard) fromIndex = 0;\n    return indexOf(obj, item, fromIndex) >= 0;\n  }\n\n  // Invoke a method (with arguments) on every item in a collection.\n  var invoke = restArguments(function(obj, path, args) {\n    var contextPath, func;\n    if (isFunction$1(path)) {\n      func = path;\n    } else {\n      path = toPath$1(path);\n      contextPath = path.slice(0, -1);\n      path = path[path.length - 1];\n    }\n    return map(obj, function(context) {\n      var method = func;\n      if (!method) {\n        if (contextPath && contextPath.length) {\n          context = deepGet(context, contextPath);\n        }\n        if (context == null) return void 0;\n        method = context[path];\n      }\n      return method == null ? method : method.apply(context, args);\n    });\n  });\n\n  // Convenience version of a common use case of `_.map`: fetching a property.\n  function pluck(obj, key) {\n    return map(obj, property(key));\n  }\n\n  // Convenience version of a common use case of `_.filter`: selecting only\n  // objects containing specific `key:value` pairs.\n  function where(obj, attrs) {\n    return filter(obj, matcher(attrs));\n  }\n\n  // Return the maximum element (or element-based computation).\n  function max(obj, iteratee, context) {\n    var result = -Infinity, lastComputed = -Infinity,\n        value, computed;\n    if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) {\n      obj = isArrayLike(obj) ? obj : values(obj);\n      for (var i = 0, length = obj.length; i < length; i++) {\n        value = obj[i];\n        if (value != null && value > result) {\n          result = value;\n        }\n      }\n    } else {\n      iteratee = cb(iteratee, context);\n      each(obj, function(v, index, list) {\n        computed = iteratee(v, index, list);\n        if (computed > lastComputed || computed === -Infinity && result === -Infinity) {\n          result = v;\n          lastComputed = computed;\n        }\n      });\n    }\n    return result;\n  }\n\n  // Return the minimum element (or element-based computation).\n  function min(obj, iteratee, context) {\n    var result = Infinity, lastComputed = Infinity,\n        value, computed;\n    if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) {\n      obj = isArrayLike(obj) ? obj : values(obj);\n      for (var i = 0, length = obj.length; i < length; i++) {\n        value = obj[i];\n        if (value != null && value < result) {\n          result = value;\n        }\n      }\n    } else {\n      iteratee = cb(iteratee, context);\n      each(obj, function(v, index, list) {\n        computed = iteratee(v, index, list);\n        if (computed < lastComputed || computed === Infinity && result === Infinity) {\n          result = v;\n          lastComputed = computed;\n        }\n      });\n    }\n    return result;\n  }\n\n  // Sample **n** random values from a collection using the modern version of the\n  // [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher–Yates_shuffle).\n  // If **n** is not specified, returns a single random element.\n  // The internal `guard` argument allows it to work with `_.map`.\n  function sample(obj, n, guard) {\n    if (n == null || guard) {\n      if (!isArrayLike(obj)) obj = values(obj);\n      return obj[random(obj.length - 1)];\n    }\n    var sample = isArrayLike(obj) ? clone(obj) : values(obj);\n    var length = getLength(sample);\n    n = Math.max(Math.min(n, length), 0);\n    var last = length - 1;\n    for (var index = 0; index < n; index++) {\n      var rand = random(index, last);\n      var temp = sample[index];\n      sample[index] = sample[rand];\n      sample[rand] = temp;\n    }\n    return sample.slice(0, n);\n  }\n\n  // Shuffle a collection.\n  function shuffle(obj) {\n    return sample(obj, Infinity);\n  }\n\n  // Sort the object's values by a criterion produced by an iteratee.\n  function sortBy(obj, iteratee, context) {\n    var index = 0;\n    iteratee = cb(iteratee, context);\n    return pluck(map(obj, function(value, key, list) {\n      return {\n        value: value,\n        index: index++,\n        criteria: iteratee(value, key, list)\n      };\n    }).sort(function(left, right) {\n      var a = left.criteria;\n      var b = right.criteria;\n      if (a !== b) {\n        if (a > b || a === void 0) return 1;\n        if (a < b || b === void 0) return -1;\n      }\n      return left.index - right.index;\n    }), 'value');\n  }\n\n  // An internal function used for aggregate \"group by\" operations.\n  function group(behavior, partition) {\n    return function(obj, iteratee, context) {\n      var result = partition ? [[], []] : {};\n      iteratee = cb(iteratee, context);\n      each(obj, function(value, index) {\n        var key = iteratee(value, index, obj);\n        behavior(result, value, key);\n      });\n      return result;\n    };\n  }\n\n  // Groups the object's values by a criterion. Pass either a string attribute\n  // to group by, or a function that returns the criterion.\n  var groupBy = group(function(result, value, key) {\n    if (has(result, key)) result[key].push(value); else result[key] = [value];\n  });\n\n  // Indexes the object's values by a criterion, similar to `_.groupBy`, but for\n  // when you know that your index values will be unique.\n  var indexBy = group(function(result, value, key) {\n    result[key] = value;\n  });\n\n  // Counts instances of an object that group by a certain criterion. Pass\n  // either a string attribute to count by, or a function that returns the\n  // criterion.\n  var countBy = group(function(result, value, key) {\n    if (has(result, key)) result[key]++; else result[key] = 1;\n  });\n\n  // Split a collection into two arrays: one whose elements all pass the given\n  // truth test, and one whose elements all do not pass the truth test.\n  var partition = group(function(result, value, pass) {\n    result[pass ? 0 : 1].push(value);\n  }, true);\n\n  // Safely create a real, live array from anything iterable.\n  var reStrSymbol = /[^\\ud800-\\udfff]|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\ud800-\\udfff]/g;\n  function toArray(obj) {\n    if (!obj) return [];\n    if (isArray(obj)) return slice.call(obj);\n    if (isString(obj)) {\n      // Keep surrogate pair characters together.\n      return obj.match(reStrSymbol);\n    }\n    if (isArrayLike(obj)) return map(obj, identity);\n    return values(obj);\n  }\n\n  // Return the number of elements in a collection.\n  function size(obj) {\n    if (obj == null) return 0;\n    return isArrayLike(obj) ? obj.length : keys(obj).length;\n  }\n\n  // Internal `_.pick` helper function to determine whether `key` is an enumerable\n  // property name of `obj`.\n  function keyInObj(value, key, obj) {\n    return key in obj;\n  }\n\n  // Return a copy of the object only containing the allowed properties.\n  var pick = restArguments(function(obj, keys) {\n    var result = {}, iteratee = keys[0];\n    if (obj == null) return result;\n    if (isFunction$1(iteratee)) {\n      if (keys.length > 1) iteratee = optimizeCb(iteratee, keys[1]);\n      keys = allKeys(obj);\n    } else {\n      iteratee = keyInObj;\n      keys = flatten(keys, false, false);\n      obj = Object(obj);\n    }\n    for (var i = 0, length = keys.length; i < length; i++) {\n      var key = keys[i];\n      var value = obj[key];\n      if (iteratee(value, key, obj)) result[key] = value;\n    }\n    return result;\n  });\n\n  // Return a copy of the object without the disallowed properties.\n  var omit = restArguments(function(obj, keys) {\n    var iteratee = keys[0], context;\n    if (isFunction$1(iteratee)) {\n      iteratee = negate(iteratee);\n      if (keys.length > 1) context = keys[1];\n    } else {\n      keys = map(flatten(keys, false, false), String);\n      iteratee = function(value, key) {\n        return !contains(keys, key);\n      };\n    }\n    return pick(obj, iteratee, context);\n  });\n\n  // Returns everything but the last entry of the array. Especially useful on\n  // the arguments object. Passing **n** will return all the values in\n  // the array, excluding the last N.\n  function initial(array, n, guard) {\n    return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));\n  }\n\n  // Get the first element of an array. Passing **n** will return the first N\n  // values in the array. The **guard** check allows it to work with `_.map`.\n  function first(array, n, guard) {\n    if (array == null || array.length < 1) return n == null || guard ? void 0 : [];\n    if (n == null || guard) return array[0];\n    return initial(array, array.length - n);\n  }\n\n  // Returns everything but the first entry of the `array`. Especially useful on\n  // the `arguments` object. Passing an **n** will return the rest N values in the\n  // `array`.\n  function rest(array, n, guard) {\n    return slice.call(array, n == null || guard ? 1 : n);\n  }\n\n  // Get the last element of an array. Passing **n** will return the last N\n  // values in the array.\n  function last(array, n, guard) {\n    if (array == null || array.length < 1) return n == null || guard ? void 0 : [];\n    if (n == null || guard) return array[array.length - 1];\n    return rest(array, Math.max(0, array.length - n));\n  }\n\n  // Trim out all falsy values from an array.\n  function compact(array) {\n    return filter(array, Boolean);\n  }\n\n  // Flatten out an array, either recursively (by default), or up to `depth`.\n  // Passing `true` or `false` as `depth` means `1` or `Infinity`, respectively.\n  function flatten$1(array, depth) {\n    return flatten(array, depth, false);\n  }\n\n  // Take the difference between one array and a number of other arrays.\n  // Only the elements present in just the first array will remain.\n  var difference = restArguments(function(array, rest) {\n    rest = flatten(rest, true, true);\n    return filter(array, function(value){\n      return !contains(rest, value);\n    });\n  });\n\n  // Return a version of the array that does not contain the specified value(s).\n  var without = restArguments(function(array, otherArrays) {\n    return difference(array, otherArrays);\n  });\n\n  // Produce a duplicate-free version of the array. If the array has already\n  // been sorted, you have the option of using a faster algorithm.\n  // The faster algorithm will not work with an iteratee if the iteratee\n  // is not a one-to-one function, so providing an iteratee will disable\n  // the faster algorithm.\n  function uniq(array, isSorted, iteratee, context) {\n    if (!isBoolean(isSorted)) {\n      context = iteratee;\n      iteratee = isSorted;\n      isSorted = false;\n    }\n    if (iteratee != null) iteratee = cb(iteratee, context);\n    var result = [];\n    var seen = [];\n    for (var i = 0, length = getLength(array); i < length; i++) {\n      var value = array[i],\n          computed = iteratee ? iteratee(value, i, array) : value;\n      if (isSorted && !iteratee) {\n        if (!i || seen !== computed) result.push(value);\n        seen = computed;\n      } else if (iteratee) {\n        if (!contains(seen, computed)) {\n          seen.push(computed);\n          result.push(value);\n        }\n      } else if (!contains(result, value)) {\n        result.push(value);\n      }\n    }\n    return result;\n  }\n\n  // Produce an array that contains the union: each distinct element from all of\n  // the passed-in arrays.\n  var union = restArguments(function(arrays) {\n    return uniq(flatten(arrays, true, true));\n  });\n\n  // Produce an array that contains every item shared between all the\n  // passed-in arrays.\n  function intersection(array) {\n    var result = [];\n    var argsLength = arguments.length;\n    for (var i = 0, length = getLength(array); i < length; i++) {\n      var item = array[i];\n      if (contains(result, item)) continue;\n      var j;\n      for (j = 1; j < argsLength; j++) {\n        if (!contains(arguments[j], item)) break;\n      }\n      if (j === argsLength) result.push(item);\n    }\n    return result;\n  }\n\n  // Complement of zip. Unzip accepts an array of arrays and groups\n  // each array's elements on shared indices.\n  function unzip(array) {\n    var length = array && max(array, getLength).length || 0;\n    var result = Array(length);\n\n    for (var index = 0; index < length; index++) {\n      result[index] = pluck(array, index);\n    }\n    return result;\n  }\n\n  // Zip together multiple lists into a single array -- elements that share\n  // an index go together.\n  var zip = restArguments(unzip);\n\n  // Converts lists into objects. Pass either a single array of `[key, value]`\n  // pairs, or two parallel arrays of the same length -- one of keys, and one of\n  // the corresponding values. Passing by pairs is the reverse of `_.pairs`.\n  function object(list, values) {\n    var result = {};\n    for (var i = 0, length = getLength(list); i < length; i++) {\n      if (values) {\n        result[list[i]] = values[i];\n      } else {\n        result[list[i][0]] = list[i][1];\n      }\n    }\n    return result;\n  }\n\n  // Generate an integer Array containing an arithmetic progression. A port of\n  // the native Python `range()` function. See\n  // [the Python documentation](https://docs.python.org/library/functions.html#range).\n  function range(start, stop, step) {\n    if (stop == null) {\n      stop = start || 0;\n      start = 0;\n    }\n    if (!step) {\n      step = stop < start ? -1 : 1;\n    }\n\n    var length = Math.max(Math.ceil((stop - start) / step), 0);\n    var range = Array(length);\n\n    for (var idx = 0; idx < length; idx++, start += step) {\n      range[idx] = start;\n    }\n\n    return range;\n  }\n\n  // Chunk a single array into multiple arrays, each containing `count` or fewer\n  // items.\n  function chunk(array, count) {\n    if (count == null || count < 1) return [];\n    var result = [];\n    var i = 0, length = array.length;\n    while (i < length) {\n      result.push(slice.call(array, i, i += count));\n    }\n    return result;\n  }\n\n  // Helper function to continue chaining intermediate results.\n  function chainResult(instance, obj) {\n    return instance._chain ? _(obj).chain() : obj;\n  }\n\n  // Add your own custom functions to the Underscore object.\n  function mixin(obj) {\n    each(functions(obj), function(name) {\n      var func = _[name] = obj[name];\n      _.prototype[name] = function() {\n        var args = [this._wrapped];\n        push.apply(args, arguments);\n        return chainResult(this, func.apply(_, args));\n      };\n    });\n    return _;\n  }\n\n  // Add all mutator `Array` functions to the wrapper.\n  each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {\n    var method = ArrayProto[name];\n    _.prototype[name] = function() {\n      var obj = this._wrapped;\n      if (obj != null) {\n        method.apply(obj, arguments);\n        if ((name === 'shift' || name === 'splice') && obj.length === 0) {\n          delete obj[0];\n        }\n      }\n      return chainResult(this, obj);\n    };\n  });\n\n  // Add all accessor `Array` functions to the wrapper.\n  each(['concat', 'join', 'slice'], function(name) {\n    var method = ArrayProto[name];\n    _.prototype[name] = function() {\n      var obj = this._wrapped;\n      if (obj != null) obj = method.apply(obj, arguments);\n      return chainResult(this, obj);\n    };\n  });\n\n  // Named Exports\n\n  var allExports = {\n    __proto__: null,\n    VERSION: VERSION,\n    restArguments: restArguments,\n    isObject: isObject,\n    isNull: isNull,\n    isUndefined: isUndefined,\n    isBoolean: isBoolean,\n    isElement: isElement,\n    isString: isString,\n    isNumber: isNumber,\n    isDate: isDate,\n    isRegExp: isRegExp,\n    isError: isError,\n    isSymbol: isSymbol,\n    isArrayBuffer: isArrayBuffer,\n    isDataView: isDataView$1,\n    isArray: isArray,\n    isFunction: isFunction$1,\n    isArguments: isArguments$1,\n    isFinite: isFinite$1,\n    isNaN: isNaN$1,\n    isTypedArray: isTypedArray$1,\n    isEmpty: isEmpty,\n    isMatch: isMatch,\n    isEqual: isEqual,\n    isMap: isMap,\n    isWeakMap: isWeakMap,\n    isSet: isSet,\n    isWeakSet: isWeakSet,\n    keys: keys,\n    allKeys: allKeys,\n    values: values,\n    pairs: pairs,\n    invert: invert,\n    functions: functions,\n    methods: functions,\n    extend: extend,\n    extendOwn: extendOwn,\n    assign: extendOwn,\n    defaults: defaults,\n    create: create,\n    clone: clone,\n    tap: tap,\n    get: get,\n    has: has$1,\n    mapObject: mapObject,\n    identity: identity,\n    constant: constant,\n    noop: noop,\n    toPath: toPath,\n    property: property,\n    propertyOf: propertyOf,\n    matcher: matcher,\n    matches: matcher,\n    times: times,\n    random: random,\n    now: now,\n    escape: _escape,\n    unescape: _unescape,\n    templateSettings: templateSettings,\n    template: template,\n    result: result,\n    uniqueId: uniqueId,\n    chain: chain,\n    iteratee: iteratee,\n    partial: partial,\n    bind: bind,\n    bindAll: bindAll,\n    memoize: memoize,\n    delay: delay,\n    defer: defer,\n    throttle: throttle,\n    debounce: debounce,\n    wrap: wrap,\n    negate: negate,\n    compose: compose,\n    after: after,\n    before: before,\n    once: once,\n    findKey: findKey,\n    findIndex: findIndex,\n    findLastIndex: findLastIndex,\n    sortedIndex: sortedIndex,\n    indexOf: indexOf,\n    lastIndexOf: lastIndexOf,\n    find: find,\n    detect: find,\n    findWhere: findWhere,\n    each: each,\n    forEach: each,\n    map: map,\n    collect: map,\n    reduce: reduce,\n    foldl: reduce,\n    inject: reduce,\n    reduceRight: reduceRight,\n    foldr: reduceRight,\n    filter: filter,\n    select: filter,\n    reject: reject,\n    every: every,\n    all: every,\n    some: some,\n    any: some,\n    contains: contains,\n    includes: contains,\n    include: contains,\n    invoke: invoke,\n    pluck: pluck,\n    where: where,\n    max: max,\n    min: min,\n    shuffle: shuffle,\n    sample: sample,\n    sortBy: sortBy,\n    groupBy: groupBy,\n    indexBy: indexBy,\n    countBy: countBy,\n    partition: partition,\n    toArray: toArray,\n    size: size,\n    pick: pick,\n    omit: omit,\n    first: first,\n    head: first,\n    take: first,\n    initial: initial,\n    last: last,\n    rest: rest,\n    tail: rest,\n    drop: rest,\n    compact: compact,\n    flatten: flatten$1,\n    without: without,\n    uniq: uniq,\n    unique: uniq,\n    union: union,\n    intersection: intersection,\n    difference: difference,\n    unzip: unzip,\n    transpose: unzip,\n    zip: zip,\n    object: object,\n    range: range,\n    chunk: chunk,\n    mixin: mixin,\n    'default': _\n  };\n\n  // Default Export\n\n  // Add all of the Underscore functions to the wrapper object.\n  var _$1 = mixin(allExports);\n  // Legacy Node.js API.\n  _$1._ = _$1;\n\n  return _$1;\n\n})));\n//# sourceMappingURL=underscore.js.map\n"
  },
  {
    "path": "docs/_static/underscore-1.3.1.js",
    "content": "//     Underscore.js 1.3.1\n//     (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.\n//     Underscore is freely distributable under the MIT license.\n//     Portions of Underscore are inspired or borrowed from Prototype,\n//     Oliver Steele's Functional, and John Resig's Micro-Templating.\n//     For all details and documentation:\n//     http://documentcloud.github.com/underscore\n\n(function() {\n\n  // Baseline setup\n  // --------------\n\n  // Establish the root object, `window` in the browser, or `global` on the server.\n  var root = this;\n\n  // Save the previous value of the `_` variable.\n  var previousUnderscore = root._;\n\n  // Establish the object that gets returned to break out of a loop iteration.\n  var breaker = {};\n\n  // Save bytes in the minified (but not gzipped) version:\n  var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;\n\n  // Create quick reference variables for speed access to core prototypes.\n  var slice            = ArrayProto.slice,\n      unshift          = ArrayProto.unshift,\n      toString         = ObjProto.toString,\n      hasOwnProperty   = ObjProto.hasOwnProperty;\n\n  // All **ECMAScript 5** native function implementations that we hope to use\n  // are declared here.\n  var\n    nativeForEach      = ArrayProto.forEach,\n    nativeMap          = ArrayProto.map,\n    nativeReduce       = ArrayProto.reduce,\n    nativeReduceRight  = ArrayProto.reduceRight,\n    nativeFilter       = ArrayProto.filter,\n    nativeEvery        = ArrayProto.every,\n    nativeSome         = ArrayProto.some,\n    nativeIndexOf      = ArrayProto.indexOf,\n    nativeLastIndexOf  = ArrayProto.lastIndexOf,\n    nativeIsArray      = Array.isArray,\n    nativeKeys         = Object.keys,\n    nativeBind         = FuncProto.bind;\n\n  // Create a safe reference to the Underscore object for use below.\n  var _ = function(obj) { return new wrapper(obj); };\n\n  // Export the Underscore object for **Node.js**, with\n  // backwards-compatibility for the old `require()` API. If we're in\n  // the browser, add `_` as a global object via a string identifier,\n  // for Closure Compiler \"advanced\" mode.\n  if (typeof exports !== 'undefined') {\n    if (typeof module !== 'undefined' && module.exports) {\n      exports = module.exports = _;\n    }\n    exports._ = _;\n  } else {\n    root['_'] = _;\n  }\n\n  // Current version.\n  _.VERSION = '1.3.1';\n\n  // Collection Functions\n  // --------------------\n\n  // The cornerstone, an `each` implementation, aka `forEach`.\n  // Handles objects with the built-in `forEach`, arrays, and raw objects.\n  // Delegates to **ECMAScript 5**'s native `forEach` if available.\n  var each = _.each = _.forEach = function(obj, iterator, context) {\n    if (obj == null) return;\n    if (nativeForEach && obj.forEach === nativeForEach) {\n      obj.forEach(iterator, context);\n    } else if (obj.length === +obj.length) {\n      for (var i = 0, l = obj.length; i < l; i++) {\n        if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;\n      }\n    } else {\n      for (var key in obj) {\n        if (_.has(obj, key)) {\n          if (iterator.call(context, obj[key], key, obj) === breaker) return;\n        }\n      }\n    }\n  };\n\n  // Return the results of applying the iterator to each element.\n  // Delegates to **ECMAScript 5**'s native `map` if available.\n  _.map = _.collect = function(obj, iterator, context) {\n    var results = [];\n    if (obj == null) return results;\n    if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);\n    each(obj, function(value, index, list) {\n      results[results.length] = iterator.call(context, value, index, list);\n    });\n    if (obj.length === +obj.length) results.length = obj.length;\n    return results;\n  };\n\n  // **Reduce** builds up a single result from a list of values, aka `inject`,\n  // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.\n  _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {\n    var initial = arguments.length > 2;\n    if (obj == null) obj = [];\n    if (nativeReduce && obj.reduce === nativeReduce) {\n      if (context) iterator = _.bind(iterator, context);\n      return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);\n    }\n    each(obj, function(value, index, list) {\n      if (!initial) {\n        memo = value;\n        initial = true;\n      } else {\n        memo = iterator.call(context, memo, value, index, list);\n      }\n    });\n    if (!initial) throw new TypeError('Reduce of empty array with no initial value');\n    return memo;\n  };\n\n  // The right-associative version of reduce, also known as `foldr`.\n  // Delegates to **ECMAScript 5**'s native `reduceRight` if available.\n  _.reduceRight = _.foldr = function(obj, iterator, memo, context) {\n    var initial = arguments.length > 2;\n    if (obj == null) obj = [];\n    if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {\n      if (context) iterator = _.bind(iterator, context);\n      return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);\n    }\n    var reversed = _.toArray(obj).reverse();\n    if (context && !initial) iterator = _.bind(iterator, context);\n    return initial ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator);\n  };\n\n  // Return the first value which passes a truth test. Aliased as `detect`.\n  _.find = _.detect = function(obj, iterator, context) {\n    var result;\n    any(obj, function(value, index, list) {\n      if (iterator.call(context, value, index, list)) {\n        result = value;\n        return true;\n      }\n    });\n    return result;\n  };\n\n  // Return all the elements that pass a truth test.\n  // Delegates to **ECMAScript 5**'s native `filter` if available.\n  // Aliased as `select`.\n  _.filter = _.select = function(obj, iterator, context) {\n    var results = [];\n    if (obj == null) return results;\n    if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);\n    each(obj, function(value, index, list) {\n      if (iterator.call(context, value, index, list)) results[results.length] = value;\n    });\n    return results;\n  };\n\n  // Return all the elements for which a truth test fails.\n  _.reject = function(obj, iterator, context) {\n    var results = [];\n    if (obj == null) return results;\n    each(obj, function(value, index, list) {\n      if (!iterator.call(context, value, index, list)) results[results.length] = value;\n    });\n    return results;\n  };\n\n  // Determine whether all of the elements match a truth test.\n  // Delegates to **ECMAScript 5**'s native `every` if available.\n  // Aliased as `all`.\n  _.every = _.all = function(obj, iterator, context) {\n    var result = true;\n    if (obj == null) return result;\n    if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);\n    each(obj, function(value, index, list) {\n      if (!(result = result && iterator.call(context, value, index, list))) return breaker;\n    });\n    return result;\n  };\n\n  // Determine if at least one element in the object matches a truth test.\n  // Delegates to **ECMAScript 5**'s native `some` if available.\n  // Aliased as `any`.\n  var any = _.some = _.any = function(obj, iterator, context) {\n    iterator || (iterator = _.identity);\n    var result = false;\n    if (obj == null) return result;\n    if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);\n    each(obj, function(value, index, list) {\n      if (result || (result = iterator.call(context, value, index, list))) return breaker;\n    });\n    return !!result;\n  };\n\n  // Determine if a given value is included in the array or object using `===`.\n  // Aliased as `contains`.\n  _.include = _.contains = function(obj, target) {\n    var found = false;\n    if (obj == null) return found;\n    if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;\n    found = any(obj, function(value) {\n      return value === target;\n    });\n    return found;\n  };\n\n  // Invoke a method (with arguments) on every item in a collection.\n  _.invoke = function(obj, method) {\n    var args = slice.call(arguments, 2);\n    return _.map(obj, function(value) {\n      return (_.isFunction(method) ? method || value : value[method]).apply(value, args);\n    });\n  };\n\n  // Convenience version of a common use case of `map`: fetching a property.\n  _.pluck = function(obj, key) {\n    return _.map(obj, function(value){ return value[key]; });\n  };\n\n  // Return the maximum element or (element-based computation).\n  _.max = function(obj, iterator, context) {\n    if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);\n    if (!iterator && _.isEmpty(obj)) return -Infinity;\n    var result = {computed : -Infinity};\n    each(obj, function(value, index, list) {\n      var computed = iterator ? iterator.call(context, value, index, list) : value;\n      computed >= result.computed && (result = {value : value, computed : computed});\n    });\n    return result.value;\n  };\n\n  // Return the minimum element (or element-based computation).\n  _.min = function(obj, iterator, context) {\n    if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);\n    if (!iterator && _.isEmpty(obj)) return Infinity;\n    var result = {computed : Infinity};\n    each(obj, function(value, index, list) {\n      var computed = iterator ? iterator.call(context, value, index, list) : value;\n      computed < result.computed && (result = {value : value, computed : computed});\n    });\n    return result.value;\n  };\n\n  // Shuffle an array.\n  _.shuffle = function(obj) {\n    var shuffled = [], rand;\n    each(obj, function(value, index, list) {\n      if (index == 0) {\n        shuffled[0] = value;\n      } else {\n        rand = Math.floor(Math.random() * (index + 1));\n        shuffled[index] = shuffled[rand];\n        shuffled[rand] = value;\n      }\n    });\n    return shuffled;\n  };\n\n  // Sort the object's values by a criterion produced by an iterator.\n  _.sortBy = function(obj, iterator, context) {\n    return _.pluck(_.map(obj, function(value, index, list) {\n      return {\n        value : value,\n        criteria : iterator.call(context, value, index, list)\n      };\n    }).sort(function(left, right) {\n      var a = left.criteria, b = right.criteria;\n      return a < b ? -1 : a > b ? 1 : 0;\n    }), 'value');\n  };\n\n  // Groups the object's values by a criterion. Pass either a string attribute\n  // to group by, or a function that returns the criterion.\n  _.groupBy = function(obj, val) {\n    var result = {};\n    var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };\n    each(obj, function(value, index) {\n      var key = iterator(value, index);\n      (result[key] || (result[key] = [])).push(value);\n    });\n    return result;\n  };\n\n  // Use a comparator function to figure out at what index an object should\n  // be inserted so as to maintain order. Uses binary search.\n  _.sortedIndex = function(array, obj, iterator) {\n    iterator || (iterator = _.identity);\n    var low = 0, high = array.length;\n    while (low < high) {\n      var mid = (low + high) >> 1;\n      iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;\n    }\n    return low;\n  };\n\n  // Safely convert anything iterable into a real, live array.\n  _.toArray = function(iterable) {\n    if (!iterable)                return [];\n    if (iterable.toArray)         return iterable.toArray();\n    if (_.isArray(iterable))      return slice.call(iterable);\n    if (_.isArguments(iterable))  return slice.call(iterable);\n    return _.values(iterable);\n  };\n\n  // Return the number of elements in an object.\n  _.size = function(obj) {\n    return _.toArray(obj).length;\n  };\n\n  // Array Functions\n  // ---------------\n\n  // Get the first element of an array. Passing **n** will return the first N\n  // values in the array. Aliased as `head`. The **guard** check allows it to work\n  // with `_.map`.\n  _.first = _.head = function(array, n, guard) {\n    return (n != null) && !guard ? slice.call(array, 0, n) : array[0];\n  };\n\n  // Returns everything but the last entry of the array. Especcialy useful on\n  // the arguments object. Passing **n** will return all the values in\n  // the array, excluding the last N. The **guard** check allows it to work with\n  // `_.map`.\n  _.initial = function(array, n, guard) {\n    return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));\n  };\n\n  // Get the last element of an array. Passing **n** will return the last N\n  // values in the array. The **guard** check allows it to work with `_.map`.\n  _.last = function(array, n, guard) {\n    if ((n != null) && !guard) {\n      return slice.call(array, Math.max(array.length - n, 0));\n    } else {\n      return array[array.length - 1];\n    }\n  };\n\n  // Returns everything but the first entry of the array. Aliased as `tail`.\n  // Especially useful on the arguments object. Passing an **index** will return\n  // the rest of the values in the array from that index onward. The **guard**\n  // check allows it to work with `_.map`.\n  _.rest = _.tail = function(array, index, guard) {\n    return slice.call(array, (index == null) || guard ? 1 : index);\n  };\n\n  // Trim out all falsy values from an array.\n  _.compact = function(array) {\n    return _.filter(array, function(value){ return !!value; });\n  };\n\n  // Return a completely flattened version of an array.\n  _.flatten = function(array, shallow) {\n    return _.reduce(array, function(memo, value) {\n      if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));\n      memo[memo.length] = value;\n      return memo;\n    }, []);\n  };\n\n  // Return a version of the array that does not contain the specified value(s).\n  _.without = function(array) {\n    return _.difference(array, slice.call(arguments, 1));\n  };\n\n  // Produce a duplicate-free version of the array. If the array has already\n  // been sorted, you have the option of using a faster algorithm.\n  // Aliased as `unique`.\n  _.uniq = _.unique = function(array, isSorted, iterator) {\n    var initial = iterator ? _.map(array, iterator) : array;\n    var result = [];\n    _.reduce(initial, function(memo, el, i) {\n      if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) {\n        memo[memo.length] = el;\n        result[result.length] = array[i];\n      }\n      return memo;\n    }, []);\n    return result;\n  };\n\n  // Produce an array that contains the union: each distinct element from all of\n  // the passed-in arrays.\n  _.union = function() {\n    return _.uniq(_.flatten(arguments, true));\n  };\n\n  // Produce an array that contains every item shared between all the\n  // passed-in arrays. (Aliased as \"intersect\" for back-compat.)\n  _.intersection = _.intersect = function(array) {\n    var rest = slice.call(arguments, 1);\n    return _.filter(_.uniq(array), function(item) {\n      return _.every(rest, function(other) {\n        return _.indexOf(other, item) >= 0;\n      });\n    });\n  };\n\n  // Take the difference between one array and a number of other arrays.\n  // Only the elements present in just the first array will remain.\n  _.difference = function(array) {\n    var rest = _.flatten(slice.call(arguments, 1));\n    return _.filter(array, function(value){ return !_.include(rest, value); });\n  };\n\n  // Zip together multiple lists into a single array -- elements that share\n  // an index go together.\n  _.zip = function() {\n    var args = slice.call(arguments);\n    var length = _.max(_.pluck(args, 'length'));\n    var results = new Array(length);\n    for (var i = 0; i < length; i++) results[i] = _.pluck(args, \"\" + i);\n    return results;\n  };\n\n  // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),\n  // we need this function. Return the position of the first occurrence of an\n  // item in an array, or -1 if the item is not included in the array.\n  // Delegates to **ECMAScript 5**'s native `indexOf` if available.\n  // If the array is large and already in sort order, pass `true`\n  // for **isSorted** to use binary search.\n  _.indexOf = function(array, item, isSorted) {\n    if (array == null) return -1;\n    var i, l;\n    if (isSorted) {\n      i = _.sortedIndex(array, item);\n      return array[i] === item ? i : -1;\n    }\n    if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);\n    for (i = 0, l = array.length; i < l; i++) if (i in array && array[i] === item) return i;\n    return -1;\n  };\n\n  // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.\n  _.lastIndexOf = function(array, item) {\n    if (array == null) return -1;\n    if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);\n    var i = array.length;\n    while (i--) if (i in array && array[i] === item) return i;\n    return -1;\n  };\n\n  // Generate an integer Array containing an arithmetic progression. A port of\n  // the native Python `range()` function. See\n  // [the Python documentation](http://docs.python.org/library/functions.html#range).\n  _.range = function(start, stop, step) {\n    if (arguments.length <= 1) {\n      stop = start || 0;\n      start = 0;\n    }\n    step = arguments[2] || 1;\n\n    var len = Math.max(Math.ceil((stop - start) / step), 0);\n    var idx = 0;\n    var range = new Array(len);\n\n    while(idx < len) {\n      range[idx++] = start;\n      start += step;\n    }\n\n    return range;\n  };\n\n  // Function (ahem) Functions\n  // ------------------\n\n  // Reusable constructor function for prototype setting.\n  var ctor = function(){};\n\n  // Create a function bound to a given object (assigning `this`, and arguments,\n  // optionally). Binding with arguments is also known as `curry`.\n  // Delegates to **ECMAScript 5**'s native `Function.bind` if available.\n  // We check for `func.bind` first, to fail fast when `func` is undefined.\n  _.bind = function bind(func, context) {\n    var bound, args;\n    if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));\n    if (!_.isFunction(func)) throw new TypeError;\n    args = slice.call(arguments, 2);\n    return bound = function() {\n      if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));\n      ctor.prototype = func.prototype;\n      var self = new ctor;\n      var result = func.apply(self, args.concat(slice.call(arguments)));\n      if (Object(result) === result) return result;\n      return self;\n    };\n  };\n\n  // Bind all of an object's methods to that object. Useful for ensuring that\n  // all callbacks defined on an object belong to it.\n  _.bindAll = function(obj) {\n    var funcs = slice.call(arguments, 1);\n    if (funcs.length == 0) funcs = _.functions(obj);\n    each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });\n    return obj;\n  };\n\n  // Memoize an expensive function by storing its results.\n  _.memoize = function(func, hasher) {\n    var memo = {};\n    hasher || (hasher = _.identity);\n    return function() {\n      var key = hasher.apply(this, arguments);\n      return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));\n    };\n  };\n\n  // Delays a function for the given number of milliseconds, and then calls\n  // it with the arguments supplied.\n  _.delay = function(func, wait) {\n    var args = slice.call(arguments, 2);\n    return setTimeout(function(){ return func.apply(func, args); }, wait);\n  };\n\n  // Defers a function, scheduling it to run after the current call stack has\n  // cleared.\n  _.defer = function(func) {\n    return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));\n  };\n\n  // Returns a function, that, when invoked, will only be triggered at most once\n  // during a given window of time.\n  _.throttle = function(func, wait) {\n    var context, args, timeout, throttling, more;\n    var whenDone = _.debounce(function(){ more = throttling = false; }, wait);\n    return function() {\n      context = this; args = arguments;\n      var later = function() {\n        timeout = null;\n        if (more) func.apply(context, args);\n        whenDone();\n      };\n      if (!timeout) timeout = setTimeout(later, wait);\n      if (throttling) {\n        more = true;\n      } else {\n        func.apply(context, args);\n      }\n      whenDone();\n      throttling = true;\n    };\n  };\n\n  // Returns a function, that, as long as it continues to be invoked, will not\n  // be triggered. The function will be called after it stops being called for\n  // N milliseconds.\n  _.debounce = function(func, wait) {\n    var timeout;\n    return function() {\n      var context = this, args = arguments;\n      var later = function() {\n        timeout = null;\n        func.apply(context, args);\n      };\n      clearTimeout(timeout);\n      timeout = setTimeout(later, wait);\n    };\n  };\n\n  // Returns a function that will be executed at most one time, no matter how\n  // often you call it. Useful for lazy initialization.\n  _.once = function(func) {\n    var ran = false, memo;\n    return function() {\n      if (ran) return memo;\n      ran = true;\n      return memo = func.apply(this, arguments);\n    };\n  };\n\n  // Returns the first function passed as an argument to the second,\n  // allowing you to adjust arguments, run code before and after, and\n  // conditionally execute the original function.\n  _.wrap = function(func, wrapper) {\n    return function() {\n      var args = [func].concat(slice.call(arguments, 0));\n      return wrapper.apply(this, args);\n    };\n  };\n\n  // Returns a function that is the composition of a list of functions, each\n  // consuming the return value of the function that follows.\n  _.compose = function() {\n    var funcs = arguments;\n    return function() {\n      var args = arguments;\n      for (var i = funcs.length - 1; i >= 0; i--) {\n        args = [funcs[i].apply(this, args)];\n      }\n      return args[0];\n    };\n  };\n\n  // Returns a function that will only be executed after being called N times.\n  _.after = function(times, func) {\n    if (times <= 0) return func();\n    return function() {\n      if (--times < 1) { return func.apply(this, arguments); }\n    };\n  };\n\n  // Object Functions\n  // ----------------\n\n  // Retrieve the names of an object's properties.\n  // Delegates to **ECMAScript 5**'s native `Object.keys`\n  _.keys = nativeKeys || function(obj) {\n    if (obj !== Object(obj)) throw new TypeError('Invalid object');\n    var keys = [];\n    for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;\n    return keys;\n  };\n\n  // Retrieve the values of an object's properties.\n  _.values = function(obj) {\n    return _.map(obj, _.identity);\n  };\n\n  // Return a sorted list of the function names available on the object.\n  // Aliased as `methods`\n  _.functions = _.methods = function(obj) {\n    var names = [];\n    for (var key in obj) {\n      if (_.isFunction(obj[key])) names.push(key);\n    }\n    return names.sort();\n  };\n\n  // Extend a given object with all the properties in passed-in object(s).\n  _.extend = function(obj) {\n    each(slice.call(arguments, 1), function(source) {\n      for (var prop in source) {\n        obj[prop] = source[prop];\n      }\n    });\n    return obj;\n  };\n\n  // Fill in a given object with default properties.\n  _.defaults = function(obj) {\n    each(slice.call(arguments, 1), function(source) {\n      for (var prop in source) {\n        if (obj[prop] == null) obj[prop] = source[prop];\n      }\n    });\n    return obj;\n  };\n\n  // Create a (shallow-cloned) duplicate of an object.\n  _.clone = function(obj) {\n    if (!_.isObject(obj)) return obj;\n    return _.isArray(obj) ? obj.slice() : _.extend({}, obj);\n  };\n\n  // Invokes interceptor with the obj, and then returns obj.\n  // The primary purpose of this method is to \"tap into\" a method chain, in\n  // order to perform operations on intermediate results within the chain.\n  _.tap = function(obj, interceptor) {\n    interceptor(obj);\n    return obj;\n  };\n\n  // Internal recursive comparison function.\n  function eq(a, b, stack) {\n    // Identical objects are equal. `0 === -0`, but they aren't identical.\n    // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.\n    if (a === b) return a !== 0 || 1 / a == 1 / b;\n    // A strict comparison is necessary because `null == undefined`.\n    if (a == null || b == null) return a === b;\n    // Unwrap any wrapped objects.\n    if (a._chain) a = a._wrapped;\n    if (b._chain) b = b._wrapped;\n    // Invoke a custom `isEqual` method if one is provided.\n    if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b);\n    if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a);\n    // Compare `[[Class]]` names.\n    var className = toString.call(a);\n    if (className != toString.call(b)) return false;\n    switch (className) {\n      // Strings, numbers, dates, and booleans are compared by value.\n      case '[object String]':\n        // Primitives and their corresponding object wrappers are equivalent; thus, `\"5\"` is\n        // equivalent to `new String(\"5\")`.\n        return a == String(b);\n      case '[object Number]':\n        // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for\n        // other numeric values.\n        return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);\n      case '[object Date]':\n      case '[object Boolean]':\n        // Coerce dates and booleans to numeric primitive values. Dates are compared by their\n        // millisecond representations. Note that invalid dates with millisecond representations\n        // of `NaN` are not equivalent.\n        return +a == +b;\n      // RegExps are compared by their source patterns and flags.\n      case '[object RegExp]':\n        return a.source == b.source &&\n               a.global == b.global &&\n               a.multiline == b.multiline &&\n               a.ignoreCase == b.ignoreCase;\n    }\n    if (typeof a != 'object' || typeof b != 'object') return false;\n    // Assume equality for cyclic structures. The algorithm for detecting cyclic\n    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.\n    var length = stack.length;\n    while (length--) {\n      // Linear search. Performance is inversely proportional to the number of\n      // unique nested structures.\n      if (stack[length] == a) return true;\n    }\n    // Add the first object to the stack of traversed objects.\n    stack.push(a);\n    var size = 0, result = true;\n    // Recursively compare objects and arrays.\n    if (className == '[object Array]') {\n      // Compare array lengths to determine if a deep comparison is necessary.\n      size = a.length;\n      result = size == b.length;\n      if (result) {\n        // Deep compare the contents, ignoring non-numeric properties.\n        while (size--) {\n          // Ensure commutative equality for sparse arrays.\n          if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;\n        }\n      }\n    } else {\n      // Objects with different constructors are not equivalent.\n      if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) return false;\n      // Deep compare objects.\n      for (var key in a) {\n        if (_.has(a, key)) {\n          // Count the expected number of properties.\n          size++;\n          // Deep compare each member.\n          if (!(result = _.has(b, key) && eq(a[key], b[key], stack))) break;\n        }\n      }\n      // Ensure that both objects contain the same number of properties.\n      if (result) {\n        for (key in b) {\n          if (_.has(b, key) && !(size--)) break;\n        }\n        result = !size;\n      }\n    }\n    // Remove the first object from the stack of traversed objects.\n    stack.pop();\n    return result;\n  }\n\n  // Perform a deep comparison to check if two objects are equal.\n  _.isEqual = function(a, b) {\n    return eq(a, b, []);\n  };\n\n  // Is a given array, string, or object empty?\n  // An \"empty\" object has no enumerable own-properties.\n  _.isEmpty = function(obj) {\n    if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;\n    for (var key in obj) if (_.has(obj, key)) return false;\n    return true;\n  };\n\n  // Is a given value a DOM element?\n  _.isElement = function(obj) {\n    return !!(obj && obj.nodeType == 1);\n  };\n\n  // Is a given value an array?\n  // Delegates to ECMA5's native Array.isArray\n  _.isArray = nativeIsArray || function(obj) {\n    return toString.call(obj) == '[object Array]';\n  };\n\n  // Is a given variable an object?\n  _.isObject = function(obj) {\n    return obj === Object(obj);\n  };\n\n  // Is a given variable an arguments object?\n  _.isArguments = function(obj) {\n    return toString.call(obj) == '[object Arguments]';\n  };\n  if (!_.isArguments(arguments)) {\n    _.isArguments = function(obj) {\n      return !!(obj && _.has(obj, 'callee'));\n    };\n  }\n\n  // Is a given value a function?\n  _.isFunction = function(obj) {\n    return toString.call(obj) == '[object Function]';\n  };\n\n  // Is a given value a string?\n  _.isString = function(obj) {\n    return toString.call(obj) == '[object String]';\n  };\n\n  // Is a given value a number?\n  _.isNumber = function(obj) {\n    return toString.call(obj) == '[object Number]';\n  };\n\n  // Is the given value `NaN`?\n  _.isNaN = function(obj) {\n    // `NaN` is the only value for which `===` is not reflexive.\n    return obj !== obj;\n  };\n\n  // Is a given value a boolean?\n  _.isBoolean = function(obj) {\n    return obj === true || obj === false || toString.call(obj) == '[object Boolean]';\n  };\n\n  // Is a given value a date?\n  _.isDate = function(obj) {\n    return toString.call(obj) == '[object Date]';\n  };\n\n  // Is the given value a regular expression?\n  _.isRegExp = function(obj) {\n    return toString.call(obj) == '[object RegExp]';\n  };\n\n  // Is a given value equal to null?\n  _.isNull = function(obj) {\n    return obj === null;\n  };\n\n  // Is a given variable undefined?\n  _.isUndefined = function(obj) {\n    return obj === void 0;\n  };\n\n  // Has own property?\n  _.has = function(obj, key) {\n    return hasOwnProperty.call(obj, key);\n  };\n\n  // Utility Functions\n  // -----------------\n\n  // Run Underscore.js in *noConflict* mode, returning the `_` variable to its\n  // previous owner. Returns a reference to the Underscore object.\n  _.noConflict = function() {\n    root._ = previousUnderscore;\n    return this;\n  };\n\n  // Keep the identity function around for default iterators.\n  _.identity = function(value) {\n    return value;\n  };\n\n  // Run a function **n** times.\n  _.times = function (n, iterator, context) {\n    for (var i = 0; i < n; i++) iterator.call(context, i);\n  };\n\n  // Escape a string for HTML interpolation.\n  _.escape = function(string) {\n    return (''+string).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\\//g,'&#x2F;');\n  };\n\n  // Add your own custom functions to the Underscore object, ensuring that\n  // they're correctly added to the OOP wrapper as well.\n  _.mixin = function(obj) {\n    each(_.functions(obj), function(name){\n      addToWrapper(name, _[name] = obj[name]);\n    });\n  };\n\n  // Generate a unique integer id (unique within the entire client session).\n  // Useful for temporary DOM ids.\n  var idCounter = 0;\n  _.uniqueId = function(prefix) {\n    var id = idCounter++;\n    return prefix ? prefix + id : id;\n  };\n\n  // By default, Underscore uses ERB-style template delimiters, change the\n  // following template settings to use alternative delimiters.\n  _.templateSettings = {\n    evaluate    : /<%([\\s\\S]+?)%>/g,\n    interpolate : /<%=([\\s\\S]+?)%>/g,\n    escape      : /<%-([\\s\\S]+?)%>/g\n  };\n\n  // When customizing `templateSettings`, if you don't want to define an\n  // interpolation, evaluation or escaping regex, we need one that is\n  // guaranteed not to match.\n  var noMatch = /.^/;\n\n  // Within an interpolation, evaluation, or escaping, remove HTML escaping\n  // that had been previously added.\n  var unescape = function(code) {\n    return code.replace(/\\\\\\\\/g, '\\\\').replace(/\\\\'/g, \"'\");\n  };\n\n  // JavaScript micro-templating, similar to John Resig's implementation.\n  // Underscore templating handles arbitrary delimiters, preserves whitespace,\n  // and correctly escapes quotes within interpolated code.\n  _.template = function(str, data) {\n    var c  = _.templateSettings;\n    var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +\n      'with(obj||{}){__p.push(\\'' +\n      str.replace(/\\\\/g, '\\\\\\\\')\n         .replace(/'/g, \"\\\\'\")\n         .replace(c.escape || noMatch, function(match, code) {\n           return \"',_.escape(\" + unescape(code) + \"),'\";\n         })\n         .replace(c.interpolate || noMatch, function(match, code) {\n           return \"',\" + unescape(code) + \",'\";\n         })\n         .replace(c.evaluate || noMatch, function(match, code) {\n           return \"');\" + unescape(code).replace(/[\\r\\n\\t]/g, ' ') + \";__p.push('\";\n         })\n         .replace(/\\r/g, '\\\\r')\n         .replace(/\\n/g, '\\\\n')\n         .replace(/\\t/g, '\\\\t')\n         + \"');}return __p.join('');\";\n    var func = new Function('obj', '_', tmpl);\n    if (data) return func(data, _);\n    return function(data) {\n      return func.call(this, data, _);\n    };\n  };\n\n  // Add a \"chain\" function, which will delegate to the wrapper.\n  _.chain = function(obj) {\n    return _(obj).chain();\n  };\n\n  // The OOP Wrapper\n  // ---------------\n\n  // If Underscore is called as a function, it returns a wrapped object that\n  // can be used OO-style. This wrapper holds altered versions of all the\n  // underscore functions. Wrapped objects may be chained.\n  var wrapper = function(obj) { this._wrapped = obj; };\n\n  // Expose `wrapper.prototype` as `_.prototype`\n  _.prototype = wrapper.prototype;\n\n  // Helper function to continue chaining intermediate results.\n  var result = function(obj, chain) {\n    return chain ? _(obj).chain() : obj;\n  };\n\n  // A method to easily add functions to the OOP wrapper.\n  var addToWrapper = function(name, func) {\n    wrapper.prototype[name] = function() {\n      var args = slice.call(arguments);\n      unshift.call(args, this._wrapped);\n      return result(func.apply(_, args), this._chain);\n    };\n  };\n\n  // Add all of the Underscore functions to the wrapper object.\n  _.mixin(_);\n\n  // Add all mutator Array functions to the wrapper.\n  each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {\n    var method = ArrayProto[name];\n    wrapper.prototype[name] = function() {\n      var wrapped = this._wrapped;\n      method.apply(wrapped, arguments);\n      var length = wrapped.length;\n      if ((name == 'shift' || name == 'splice') && length === 0) delete wrapped[0];\n      return result(wrapped, this._chain);\n    };\n  });\n\n  // Add all accessor Array functions to the wrapper.\n  each(['concat', 'join', 'slice'], function(name) {\n    var method = ArrayProto[name];\n    wrapper.prototype[name] = function() {\n      return result(method.apply(this._wrapped, arguments), this._chain);\n    };\n  });\n\n  // Start chaining a wrapped Underscore object.\n  wrapper.prototype.chain = function() {\n    this._chain = true;\n    return this;\n  };\n\n  // Extracts the result from a wrapped and chained object.\n  wrapper.prototype.value = function() {\n    return this._wrapped;\n  };\n\n}).call(this);\n"
  },
  {
    "path": "docs/_static/underscore.js",
    "content": "!function(n,r){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=r():\"function\"==typeof define&&define.amd?define(\"underscore\",r):(n=n||self,function(){var t=n._,e=n._=r();e.noConflict=function(){return n._=t,e}}())}(this,(function(){\n//     Underscore.js 1.12.0\n//     https://underscorejs.org\n//     (c) 2009-2020 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n//     Underscore may be freely distributed under the MIT license.\nvar n=\"1.12.0\",r=\"object\"==typeof self&&self.self===self&&self||\"object\"==typeof global&&global.global===global&&global||Function(\"return this\")()||{},t=Array.prototype,e=Object.prototype,u=\"undefined\"!=typeof Symbol?Symbol.prototype:null,o=t.push,i=t.slice,a=e.toString,f=e.hasOwnProperty,c=\"undefined\"!=typeof ArrayBuffer,l=\"undefined\"!=typeof DataView,s=Array.isArray,p=Object.keys,v=Object.create,h=c&&ArrayBuffer.isView,y=isNaN,g=isFinite,d=!{toString:null}.propertyIsEnumerable(\"toString\"),b=[\"valueOf\",\"isPrototypeOf\",\"toString\",\"propertyIsEnumerable\",\"hasOwnProperty\",\"toLocaleString\"],m=Math.pow(2,53)-1;function j(n,r){return r=null==r?n.length-1:+r,function(){for(var t=Math.max(arguments.length-r,0),e=Array(t),u=0;u<t;u++)e[u]=arguments[u+r];switch(r){case 0:return n.call(this,e);case 1:return n.call(this,arguments[0],e);case 2:return n.call(this,arguments[0],arguments[1],e)}var o=Array(r+1);for(u=0;u<r;u++)o[u]=arguments[u];return o[r]=e,n.apply(this,o)}}function _(n){var r=typeof n;return\"function\"===r||\"object\"===r&&!!n}function w(n){return void 0===n}function A(n){return!0===n||!1===n||\"[object Boolean]\"===a.call(n)}function x(n){var r=\"[object \"+n+\"]\";return function(n){return a.call(n)===r}}var S=x(\"String\"),O=x(\"Number\"),M=x(\"Date\"),E=x(\"RegExp\"),B=x(\"Error\"),N=x(\"Symbol\"),I=x(\"ArrayBuffer\"),k=x(\"Function\"),T=r.document&&r.document.childNodes;\"function\"!=typeof/./&&\"object\"!=typeof Int8Array&&\"function\"!=typeof T&&(k=function(n){return\"function\"==typeof n||!1});var D=k,R=x(\"Object\"),F=l&&R(new DataView(new ArrayBuffer(8))),V=\"undefined\"!=typeof Map&&R(new Map),P=x(\"DataView\");var q=F?function(n){return null!=n&&D(n.getInt8)&&I(n.buffer)}:P,U=s||x(\"Array\");function W(n,r){return null!=n&&f.call(n,r)}var z=x(\"Arguments\");!function(){z(arguments)||(z=function(n){return W(n,\"callee\")})}();var L=z;function C(n){return O(n)&&y(n)}function K(n){return function(){return n}}function J(n){return function(r){var t=n(r);return\"number\"==typeof t&&t>=0&&t<=m}}function $(n){return function(r){return null==r?void 0:r[n]}}var G=$(\"byteLength\"),H=J(G),Q=/\\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\\]/;var X=c?function(n){return h?h(n)&&!q(n):H(n)&&Q.test(a.call(n))}:K(!1),Y=$(\"length\");function Z(n,r){r=function(n){for(var r={},t=n.length,e=0;e<t;++e)r[n[e]]=!0;return{contains:function(n){return r[n]},push:function(t){return r[t]=!0,n.push(t)}}}(r);var t=b.length,u=n.constructor,o=D(u)&&u.prototype||e,i=\"constructor\";for(W(n,i)&&!r.contains(i)&&r.push(i);t--;)(i=b[t])in n&&n[i]!==o[i]&&!r.contains(i)&&r.push(i)}function nn(n){if(!_(n))return[];if(p)return p(n);var r=[];for(var t in n)W(n,t)&&r.push(t);return d&&Z(n,r),r}function rn(n,r){var t=nn(r),e=t.length;if(null==n)return!e;for(var u=Object(n),o=0;o<e;o++){var i=t[o];if(r[i]!==u[i]||!(i in u))return!1}return!0}function tn(n){return n instanceof tn?n:this instanceof tn?void(this._wrapped=n):new tn(n)}function en(n){return new Uint8Array(n.buffer||n,n.byteOffset||0,G(n))}tn.VERSION=n,tn.prototype.value=function(){return this._wrapped},tn.prototype.valueOf=tn.prototype.toJSON=tn.prototype.value,tn.prototype.toString=function(){return String(this._wrapped)};var un=\"[object DataView]\";function on(n,r,t,e){if(n===r)return 0!==n||1/n==1/r;if(null==n||null==r)return!1;if(n!=n)return r!=r;var o=typeof n;return(\"function\"===o||\"object\"===o||\"object\"==typeof r)&&function n(r,t,e,o){r instanceof tn&&(r=r._wrapped);t instanceof tn&&(t=t._wrapped);var i=a.call(r);if(i!==a.call(t))return!1;if(F&&\"[object Object]\"==i&&q(r)){if(!q(t))return!1;i=un}switch(i){case\"[object RegExp]\":case\"[object String]\":return\"\"+r==\"\"+t;case\"[object Number]\":return+r!=+r?+t!=+t:0==+r?1/+r==1/t:+r==+t;case\"[object Date]\":case\"[object Boolean]\":return+r==+t;case\"[object Symbol]\":return u.valueOf.call(r)===u.valueOf.call(t);case\"[object ArrayBuffer]\":case un:return n(en(r),en(t),e,o)}var f=\"[object Array]\"===i;if(!f&&X(r)){if(G(r)!==G(t))return!1;if(r.buffer===t.buffer&&r.byteOffset===t.byteOffset)return!0;f=!0}if(!f){if(\"object\"!=typeof r||\"object\"!=typeof t)return!1;var c=r.constructor,l=t.constructor;if(c!==l&&!(D(c)&&c instanceof c&&D(l)&&l instanceof l)&&\"constructor\"in r&&\"constructor\"in t)return!1}o=o||[];var s=(e=e||[]).length;for(;s--;)if(e[s]===r)return o[s]===t;if(e.push(r),o.push(t),f){if((s=r.length)!==t.length)return!1;for(;s--;)if(!on(r[s],t[s],e,o))return!1}else{var p,v=nn(r);if(s=v.length,nn(t).length!==s)return!1;for(;s--;)if(p=v[s],!W(t,p)||!on(r[p],t[p],e,o))return!1}return e.pop(),o.pop(),!0}(n,r,t,e)}function an(n){if(!_(n))return[];var r=[];for(var t in n)r.push(t);return d&&Z(n,r),r}function fn(n){var r=Y(n);return function(t){if(null==t)return!1;var e=an(t);if(Y(e))return!1;for(var u=0;u<r;u++)if(!D(t[n[u]]))return!1;return n!==hn||!D(t[cn])}}var cn=\"forEach\",ln=\"has\",sn=[\"clear\",\"delete\"],pn=[\"get\",ln,\"set\"],vn=sn.concat(cn,pn),hn=sn.concat(pn),yn=[\"add\"].concat(sn,cn,ln),gn=V?fn(vn):x(\"Map\"),dn=V?fn(hn):x(\"WeakMap\"),bn=V?fn(yn):x(\"Set\"),mn=x(\"WeakSet\");function jn(n){for(var r=nn(n),t=r.length,e=Array(t),u=0;u<t;u++)e[u]=n[r[u]];return e}function _n(n){for(var r={},t=nn(n),e=0,u=t.length;e<u;e++)r[n[t[e]]]=t[e];return r}function wn(n){var r=[];for(var t in n)D(n[t])&&r.push(t);return r.sort()}function An(n,r){return function(t){var e=arguments.length;if(r&&(t=Object(t)),e<2||null==t)return t;for(var u=1;u<e;u++)for(var o=arguments[u],i=n(o),a=i.length,f=0;f<a;f++){var c=i[f];r&&void 0!==t[c]||(t[c]=o[c])}return t}}var xn=An(an),Sn=An(nn),On=An(an,!0);function Mn(n){if(!_(n))return{};if(v)return v(n);var r=function(){};r.prototype=n;var t=new r;return r.prototype=null,t}function En(n){return _(n)?U(n)?n.slice():xn({},n):n}function Bn(n){return U(n)?n:[n]}function Nn(n){return tn.toPath(n)}function In(n,r){for(var t=r.length,e=0;e<t;e++){if(null==n)return;n=n[r[e]]}return t?n:void 0}function kn(n,r,t){var e=In(n,Nn(r));return w(e)?t:e}function Tn(n){return n}function Dn(n){return n=Sn({},n),function(r){return rn(r,n)}}function Rn(n){return n=Nn(n),function(r){return In(r,n)}}function Fn(n,r,t){if(void 0===r)return n;switch(null==t?3:t){case 1:return function(t){return n.call(r,t)};case 3:return function(t,e,u){return n.call(r,t,e,u)};case 4:return function(t,e,u,o){return n.call(r,t,e,u,o)}}return function(){return n.apply(r,arguments)}}function Vn(n,r,t){return null==n?Tn:D(n)?Fn(n,r,t):_(n)&&!U(n)?Dn(n):Rn(n)}function Pn(n,r){return Vn(n,r,1/0)}function qn(n,r,t){return tn.iteratee!==Pn?tn.iteratee(n,r):Vn(n,r,t)}function Un(){}function Wn(n,r){return null==r&&(r=n,n=0),n+Math.floor(Math.random()*(r-n+1))}tn.toPath=Bn,tn.iteratee=Pn;var zn=Date.now||function(){return(new Date).getTime()};function Ln(n){var r=function(r){return n[r]},t=\"(?:\"+nn(n).join(\"|\")+\")\",e=RegExp(t),u=RegExp(t,\"g\");return function(n){return n=null==n?\"\":\"\"+n,e.test(n)?n.replace(u,r):n}}var Cn={\"&\":\"&amp;\",\"<\":\"&lt;\",\">\":\"&gt;\",'\"':\"&quot;\",\"'\":\"&#x27;\",\"`\":\"&#x60;\"},Kn=Ln(Cn),Jn=Ln(_n(Cn)),$n=tn.templateSettings={evaluate:/<%([\\s\\S]+?)%>/g,interpolate:/<%=([\\s\\S]+?)%>/g,escape:/<%-([\\s\\S]+?)%>/g},Gn=/(.)^/,Hn={\"'\":\"'\",\"\\\\\":\"\\\\\",\"\\r\":\"r\",\"\\n\":\"n\",\"\\u2028\":\"u2028\",\"\\u2029\":\"u2029\"},Qn=/\\\\|'|\\r|\\n|\\u2028|\\u2029/g;function Xn(n){return\"\\\\\"+Hn[n]}var Yn=0;function Zn(n,r,t,e,u){if(!(e instanceof r))return n.apply(t,u);var o=Mn(n.prototype),i=n.apply(o,u);return _(i)?i:o}var nr=j((function(n,r){var t=nr.placeholder,e=function(){for(var u=0,o=r.length,i=Array(o),a=0;a<o;a++)i[a]=r[a]===t?arguments[u++]:r[a];for(;u<arguments.length;)i.push(arguments[u++]);return Zn(n,e,this,this,i)};return e}));nr.placeholder=tn;var rr=j((function(n,r,t){if(!D(n))throw new TypeError(\"Bind must be called on a function\");var e=j((function(u){return Zn(n,e,r,this,t.concat(u))}));return e})),tr=J(Y);function er(n,r,t,e){if(e=e||[],r||0===r){if(r<=0)return e.concat(n)}else r=1/0;for(var u=e.length,o=0,i=Y(n);o<i;o++){var a=n[o];if(tr(a)&&(U(a)||L(a)))if(r>1)er(a,r-1,t,e),u=e.length;else for(var f=0,c=a.length;f<c;)e[u++]=a[f++];else t||(e[u++]=a)}return e}var ur=j((function(n,r){var t=(r=er(r,!1,!1)).length;if(t<1)throw new Error(\"bindAll must be passed function names\");for(;t--;){var e=r[t];n[e]=rr(n[e],n)}return n}));var or=j((function(n,r,t){return setTimeout((function(){return n.apply(null,t)}),r)})),ir=nr(or,tn,1);function ar(n){return function(){return!n.apply(this,arguments)}}function fr(n,r){var t;return function(){return--n>0&&(t=r.apply(this,arguments)),n<=1&&(r=null),t}}var cr=nr(fr,2);function lr(n,r,t){r=qn(r,t);for(var e,u=nn(n),o=0,i=u.length;o<i;o++)if(r(n[e=u[o]],e,n))return e}function sr(n){return function(r,t,e){t=qn(t,e);for(var u=Y(r),o=n>0?0:u-1;o>=0&&o<u;o+=n)if(t(r[o],o,r))return o;return-1}}var pr=sr(1),vr=sr(-1);function hr(n,r,t,e){for(var u=(t=qn(t,e,1))(r),o=0,i=Y(n);o<i;){var a=Math.floor((o+i)/2);t(n[a])<u?o=a+1:i=a}return o}function yr(n,r,t){return function(e,u,o){var a=0,f=Y(e);if(\"number\"==typeof o)n>0?a=o>=0?o:Math.max(o+f,a):f=o>=0?Math.min(o+1,f):o+f+1;else if(t&&o&&f)return e[o=t(e,u)]===u?o:-1;if(u!=u)return(o=r(i.call(e,a,f),C))>=0?o+a:-1;for(o=n>0?a:f-1;o>=0&&o<f;o+=n)if(e[o]===u)return o;return-1}}var gr=yr(1,pr,hr),dr=yr(-1,vr);function br(n,r,t){var e=(tr(n)?pr:lr)(n,r,t);if(void 0!==e&&-1!==e)return n[e]}function mr(n,r,t){var e,u;if(r=Fn(r,t),tr(n))for(e=0,u=n.length;e<u;e++)r(n[e],e,n);else{var o=nn(n);for(e=0,u=o.length;e<u;e++)r(n[o[e]],o[e],n)}return n}function jr(n,r,t){r=qn(r,t);for(var e=!tr(n)&&nn(n),u=(e||n).length,o=Array(u),i=0;i<u;i++){var a=e?e[i]:i;o[i]=r(n[a],a,n)}return o}function _r(n){var r=function(r,t,e,u){var o=!tr(r)&&nn(r),i=(o||r).length,a=n>0?0:i-1;for(u||(e=r[o?o[a]:a],a+=n);a>=0&&a<i;a+=n){var f=o?o[a]:a;e=t(e,r[f],f,r)}return e};return function(n,t,e,u){var o=arguments.length>=3;return r(n,Fn(t,u,4),e,o)}}var wr=_r(1),Ar=_r(-1);function xr(n,r,t){var e=[];return r=qn(r,t),mr(n,(function(n,t,u){r(n,t,u)&&e.push(n)})),e}function Sr(n,r,t){r=qn(r,t);for(var e=!tr(n)&&nn(n),u=(e||n).length,o=0;o<u;o++){var i=e?e[o]:o;if(!r(n[i],i,n))return!1}return!0}function Or(n,r,t){r=qn(r,t);for(var e=!tr(n)&&nn(n),u=(e||n).length,o=0;o<u;o++){var i=e?e[o]:o;if(r(n[i],i,n))return!0}return!1}function Mr(n,r,t,e){return tr(n)||(n=jn(n)),(\"number\"!=typeof t||e)&&(t=0),gr(n,r,t)>=0}var Er=j((function(n,r,t){var e,u;return D(r)?u=r:(r=Nn(r),e=r.slice(0,-1),r=r[r.length-1]),jr(n,(function(n){var o=u;if(!o){if(e&&e.length&&(n=In(n,e)),null==n)return;o=n[r]}return null==o?o:o.apply(n,t)}))}));function Br(n,r){return jr(n,Rn(r))}function Nr(n,r,t){var e,u,o=-1/0,i=-1/0;if(null==r||\"number\"==typeof r&&\"object\"!=typeof n[0]&&null!=n)for(var a=0,f=(n=tr(n)?n:jn(n)).length;a<f;a++)null!=(e=n[a])&&e>o&&(o=e);else r=qn(r,t),mr(n,(function(n,t,e){((u=r(n,t,e))>i||u===-1/0&&o===-1/0)&&(o=n,i=u)}));return o}function Ir(n,r,t){if(null==r||t)return tr(n)||(n=jn(n)),n[Wn(n.length-1)];var e=tr(n)?En(n):jn(n),u=Y(e);r=Math.max(Math.min(r,u),0);for(var o=u-1,i=0;i<r;i++){var a=Wn(i,o),f=e[i];e[i]=e[a],e[a]=f}return e.slice(0,r)}function kr(n,r){return function(t,e,u){var o=r?[[],[]]:{};return e=qn(e,u),mr(t,(function(r,u){var i=e(r,u,t);n(o,r,i)})),o}}var Tr=kr((function(n,r,t){W(n,t)?n[t].push(r):n[t]=[r]})),Dr=kr((function(n,r,t){n[t]=r})),Rr=kr((function(n,r,t){W(n,t)?n[t]++:n[t]=1})),Fr=kr((function(n,r,t){n[t?0:1].push(r)}),!0),Vr=/[^\\ud800-\\udfff]|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\ud800-\\udfff]/g;function Pr(n,r,t){return r in t}var qr=j((function(n,r){var t={},e=r[0];if(null==n)return t;D(e)?(r.length>1&&(e=Fn(e,r[1])),r=an(n)):(e=Pr,r=er(r,!1,!1),n=Object(n));for(var u=0,o=r.length;u<o;u++){var i=r[u],a=n[i];e(a,i,n)&&(t[i]=a)}return t})),Ur=j((function(n,r){var t,e=r[0];return D(e)?(e=ar(e),r.length>1&&(t=r[1])):(r=jr(er(r,!1,!1),String),e=function(n,t){return!Mr(r,t)}),qr(n,e,t)}));function Wr(n,r,t){return i.call(n,0,Math.max(0,n.length-(null==r||t?1:r)))}function zr(n,r,t){return null==n||n.length<1?null==r||t?void 0:[]:null==r||t?n[0]:Wr(n,n.length-r)}function Lr(n,r,t){return i.call(n,null==r||t?1:r)}var Cr=j((function(n,r){return r=er(r,!0,!0),xr(n,(function(n){return!Mr(r,n)}))})),Kr=j((function(n,r){return Cr(n,r)}));function Jr(n,r,t,e){A(r)||(e=t,t=r,r=!1),null!=t&&(t=qn(t,e));for(var u=[],o=[],i=0,a=Y(n);i<a;i++){var f=n[i],c=t?t(f,i,n):f;r&&!t?(i&&o===c||u.push(f),o=c):t?Mr(o,c)||(o.push(c),u.push(f)):Mr(u,f)||u.push(f)}return u}var $r=j((function(n){return Jr(er(n,!0,!0))}));function Gr(n){for(var r=n&&Nr(n,Y).length||0,t=Array(r),e=0;e<r;e++)t[e]=Br(n,e);return t}var Hr=j(Gr);function Qr(n,r){return n._chain?tn(r).chain():r}function Xr(n){return mr(wn(n),(function(r){var t=tn[r]=n[r];tn.prototype[r]=function(){var n=[this._wrapped];return o.apply(n,arguments),Qr(this,t.apply(tn,n))}})),tn}mr([\"pop\",\"push\",\"reverse\",\"shift\",\"sort\",\"splice\",\"unshift\"],(function(n){var r=t[n];tn.prototype[n]=function(){var t=this._wrapped;return null!=t&&(r.apply(t,arguments),\"shift\"!==n&&\"splice\"!==n||0!==t.length||delete t[0]),Qr(this,t)}})),mr([\"concat\",\"join\",\"slice\"],(function(n){var r=t[n];tn.prototype[n]=function(){var n=this._wrapped;return null!=n&&(n=r.apply(n,arguments)),Qr(this,n)}}));var Yr=Xr({__proto__:null,VERSION:n,restArguments:j,isObject:_,isNull:function(n){return null===n},isUndefined:w,isBoolean:A,isElement:function(n){return!(!n||1!==n.nodeType)},isString:S,isNumber:O,isDate:M,isRegExp:E,isError:B,isSymbol:N,isArrayBuffer:I,isDataView:q,isArray:U,isFunction:D,isArguments:L,isFinite:function(n){return!N(n)&&g(n)&&!isNaN(parseFloat(n))},isNaN:C,isTypedArray:X,isEmpty:function(n){if(null==n)return!0;var r=Y(n);return\"number\"==typeof r&&(U(n)||S(n)||L(n))?0===r:0===Y(nn(n))},isMatch:rn,isEqual:function(n,r){return on(n,r)},isMap:gn,isWeakMap:dn,isSet:bn,isWeakSet:mn,keys:nn,allKeys:an,values:jn,pairs:function(n){for(var r=nn(n),t=r.length,e=Array(t),u=0;u<t;u++)e[u]=[r[u],n[r[u]]];return e},invert:_n,functions:wn,methods:wn,extend:xn,extendOwn:Sn,assign:Sn,defaults:On,create:function(n,r){var t=Mn(n);return r&&Sn(t,r),t},clone:En,tap:function(n,r){return r(n),n},get:kn,has:function(n,r){for(var t=(r=Nn(r)).length,e=0;e<t;e++){var u=r[e];if(!W(n,u))return!1;n=n[u]}return!!t},mapObject:function(n,r,t){r=qn(r,t);for(var e=nn(n),u=e.length,o={},i=0;i<u;i++){var a=e[i];o[a]=r(n[a],a,n)}return o},identity:Tn,constant:K,noop:Un,toPath:Bn,property:Rn,propertyOf:function(n){return null==n?Un:function(r){return kn(n,r)}},matcher:Dn,matches:Dn,times:function(n,r,t){var e=Array(Math.max(0,n));r=Fn(r,t,1);for(var u=0;u<n;u++)e[u]=r(u);return e},random:Wn,now:zn,escape:Kn,unescape:Jn,templateSettings:$n,template:function(n,r,t){!r&&t&&(r=t),r=On({},r,tn.templateSettings);var e,u=RegExp([(r.escape||Gn).source,(r.interpolate||Gn).source,(r.evaluate||Gn).source].join(\"|\")+\"|$\",\"g\"),o=0,i=\"__p+='\";n.replace(u,(function(r,t,e,u,a){return i+=n.slice(o,a).replace(Qn,Xn),o=a+r.length,t?i+=\"'+\\n((__t=(\"+t+\"))==null?'':_.escape(__t))+\\n'\":e?i+=\"'+\\n((__t=(\"+e+\"))==null?'':__t)+\\n'\":u&&(i+=\"';\\n\"+u+\"\\n__p+='\"),r})),i+=\"';\\n\",r.variable||(i=\"with(obj||{}){\\n\"+i+\"}\\n\"),i=\"var __t,__p='',__j=Array.prototype.join,\"+\"print=function(){__p+=__j.call(arguments,'');};\\n\"+i+\"return __p;\\n\";try{e=new Function(r.variable||\"obj\",\"_\",i)}catch(n){throw n.source=i,n}var a=function(n){return e.call(this,n,tn)},f=r.variable||\"obj\";return a.source=\"function(\"+f+\"){\\n\"+i+\"}\",a},result:function(n,r,t){var e=(r=Nn(r)).length;if(!e)return D(t)?t.call(n):t;for(var u=0;u<e;u++){var o=null==n?void 0:n[r[u]];void 0===o&&(o=t,u=e),n=D(o)?o.call(n):o}return n},uniqueId:function(n){var r=++Yn+\"\";return n?n+r:r},chain:function(n){var r=tn(n);return r._chain=!0,r},iteratee:Pn,partial:nr,bind:rr,bindAll:ur,memoize:function(n,r){var t=function(e){var u=t.cache,o=\"\"+(r?r.apply(this,arguments):e);return W(u,o)||(u[o]=n.apply(this,arguments)),u[o]};return t.cache={},t},delay:or,defer:ir,throttle:function(n,r,t){var e,u,o,i,a=0;t||(t={});var f=function(){a=!1===t.leading?0:zn(),e=null,i=n.apply(u,o),e||(u=o=null)},c=function(){var c=zn();a||!1!==t.leading||(a=c);var l=r-(c-a);return u=this,o=arguments,l<=0||l>r?(e&&(clearTimeout(e),e=null),a=c,i=n.apply(u,o),e||(u=o=null)):e||!1===t.trailing||(e=setTimeout(f,l)),i};return c.cancel=function(){clearTimeout(e),a=0,e=u=o=null},c},debounce:function(n,r,t){var e,u,o=function(r,t){e=null,t&&(u=n.apply(r,t))},i=j((function(i){if(e&&clearTimeout(e),t){var a=!e;e=setTimeout(o,r),a&&(u=n.apply(this,i))}else e=or(o,r,this,i);return u}));return i.cancel=function(){clearTimeout(e),e=null},i},wrap:function(n,r){return nr(r,n)},negate:ar,compose:function(){var n=arguments,r=n.length-1;return function(){for(var t=r,e=n[r].apply(this,arguments);t--;)e=n[t].call(this,e);return e}},after:function(n,r){return function(){if(--n<1)return r.apply(this,arguments)}},before:fr,once:cr,findKey:lr,findIndex:pr,findLastIndex:vr,sortedIndex:hr,indexOf:gr,lastIndexOf:dr,find:br,detect:br,findWhere:function(n,r){return br(n,Dn(r))},each:mr,forEach:mr,map:jr,collect:jr,reduce:wr,foldl:wr,inject:wr,reduceRight:Ar,foldr:Ar,filter:xr,select:xr,reject:function(n,r,t){return xr(n,ar(qn(r)),t)},every:Sr,all:Sr,some:Or,any:Or,contains:Mr,includes:Mr,include:Mr,invoke:Er,pluck:Br,where:function(n,r){return xr(n,Dn(r))},max:Nr,min:function(n,r,t){var e,u,o=1/0,i=1/0;if(null==r||\"number\"==typeof r&&\"object\"!=typeof n[0]&&null!=n)for(var a=0,f=(n=tr(n)?n:jn(n)).length;a<f;a++)null!=(e=n[a])&&e<o&&(o=e);else r=qn(r,t),mr(n,(function(n,t,e){((u=r(n,t,e))<i||u===1/0&&o===1/0)&&(o=n,i=u)}));return o},shuffle:function(n){return Ir(n,1/0)},sample:Ir,sortBy:function(n,r,t){var e=0;return r=qn(r,t),Br(jr(n,(function(n,t,u){return{value:n,index:e++,criteria:r(n,t,u)}})).sort((function(n,r){var t=n.criteria,e=r.criteria;if(t!==e){if(t>e||void 0===t)return 1;if(t<e||void 0===e)return-1}return n.index-r.index})),\"value\")},groupBy:Tr,indexBy:Dr,countBy:Rr,partition:Fr,toArray:function(n){return n?U(n)?i.call(n):S(n)?n.match(Vr):tr(n)?jr(n,Tn):jn(n):[]},size:function(n){return null==n?0:tr(n)?n.length:nn(n).length},pick:qr,omit:Ur,first:zr,head:zr,take:zr,initial:Wr,last:function(n,r,t){return null==n||n.length<1?null==r||t?void 0:[]:null==r||t?n[n.length-1]:Lr(n,Math.max(0,n.length-r))},rest:Lr,tail:Lr,drop:Lr,compact:function(n){return xr(n,Boolean)},flatten:function(n,r){return er(n,r,!1)},without:Kr,uniq:Jr,unique:Jr,union:$r,intersection:function(n){for(var r=[],t=arguments.length,e=0,u=Y(n);e<u;e++){var o=n[e];if(!Mr(r,o)){var i;for(i=1;i<t&&Mr(arguments[i],o);i++);i===t&&r.push(o)}}return r},difference:Cr,unzip:Gr,transpose:Gr,zip:Hr,object:function(n,r){for(var t={},e=0,u=Y(n);e<u;e++)r?t[n[e]]=r[e]:t[n[e][0]]=n[e][1];return t},range:function(n,r,t){null==r&&(r=n||0,n=0),t||(t=r<n?-1:1);for(var e=Math.max(Math.ceil((r-n)/t),0),u=Array(e),o=0;o<e;o++,n+=t)u[o]=n;return u},chunk:function(n,r){if(null==r||r<1)return[];for(var t=[],e=0,u=n.length;e<u;)t.push(i.call(n,e,e+=r));return t},mixin:Xr,default:tn});return Yr._=Yr,Yr}));"
  },
  {
    "path": "docs/genindex.html",
    "content": "\n\n<!DOCTYPE html>\n<html class=\"writer-html5\" lang=\"en\" >\n<head>\n  <meta charset=\"utf-8\" />\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n  \n  <title>Index &mdash; k-means-constrained 0.5.1 documentation</title>\n  \n\n  \n  <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  <link rel=\"stylesheet\" href=\"_static/pygments.css\" type=\"text/css\" />\n  <link rel=\"stylesheet\" href=\"_static/pygments.css\" type=\"text/css\" />\n  <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n\n  \n  \n\n  \n  \n\n  \n\n  \n  <!--[if lt IE 9]>\n    <script src=\"_static/js/html5shiv.min.js\"></script>\n  <![endif]-->\n  \n    \n      <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"./\" src=\"_static/documentation_options.js\"></script>\n        <script data-url_root=\"./\" id=\"documentation_options\" src=\"_static/documentation_options.js\"></script>\n        <script src=\"_static/jquery.js\"></script>\n        <script src=\"_static/underscore.js\"></script>\n        <script src=\"_static/doctools.js\"></script>\n    \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n\n    \n    <link rel=\"index\" title=\"Index\" href=\"#\" />\n    <link rel=\"search\" title=\"Search\" href=\"search.html\" /> \n</head>\n\n<body class=\"wy-body-for-nav\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\" >\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> k-means-constrained\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        \n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n              \n            \n            \n              <!-- Local TOC -->\n              <div class=\"local-toc\"></div>\n            \n          \n        </div>\n        \n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">k-means-constrained</a>\n        \n      </nav>\n\n\n      <div class=\"wy-nav-content\">\n        \n        <div class=\"rst-content\">\n        \n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\" class=\"icon icon-home\"></a> &raquo;</li>\n        \n      <li>Index</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n          \n        \n      </li>\n    \n  </ul>\n\n  \n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n\n<h1 id=\"index\">Index</h1>\n\n<div class=\"genindex-jumpbox\">\n <a href=\"#F\"><strong>F</strong></a>\n | <a href=\"#G\"><strong>G</strong></a>\n | <a href=\"#K\"><strong>K</strong></a>\n | <a href=\"#M\"><strong>M</strong></a>\n | <a href=\"#P\"><strong>P</strong></a>\n | <a href=\"#S\"><strong>S</strong></a>\n | <a href=\"#T\"><strong>T</strong></a>\n \n</div>\n<h2 id=\"F\">F</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"index.html#k_means_constrained.KMeansConstrained.fit\">fit() (k_means_constrained.KMeansConstrained method)</a>\n</li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"index.html#k_means_constrained.KMeansConstrained.fit_predict\">fit_predict() (k_means_constrained.KMeansConstrained method)</a>\n</li>\n      <li><a href=\"index.html#k_means_constrained.KMeansConstrained.fit_transform\">fit_transform() (k_means_constrained.KMeansConstrained method)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"G\">G</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"index.html#k_means_constrained.KMeansConstrained.get_params\">get_params() (k_means_constrained.KMeansConstrained method)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"K\">K</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li>\n    k_means_constrained\n\n      <ul>\n        <li><a href=\"index.html#module-k_means_constrained\">module</a>\n</li>\n      </ul></li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"index.html#k_means_constrained.KMeansConstrained\">KMeansConstrained (class in k_means_constrained)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"M\">M</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li>\n    module\n\n      <ul>\n        <li><a href=\"index.html#module-k_means_constrained\">k_means_constrained</a>\n</li>\n      </ul></li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"P\">P</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"index.html#k_means_constrained.KMeansConstrained.predict\">predict() (k_means_constrained.KMeansConstrained method)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"S\">S</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"index.html#k_means_constrained.KMeansConstrained.score\">score() (k_means_constrained.KMeansConstrained method)</a>\n</li>\n  </ul></td>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"index.html#k_means_constrained.KMeansConstrained.set_params\">set_params() (k_means_constrained.KMeansConstrained method)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n<h2 id=\"T\">T</h2>\n<table style=\"width: 100%\" class=\"indextable genindextable\"><tr>\n  <td style=\"width: 33%; vertical-align: top;\"><ul>\n      <li><a href=\"index.html#k_means_constrained.KMeansConstrained.transform\">transform() (k_means_constrained.KMeansConstrained method)</a>\n</li>\n  </ul></td>\n</tr></table>\n\n\n\n           </div>\n           \n          </div>\n          <footer>\n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &#169; Copyright 2020, Josh Levy-Kramer. Documentation derived from Scikit-Learn.\n\n    </p>\n  </div>\n    \n    \n    \n    Built with <a href=\"https://www.sphinx-doc.org/\">Sphinx</a> using a\n    \n    <a href=\"https://github.com/readthedocs/sphinx_rtd_theme\">theme</a>\n    \n    provided by <a href=\"https://readthedocs.org\">Read the Docs</a>. \n\n</footer>\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.Navigation.enable(true);\n      });\n  </script>\n\n  \n  \n    \n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/index.html",
    "content": "\n\n<!DOCTYPE html>\n<html class=\"writer-html5\" lang=\"en\" >\n<head>\n  <meta charset=\"utf-8\" />\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n  \n  <title>Welcome to k-means-constrained’s documentation! &mdash; k-means-constrained 0.5.1 documentation</title>\n  \n\n  \n  <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  <link rel=\"stylesheet\" href=\"_static/pygments.css\" type=\"text/css\" />\n  <link rel=\"stylesheet\" href=\"_static/pygments.css\" type=\"text/css\" />\n  <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n\n  \n  \n\n  \n  \n\n  \n\n  \n  <!--[if lt IE 9]>\n    <script src=\"_static/js/html5shiv.min.js\"></script>\n  <![endif]-->\n  \n    \n      <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"./\" src=\"_static/documentation_options.js\"></script>\n        <script data-url_root=\"./\" id=\"documentation_options\" src=\"_static/documentation_options.js\"></script>\n        <script src=\"_static/jquery.js\"></script>\n        <script src=\"_static/underscore.js\"></script>\n        <script src=\"_static/doctools.js\"></script>\n    \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n\n    \n    <link rel=\"index\" title=\"Index\" href=\"genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"search.html\" /> \n</head>\n\n<body class=\"wy-body-for-nav\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\" >\n          \n\n          \n            <a href=\"#\" class=\"icon icon-home\"> k-means-constrained\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        \n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n              \n            \n            \n              <!-- Local TOC -->\n              <div class=\"local-toc\"><ul>\n<li><a class=\"reference internal\" href=\"#\">Welcome to k-means-constrained’s documentation!</a></li>\n</ul>\n</div>\n            \n          \n        </div>\n        \n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"#\">k-means-constrained</a>\n        \n      </nav>\n\n\n      <div class=\"wy-nav-content\">\n        \n        <div class=\"rst-content\">\n        \n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"#\" class=\"icon icon-home\"></a> &raquo;</li>\n        \n      <li>Welcome to k-means-constrained’s documentation!</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n          \n            <a href=\"_sources/index.rst.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n\n  \n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"welcome-to-k-means-constrained-s-documentation\">\n<h1>Welcome to k-means-constrained’s documentation!<a class=\"headerlink\" href=\"#welcome-to-k-means-constrained-s-documentation\" title=\"Permalink to this headline\">¶</a></h1>\n<p>The GitHub project can be found <a class=\"reference external\" href=\"https://github.com/joshlk/k-means-constrained\">here</a>.</p>\n<p>To install k-means-constrained using pip:</p>\n<div class=\"highlight-python notranslate\"><div class=\"highlight\"><pre><span></span><span class=\"n\">pip</span> <span class=\"n\">install</span> <span class=\"n\">k</span><span class=\"o\">-</span><span class=\"n\">means</span><span class=\"o\">-</span><span class=\"n\">constrained</span>\n</pre></div>\n</div>\n<p>API documentation:</p>\n<span class=\"target\" id=\"module-k_means_constrained\"></span><dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"k_means_constrained.KMeansConstrained\">\n<em class=\"property\"><span class=\"pre\">class</span> </em><span class=\"sig-prename descclassname\"><span class=\"pre\">k_means_constrained.</span></span><span class=\"sig-name descname\"><span class=\"pre\">KMeansConstrained</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">n_clusters</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">8</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">size_min</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">size_max</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">init</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">'k-means++'</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">n_init</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">10</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">max_iter</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">300</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">tol</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">0.0001</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">verbose</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">random_state</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">copy_x</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">True</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">n_jobs</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">1</span></span></em><span class=\"sig-paren\">)</span><a class=\"reference internal\" href=\"_modules/k_means_constrained/k_means_constrained_.html#KMeansConstrained\"><span class=\"viewcode-link\"><span class=\"pre\">[source]</span></span></a><a class=\"headerlink\" href=\"#k_means_constrained.KMeansConstrained\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>K-Means clustering with minimum and maximum cluster size constraints</p>\n<dl class=\"field-list\">\n<dt class=\"field-odd\">Parameters</dt>\n<dd class=\"field-odd\"><dl>\n<dt><strong>n_clusters</strong><span class=\"classifier\">int, optional, default: 8</span></dt><dd><p>The number of clusters to form as well as the number of\ncentroids to generate.</p>\n</dd>\n<dt><strong>size_min</strong><span class=\"classifier\">int, optional, default: None</span></dt><dd><p>Constrain the label assignment so that each cluster has a minimum\nsize of size_min. If None, no constrains will be applied</p>\n</dd>\n<dt><strong>size_max</strong><span class=\"classifier\">int, optional, default: None</span></dt><dd><p>Constrain the label assignment so that each cluster has a maximum\nsize of size_max. If None, no constrains will be applied</p>\n</dd>\n<dt><strong>init</strong><span class=\"classifier\">{‘k-means++’, ‘random’ or an ndarray}</span></dt><dd><p>Method for initialization, defaults to ‘k-means++’:</p>\n<p>‘k-means++’ : selects initial cluster centers for k-mean\nclustering in a smart way to speed up convergence. See section\nNotes in k_init for more details.</p>\n<p>‘random’: choose k observations (rows) at random from data for\nthe initial centroids.</p>\n<p>If an ndarray is passed, it should be of shape (n_clusters, n_features)\nand gives the initial centers.</p>\n</dd>\n<dt><strong>n_init</strong><span class=\"classifier\">int, default: 10</span></dt><dd><p>Number of times the k-means algorithm will be run with different\ncentroid seeds. The final results will be the best output of\nn_init consecutive runs in terms of inertia.</p>\n</dd>\n<dt><strong>max_iter</strong><span class=\"classifier\">int, default: 300</span></dt><dd><p>Maximum number of iterations of the k-means algorithm for a\nsingle run.</p>\n</dd>\n<dt><strong>tol</strong><span class=\"classifier\">float, default: 1e-4</span></dt><dd><p>Relative tolerance with regards to Frobenius norm of the difference\nin the cluster centers of two consecutive iterations to declare\nconvergence.</p>\n</dd>\n<dt><strong>verbose</strong><span class=\"classifier\">int, default 0</span></dt><dd><p>Verbosity mode.</p>\n</dd>\n<dt><strong>random_state</strong><span class=\"classifier\">int, RandomState instance or None, optional, default: None</span></dt><dd><p>If int, random_state is the seed used by the random number generator;\nIf RandomState instance, random_state is the random number generator;\nIf None, the random number generator is the RandomState instance used\nby <cite>np.random</cite>.</p>\n</dd>\n<dt><strong>copy_x</strong><span class=\"classifier\">boolean, default True</span></dt><dd><p>When pre-computing distances it is more numerically accurate to center\nthe data first.  If copy_x is True, then the original data is not\nmodified.  If False, the original data is modified, and put back before\nthe function returns, but small numerical differences may be introduced\nby subtracting and then adding the data mean.</p>\n</dd>\n<dt><strong>n_jobs</strong><span class=\"classifier\">int</span></dt><dd><p>The number of jobs to use for the computation. This works by computing\neach of the n_init runs in parallel.</p>\n<p>If -1 all CPUs are used. If 1 is given, no parallel computing code is\nused at all, which is useful for debugging. For n_jobs below -1,\n(n_cpus + 1 + n_jobs) are used. Thus for n_jobs = -2, all CPUs but one\nare used.</p>\n</dd>\n</dl>\n</dd>\n</dl>\n<p class=\"rubric\">Notes</p>\n<p>K-means problem constrained with a minimum and/or maximum size for each cluster.</p>\n<p>The constrained assignment is formulated as a Minimum Cost Flow (MCF) linear network optimisation\nproblem. This is then solved using a cost-scaling push-relabel algorithm. The implementation used is</p>\n<blockquote>\n<div><p>Google’s Operations Research tools’s <cite>SimpleMinCostFlow</cite>.</p>\n</div></blockquote>\n<p>Ref:\n1. Bradley, P. S., K. P. Bennett, and Ayhan Demiriz. “Constrained k-means clustering.”</p>\n<blockquote>\n<div><p>Microsoft Research, Redmond (2000): 1-8.</p>\n</div></blockquote>\n<ol class=\"arabic simple\" start=\"2\">\n<li><dl class=\"simple\">\n<dt>Google’s SimpleMinCostFlow implementation:</dt><dd><p><a class=\"reference external\" href=\"https://github.com/google/or-tools/blob/master/ortools/graph/min_cost_flow.h\">https://github.com/google/or-tools/blob/master/ortools/graph/min_cost_flow.h</a></p>\n</dd>\n</dl>\n</li>\n</ol>\n<p class=\"rubric\">Examples</p>\n<div class=\"doctest highlight-default notranslate\"><div class=\"highlight\"><pre><span></span><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">k_means_constrained</span> <span class=\"kn\">import</span> <span class=\"n\">KMeansConstrained</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">import</span> <span class=\"nn\">numpy</span> <span class=\"k\">as</span> <span class=\"nn\">np</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">X</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">4</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">],</span>\n<span class=\"gp\">... </span>               <span class=\"p\">[</span><span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"mi\">4</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">]])</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">clf</span> <span class=\"o\">=</span> <span class=\"n\">KMeansConstrained</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">n_clusters</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"n\">size_min</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"n\">size_max</span><span class=\"o\">=</span><span class=\"mi\">5</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"n\">random_state</span><span class=\"o\">=</span><span class=\"mi\">0</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">clf</span><span class=\"o\">.</span><span class=\"n\">fit_predict</span><span class=\"p\">(</span><span class=\"n\">X</span><span class=\"p\">)</span>\n<span class=\"go\">array([0, 0, 0, 1, 1, 1], dtype=int32)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">clf</span><span class=\"o\">.</span><span class=\"n\">cluster_centers_</span>\n<span class=\"go\">array([[ 1.,  2.],</span>\n<span class=\"go\">       [ 4.,  2.]])</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">clf</span><span class=\"o\">.</span><span class=\"n\">labels_</span>\n<span class=\"go\">array([0, 0, 0, 1, 1, 1], dtype=int32)</span>\n</pre></div>\n</div>\n<dl class=\"field-list simple\">\n<dt class=\"field-odd\">Attributes</dt>\n<dd class=\"field-odd\"><dl class=\"simple\">\n<dt><strong>cluster_centers_</strong><span class=\"classifier\">array, [n_clusters, n_features]</span></dt><dd><p>Coordinates of cluster centers</p>\n</dd>\n<dt><strong>labels_ :</strong></dt><dd><p>Labels of each point</p>\n</dd>\n<dt><strong>inertia_</strong><span class=\"classifier\">float</span></dt><dd><p>Sum of squared distances of samples to their closest cluster center.</p>\n</dd>\n</dl>\n</dd>\n</dl>\n<p class=\"rubric\">Methods</p>\n<table class=\"longtable docutils align-default\">\n<colgroup>\n<col style=\"width: 10%\" />\n<col style=\"width: 90%\" />\n</colgroup>\n<tbody>\n<tr class=\"row-odd\"><td><p><a class=\"reference internal\" href=\"#k_means_constrained.KMeansConstrained.fit\" title=\"k_means_constrained.KMeansConstrained.fit\"><code class=\"xref py py-obj docutils literal notranslate\"><span class=\"pre\">fit</span></code></a>(X[, y])</p></td>\n<td><p>Compute k-means clustering with given constants.</p></td>\n</tr>\n<tr class=\"row-even\"><td><p><a class=\"reference internal\" href=\"#k_means_constrained.KMeansConstrained.fit_predict\" title=\"k_means_constrained.KMeansConstrained.fit_predict\"><code class=\"xref py py-obj docutils literal notranslate\"><span class=\"pre\">fit_predict</span></code></a>(X[, y])</p></td>\n<td><p>Compute cluster centers and predict cluster index for each sample.</p></td>\n</tr>\n<tr class=\"row-odd\"><td><p><a class=\"reference internal\" href=\"#k_means_constrained.KMeansConstrained.fit_transform\" title=\"k_means_constrained.KMeansConstrained.fit_transform\"><code class=\"xref py py-obj docutils literal notranslate\"><span class=\"pre\">fit_transform</span></code></a>(X[, y])</p></td>\n<td><p>Compute clustering and transform X to cluster-distance space.</p></td>\n</tr>\n<tr class=\"row-even\"><td><p><a class=\"reference internal\" href=\"#k_means_constrained.KMeansConstrained.get_params\" title=\"k_means_constrained.KMeansConstrained.get_params\"><code class=\"xref py py-obj docutils literal notranslate\"><span class=\"pre\">get_params</span></code></a>([deep])</p></td>\n<td><p>Get parameters for this estimator.</p></td>\n</tr>\n<tr class=\"row-odd\"><td><p><a class=\"reference internal\" href=\"#k_means_constrained.KMeansConstrained.predict\" title=\"k_means_constrained.KMeansConstrained.predict\"><code class=\"xref py py-obj docutils literal notranslate\"><span class=\"pre\">predict</span></code></a>(X[, size_min, size_max])</p></td>\n<td><p>Predict the closest cluster each sample in X belongs to given the provided constraints.</p></td>\n</tr>\n<tr class=\"row-even\"><td><p><a class=\"reference internal\" href=\"#k_means_constrained.KMeansConstrained.score\" title=\"k_means_constrained.KMeansConstrained.score\"><code class=\"xref py py-obj docutils literal notranslate\"><span class=\"pre\">score</span></code></a>(X[, y])</p></td>\n<td><p>Opposite of the value of X on the K-means objective.</p></td>\n</tr>\n<tr class=\"row-odd\"><td><p><a class=\"reference internal\" href=\"#k_means_constrained.KMeansConstrained.set_params\" title=\"k_means_constrained.KMeansConstrained.set_params\"><code class=\"xref py py-obj docutils literal notranslate\"><span class=\"pre\">set_params</span></code></a>(**params)</p></td>\n<td><p>Set the parameters of this estimator.</p></td>\n</tr>\n<tr class=\"row-even\"><td><p><a class=\"reference internal\" href=\"#k_means_constrained.KMeansConstrained.transform\" title=\"k_means_constrained.KMeansConstrained.transform\"><code class=\"xref py py-obj docutils literal notranslate\"><span class=\"pre\">transform</span></code></a>(X)</p></td>\n<td><p>Transform X to a cluster-distance space.</p></td>\n</tr>\n</tbody>\n</table>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"k_means_constrained.KMeansConstrained.fit\">\n<span class=\"sig-name descname\"><span class=\"pre\">fit</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">X</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">y</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"reference internal\" href=\"_modules/k_means_constrained/k_means_constrained_.html#KMeansConstrained.fit\"><span class=\"viewcode-link\"><span class=\"pre\">[source]</span></span></a><a class=\"headerlink\" href=\"#k_means_constrained.KMeansConstrained.fit\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Compute k-means clustering with given constants.</p>\n<dl class=\"field-list simple\">\n<dt class=\"field-odd\">Parameters</dt>\n<dd class=\"field-odd\"><dl class=\"simple\">\n<dt><strong>X</strong><span class=\"classifier\">array-like, shape=(n_samples, n_features)</span></dt><dd><p>Training instances to cluster.</p>\n</dd>\n<dt><strong>y</strong><span class=\"classifier\">Ignored</span></dt><dd></dd>\n</dl>\n</dd>\n</dl>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"k_means_constrained.KMeansConstrained.predict\">\n<span class=\"sig-name descname\"><span class=\"pre\">predict</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">X</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">size_min</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">'init'</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">size_max</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">'init'</span></span></em><span class=\"sig-paren\">)</span><a class=\"reference internal\" href=\"_modules/k_means_constrained/k_means_constrained_.html#KMeansConstrained.predict\"><span class=\"viewcode-link\"><span class=\"pre\">[source]</span></span></a><a class=\"headerlink\" href=\"#k_means_constrained.KMeansConstrained.predict\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Predict the closest cluster each sample in X belongs to given the provided constraints.\nThe constraints can be temporally overridden when determining which cluster each datapoint is assigned to.</p>\n<p>Only computes the assignment step. It does not re-fit the cluster positions.</p>\n<dl class=\"field-list simple\">\n<dt class=\"field-odd\">Parameters</dt>\n<dd class=\"field-odd\"><dl class=\"simple\">\n<dt><strong>X</strong><span class=\"classifier\">array-like, shape = [n_samples, n_features]</span></dt><dd><p>New data to predict.</p>\n</dd>\n<dt><strong>size_min</strong><span class=\"classifier\">int, optional, default: size_min provided with initialisation</span></dt><dd><p>Constrain the label assignment so that each cluster has a minimum\nsize of size_min. If None, no constrains will be applied.\nIf ‘init’ the value provided during initialisation of the\nclass will be used.</p>\n</dd>\n<dt><strong>size_max</strong><span class=\"classifier\">int, optional, default: size_max provided with initialisation</span></dt><dd><p>Constrain the label assignment so that each cluster has a maximum\nsize of size_max. If None, no constrains will be applied.\nIf ‘init’ the value provided during initialisation of the\nclass will be used.</p>\n</dd>\n</dl>\n</dd>\n<dt class=\"field-even\">Returns</dt>\n<dd class=\"field-even\"><dl class=\"simple\">\n<dt><strong>labels</strong><span class=\"classifier\">array, shape [n_samples,]</span></dt><dd><p>Index of the cluster each sample belongs to.</p>\n</dd>\n</dl>\n</dd>\n</dl>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"k_means_constrained.KMeansConstrained.fit_predict\">\n<span class=\"sig-name descname\"><span class=\"pre\">fit_predict</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">X</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">y</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"reference internal\" href=\"_modules/k_means_constrained/k_means_constrained_.html#KMeansConstrained.fit_predict\"><span class=\"viewcode-link\"><span class=\"pre\">[source]</span></span></a><a class=\"headerlink\" href=\"#k_means_constrained.KMeansConstrained.fit_predict\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Compute cluster centers and predict cluster index for each sample.</p>\n<p>Equivalent to calling fit(X) followed by predict(X) but also more efficient.</p>\n<dl class=\"field-list simple\">\n<dt class=\"field-odd\">Parameters</dt>\n<dd class=\"field-odd\"><dl class=\"simple\">\n<dt><strong>X</strong><span class=\"classifier\">{array-like, sparse matrix}, shape = [n_samples, n_features]</span></dt><dd><p>New data to transform.</p>\n</dd>\n</dl>\n</dd>\n<dt class=\"field-even\">Returns</dt>\n<dd class=\"field-even\"><dl class=\"simple\">\n<dt><strong>labels</strong><span class=\"classifier\">array, shape [n_samples,]</span></dt><dd><p>Index of the cluster each sample belongs to.</p>\n</dd>\n</dl>\n</dd>\n</dl>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"k_means_constrained.KMeansConstrained.fit_transform\">\n<span class=\"sig-name descname\"><span class=\"pre\">fit_transform</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">X</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">y</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#k_means_constrained.KMeansConstrained.fit_transform\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Compute clustering and transform X to cluster-distance space.</p>\n<p>Equivalent to fit(X).transform(X), but more efficiently implemented.</p>\n<dl class=\"field-list simple\">\n<dt class=\"field-odd\">Parameters</dt>\n<dd class=\"field-odd\"><dl class=\"simple\">\n<dt><strong>X</strong><span class=\"classifier\">{array-like, sparse matrix}, shape = [n_samples, n_features]</span></dt><dd><p>New data to transform.</p>\n</dd>\n</dl>\n</dd>\n<dt class=\"field-even\">Returns</dt>\n<dd class=\"field-even\"><dl class=\"simple\">\n<dt><strong>X_new</strong><span class=\"classifier\">array, shape [n_samples, k]</span></dt><dd><p>X transformed in the new space.</p>\n</dd>\n</dl>\n</dd>\n</dl>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"k_means_constrained.KMeansConstrained.get_params\">\n<span class=\"sig-name descname\"><span class=\"pre\">get_params</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">deep</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">True</span></span></em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#k_means_constrained.KMeansConstrained.get_params\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Get parameters for this estimator.</p>\n<dl class=\"field-list simple\">\n<dt class=\"field-odd\">Parameters</dt>\n<dd class=\"field-odd\"><dl class=\"simple\">\n<dt><strong>deep</strong><span class=\"classifier\">boolean, optional</span></dt><dd><p>If True, will return the parameters for this estimator and\ncontained subobjects that are estimators.</p>\n</dd>\n</dl>\n</dd>\n<dt class=\"field-even\">Returns</dt>\n<dd class=\"field-even\"><dl class=\"simple\">\n<dt><strong>params</strong><span class=\"classifier\">mapping of string to any</span></dt><dd><p>Parameter names mapped to their values.</p>\n</dd>\n</dl>\n</dd>\n</dl>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"k_means_constrained.KMeansConstrained.score\">\n<span class=\"sig-name descname\"><span class=\"pre\">score</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">X</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">y</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#k_means_constrained.KMeansConstrained.score\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Opposite of the value of X on the K-means objective.</p>\n<dl class=\"field-list simple\">\n<dt class=\"field-odd\">Parameters</dt>\n<dd class=\"field-odd\"><dl class=\"simple\">\n<dt><strong>X</strong><span class=\"classifier\">{array-like, sparse matrix}, shape = [n_samples, n_features]</span></dt><dd><p>New data.</p>\n</dd>\n</dl>\n</dd>\n<dt class=\"field-even\">Returns</dt>\n<dd class=\"field-even\"><dl class=\"simple\">\n<dt><strong>score</strong><span class=\"classifier\">float</span></dt><dd><p>Opposite of the value of X on the K-means objective.</p>\n</dd>\n</dl>\n</dd>\n</dl>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"k_means_constrained.KMeansConstrained.set_params\">\n<span class=\"sig-name descname\"><span class=\"pre\">set_params</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">params</span></span></em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#k_means_constrained.KMeansConstrained.set_params\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Set the parameters of this estimator.</p>\n<p>The method works on simple estimators as well as on nested objects\n(such as pipelines). The latter have parameters of the form\n<code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;component&gt;__&lt;parameter&gt;</span></code> so that it’s possible to update each\ncomponent of a nested object.</p>\n<dl class=\"field-list simple\">\n<dt class=\"field-odd\">Returns</dt>\n<dd class=\"field-odd\"><dl class=\"simple\">\n<dt>self</dt><dd></dd>\n</dl>\n</dd>\n</dl>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"k_means_constrained.KMeansConstrained.transform\">\n<span class=\"sig-name descname\"><span class=\"pre\">transform</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">X</span></span></em><span class=\"sig-paren\">)</span><a class=\"headerlink\" href=\"#k_means_constrained.KMeansConstrained.transform\" title=\"Permalink to this definition\">¶</a></dt>\n<dd><p>Transform X to a cluster-distance space.</p>\n<p>In the new space, each dimension is the distance to the cluster\ncenters.  Note that even if X is sparse, the array returned by\n<cite>transform</cite> will typically be dense.</p>\n<dl class=\"field-list simple\">\n<dt class=\"field-odd\">Parameters</dt>\n<dd class=\"field-odd\"><dl class=\"simple\">\n<dt><strong>X</strong><span class=\"classifier\">{array-like, sparse matrix}, shape = [n_samples, n_features]</span></dt><dd><p>New data to transform.</p>\n</dd>\n</dl>\n</dd>\n<dt class=\"field-even\">Returns</dt>\n<dd class=\"field-even\"><dl class=\"simple\">\n<dt><strong>X_new</strong><span class=\"classifier\">array, shape [n_samples, k]</span></dt><dd><p>X transformed in the new space.</p>\n</dd>\n</dl>\n</dd>\n</dl>\n</dd></dl>\n\n</dd></dl>\n\n</div>\n\n\n           </div>\n           \n          </div>\n          <footer>\n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &#169; Copyright 2020, Josh Levy-Kramer. Documentation derived from Scikit-Learn.\n\n    </p>\n  </div>\n    \n    \n    \n    Built with <a href=\"https://www.sphinx-doc.org/\">Sphinx</a> using a\n    \n    <a href=\"https://github.com/readthedocs/sphinx_rtd_theme\">theme</a>\n    \n    provided by <a href=\"https://readthedocs.org\">Read the Docs</a>. \n\n</footer>\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.Navigation.enable(true);\n      });\n  </script>\n\n  \n  \n    \n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/modules.html",
    "content": "\n\n<!DOCTYPE html>\n<html class=\"writer-html5\" lang=\"en\" >\n<head>\n  <meta charset=\"utf-8\">\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  \n  <title>k_means_constrained &mdash; k-means-constrained 0.0.2 documentation</title>\n  \n\n  \n  <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  <link rel=\"stylesheet\" href=\"_static/pygments.css\" type=\"text/css\" />\n\n  \n  \n  \n  \n\n  \n  <!--[if lt IE 9]>\n    <script src=\"_static/js/html5shiv.min.js\"></script>\n  <![endif]-->\n  \n    \n      <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"./\" src=\"_static/documentation_options.js\"></script>\n        <script src=\"_static/jquery.js\"></script>\n        <script src=\"_static/underscore.js\"></script>\n        <script src=\"_static/doctools.js\"></script>\n        <script src=\"_static/language_data.js\"></script>\n    \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n\n    \n    <link rel=\"index\" title=\"Index\" href=\"genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"search.html\" /> \n</head>\n\n<body class=\"wy-body-for-nav\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\" >\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\" alt=\"Documentation Home\"> k-means-constrained\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        \n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n              \n            \n            \n              <!-- Local TOC -->\n              <div class=\"local-toc\"><ul>\n<li><a class=\"reference internal\" href=\"#\">k_means_constrained</a></li>\n</ul>\n</div>\n            \n          \n        </div>\n        \n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">k-means-constrained</a>\n        \n      </nav>\n\n\n      <div class=\"wy-nav-content\">\n        \n        <div class=\"rst-content\">\n        \n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\" class=\"icon icon-home\"></a> &raquo;</li>\n        \n      <li>k_means_constrained</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n            \n            <a href=\"_sources/modules.rst.txt\" rel=\"nofollow\"> View page source</a>\n          \n        \n      </li>\n    \n  </ul>\n\n  \n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <div class=\"section\" id=\"k-means-constrained\">\n<h1>k_means_constrained<a class=\"headerlink\" href=\"#k-means-constrained\" title=\"Permalink to this headline\">¶</a></h1>\n<div class=\"toctree-wrapper compound\">\n</div>\n</div>\n\n\n           </div>\n           \n          </div>\n          <footer>\n  \n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        \n        &copy; Copyright 2020, Josh Levy-Kramer\n\n    </p>\n  </div>\n    \n    \n    \n    Built with <a href=\"http://sphinx-doc.org/\">Sphinx</a> using a\n    \n    <a href=\"https://github.com/rtfd/sphinx_rtd_theme\">theme</a>\n    \n    provided by <a href=\"https://readthedocs.org\">Read the Docs</a>. \n\n</footer>\n\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.Navigation.enable(true);\n      });\n  </script>\n\n  \n  \n    \n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/objects.inv",
    "content": "# Sphinx inventory version 2\n# Project: k-means-constrained\n# Version: \n# The remainder of this file is compressed using zlib.\nxڭKj0\u0010:Ŕt+n@ .*Mla=Fzkz=IeP6\r-\nGb\u0010ڡ~ZN\u0006\u0001S^њM=ptU/Qz*9\b\"xcnWG\u001d^0^-}@J\u0014;:`\u001aL ,-g6#I\u001fp\u0005̊{WC\u0005+A7\u001af\u0004]ԉ\u0005cȾ)/jFz\u0010=t|*g?\u001f\u0004t袈ڻ;>䕺/\f応;e퇴gW\tEmiZ\u001cr~/\u001ad_\u0018h"
  },
  {
    "path": "docs/py-modindex.html",
    "content": "\n\n<!DOCTYPE html>\n<html class=\"writer-html5\" lang=\"en\" >\n<head>\n  <meta charset=\"utf-8\" />\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n  \n  <title>Python Module Index &mdash; k-means-constrained 0.5.1 documentation</title>\n  \n\n  \n  <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  <link rel=\"stylesheet\" href=\"_static/pygments.css\" type=\"text/css\" />\n  <link rel=\"stylesheet\" href=\"_static/pygments.css\" type=\"text/css\" />\n  <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n\n  \n  \n\n  \n  \n\n  \n\n  \n  <!--[if lt IE 9]>\n    <script src=\"_static/js/html5shiv.min.js\"></script>\n  <![endif]-->\n  \n    \n      <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"./\" src=\"_static/documentation_options.js\"></script>\n        <script data-url_root=\"./\" id=\"documentation_options\" src=\"_static/documentation_options.js\"></script>\n        <script src=\"_static/jquery.js\"></script>\n        <script src=\"_static/underscore.js\"></script>\n        <script src=\"_static/doctools.js\"></script>\n    \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n\n    \n    <link rel=\"index\" title=\"Index\" href=\"genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"search.html\" />\n \n\n    <script>\n      DOCUMENTATION_OPTIONS.COLLAPSE_INDEX = true;\n    </script>\n\n\n</head>\n\n<body class=\"wy-body-for-nav\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\" >\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> k-means-constrained\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"search.html\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        \n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n              \n            \n            \n              <!-- Local TOC -->\n              <div class=\"local-toc\"></div>\n            \n          \n        </div>\n        \n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">k-means-constrained</a>\n        \n      </nav>\n\n\n      <div class=\"wy-nav-content\">\n        \n        <div class=\"rst-content\">\n        \n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\" class=\"icon icon-home\"></a> &raquo;</li>\n        \n      <li>Python Module Index</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n      </li>\n    \n  </ul>\n\n  \n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n\n   <h1>Python Module Index</h1>\n\n   <div class=\"modindex-jumpbox\">\n   <a href=\"#cap-k\"><strong>k</strong></a>\n   </div>\n\n   <table class=\"indextable modindextable\">\n     <tr class=\"pcap\"><td></td><td>&#160;</td><td></td></tr>\n     <tr class=\"cap\" id=\"cap-k\"><td></td><td>\n       <strong>k</strong></td><td></td></tr>\n     <tr>\n       <td></td>\n       <td>\n       <a href=\"index.html#module-k_means_constrained\"><code class=\"xref\">k_means_constrained</code></a></td><td>\n       <em></em></td></tr>\n   </table>\n\n\n           </div>\n           \n          </div>\n          <footer>\n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &#169; Copyright 2020, Josh Levy-Kramer. Documentation derived from Scikit-Learn.\n\n    </p>\n  </div>\n    \n    \n    \n    Built with <a href=\"https://www.sphinx-doc.org/\">Sphinx</a> using a\n    \n    <a href=\"https://github.com/readthedocs/sphinx_rtd_theme\">theme</a>\n    \n    provided by <a href=\"https://readthedocs.org\">Read the Docs</a>. \n\n</footer>\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.Navigation.enable(true);\n      });\n  </script>\n\n  \n  \n    \n   \n\n</body>\n</html>"
  },
  {
    "path": "docs/search.html",
    "content": "\n\n<!DOCTYPE html>\n<html class=\"writer-html5\" lang=\"en\" >\n<head>\n  <meta charset=\"utf-8\" />\n  \n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n  \n  <title>Search &mdash; k-means-constrained 0.5.1 documentation</title>\n  \n\n  \n  <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n  <link rel=\"stylesheet\" href=\"_static/pygments.css\" type=\"text/css\" />\n  <link rel=\"stylesheet\" href=\"_static/pygments.css\" type=\"text/css\" />\n  <link rel=\"stylesheet\" href=\"_static/css/theme.css\" type=\"text/css\" />\n\n  \n  \n\n  \n  \n\n  \n\n  \n    \n  <!--[if lt IE 9]>\n    <script src=\"_static/js/html5shiv.min.js\"></script>\n  <![endif]-->\n  \n    \n      <script type=\"text/javascript\" id=\"documentation_options\" data-url_root=\"./\" src=\"_static/documentation_options.js\"></script>\n        <script data-url_root=\"./\" id=\"documentation_options\" src=\"_static/documentation_options.js\"></script>\n        <script src=\"_static/jquery.js\"></script>\n        <script src=\"_static/underscore.js\"></script>\n        <script src=\"_static/doctools.js\"></script>\n    \n    <script type=\"text/javascript\" src=\"_static/js/theme.js\"></script>\n\n    \n    <script type=\"text/javascript\" src=\"_static/searchtools.js\"></script>\n    <script type=\"text/javascript\" src=\"_static/language_data.js\"></script>\n    <link rel=\"index\" title=\"Index\" href=\"genindex.html\" />\n    <link rel=\"search\" title=\"Search\" href=\"#\" /> \n</head>\n\n<body class=\"wy-body-for-nav\">\n\n   \n  <div class=\"wy-grid-for-nav\">\n    \n    <nav data-toggle=\"wy-nav-shift\" class=\"wy-nav-side\">\n      <div class=\"wy-side-scroll\">\n        <div class=\"wy-side-nav-search\" >\n          \n\n          \n            <a href=\"index.html\" class=\"icon icon-home\"> k-means-constrained\n          \n\n          \n          </a>\n\n          \n            \n            \n          \n\n          \n<div role=\"search\">\n  <form id=\"rtd-search-form\" class=\"wy-form\" action=\"#\" method=\"get\">\n    <input type=\"text\" name=\"q\" placeholder=\"Search docs\" />\n    <input type=\"hidden\" name=\"check_keywords\" value=\"yes\" />\n    <input type=\"hidden\" name=\"area\" value=\"default\" />\n  </form>\n</div>\n\n          \n        </div>\n\n        \n        <div class=\"wy-menu wy-menu-vertical\" data-spy=\"affix\" role=\"navigation\" aria-label=\"main navigation\">\n          \n            \n            \n              \n            \n            \n              <!-- Local TOC -->\n              <div class=\"local-toc\"></div>\n            \n          \n        </div>\n        \n      </div>\n    </nav>\n\n    <section data-toggle=\"wy-nav-shift\" class=\"wy-nav-content-wrap\">\n\n      \n      <nav class=\"wy-nav-top\" aria-label=\"top navigation\">\n        \n          <i data-toggle=\"wy-nav-top\" class=\"fa fa-bars\"></i>\n          <a href=\"index.html\">k-means-constrained</a>\n        \n      </nav>\n\n\n      <div class=\"wy-nav-content\">\n        \n        <div class=\"rst-content\">\n        \n          \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<div role=\"navigation\" aria-label=\"breadcrumbs navigation\">\n\n  <ul class=\"wy-breadcrumbs\">\n    \n      <li><a href=\"index.html\" class=\"icon icon-home\"></a> &raquo;</li>\n        \n      <li>Search</li>\n    \n    \n      <li class=\"wy-breadcrumbs-aside\">\n        \n      </li>\n    \n  </ul>\n\n  \n  <hr/>\n</div>\n          <div role=\"main\" class=\"document\" itemscope=\"itemscope\" itemtype=\"http://schema.org/Article\">\n           <div itemprop=\"articleBody\">\n            \n  <noscript>\n  <div id=\"fallback\" class=\"admonition warning\">\n    <p class=\"last\">\n      Please activate JavaScript to enable the search functionality.\n    </p>\n  </div>\n  </noscript>\n\n  \n  <div id=\"search-results\">\n  \n  </div>\n\n           </div>\n           \n          </div>\n          <footer>\n\n  <hr/>\n\n  <div role=\"contentinfo\">\n    <p>\n        &#169; Copyright 2020, Josh Levy-Kramer. Documentation derived from Scikit-Learn.\n\n    </p>\n  </div>\n    \n    \n    \n    Built with <a href=\"https://www.sphinx-doc.org/\">Sphinx</a> using a\n    \n    <a href=\"https://github.com/readthedocs/sphinx_rtd_theme\">theme</a>\n    \n    provided by <a href=\"https://readthedocs.org\">Read the Docs</a>. \n\n</footer>\n        </div>\n      </div>\n\n    </section>\n\n  </div>\n  \n\n  <script type=\"text/javascript\">\n      jQuery(function () {\n          SphinxRtdTheme.Navigation.enable(true);\n      });\n  </script>\n\n  \n  \n    \n  \n  <script type=\"text/javascript\">\n    jQuery(function() { Search.loadIndex(\"searchindex.js\"); });\n  </script>\n  \n  <script type=\"text/javascript\" id=\"searchindexloader\"></script>\n   \n\n\n</body>\n</html>"
  },
  {
    "path": "docs/searchindex.js",
    "content": "Search.setIndex({docnames:[\"index\"],envversion:{\"sphinx.domains.c\":2,\"sphinx.domains.changeset\":1,\"sphinx.domains.citation\":1,\"sphinx.domains.cpp\":3,\"sphinx.domains.index\":1,\"sphinx.domains.javascript\":2,\"sphinx.domains.math\":2,\"sphinx.domains.python\":3,\"sphinx.domains.rst\":2,\"sphinx.domains.std\":2,\"sphinx.ext.viewcode\":1,sphinx:56},filenames:[\"index.rst\"],objects:{\"\":{k_means_constrained:[0,0,0,\"-\"]},\"k_means_constrained.KMeansConstrained\":{fit:[0,2,1,\"\"],fit_predict:[0,2,1,\"\"],fit_transform:[0,2,1,\"\"],get_params:[0,2,1,\"\"],predict:[0,2,1,\"\"],score:[0,2,1,\"\"],set_params:[0,2,1,\"\"],transform:[0,2,1,\"\"]},k_means_constrained:{KMeansConstrained:[0,1,1,\"\"]}},objnames:{\"0\":[\"py\",\"module\",\"Python module\"],\"1\":[\"py\",\"class\",\"Python class\"],\"2\":[\"py\",\"method\",\"Python method\"]},objtypes:{\"0\":\"py:module\",\"1\":\"py:class\",\"2\":\"py:method\"},terms:{\"0\":0,\"0001\":0,\"1\":0,\"10\":0,\"1e\":0,\"2\":0,\"2000\":0,\"300\":0,\"4\":0,\"5\":0,\"8\":0,\"boolean\":0,\"class\":0,\"default\":0,\"final\":0,\"float\":0,\"function\":0,\"import\":0,\"int\":0,\"new\":0,\"return\":0,\"true\":0,For:0,If:0,In:0,It:0,The:0,To:0,__:0,accur:0,ad:0,algorithm:0,all:0,also:0,an:0,ani:0,api:0,appli:0,ar:0,arrai:0,assign:0,attribut:0,ayhan:0,back:0,befor:0,belong:0,below:0,bennett:0,best:0,blob:0,bradlei:0,call:0,can:0,center:0,centroid:0,choos:0,clf:0,closest:0,cluster:0,cluster_centers_:0,code:0,com:0,compon:0,comput:0,consecut:0,constant:0,constraint:0,contain:0,converg:0,coordin:0,copy_x:0,cost:0,cpu:0,data:0,datapoint:0,debug:0,declar:0,deep:0,demiriz:0,dens:0,detail:0,determin:0,differ:0,dimens:0,distanc:0,doe:0,dtype:0,dure:0,each:0,effici:0,equival:0,estim:0,even:0,exampl:0,fals:0,first:0,fit:0,fit_predict:0,fit_transform:0,flow:0,follow:0,form:0,formul:0,found:0,frobeniu:0,from:0,gener:0,get:0,get_param:0,github:0,give:0,given:0,googl:0,graph:0,h:0,ha:0,have:0,here:0,http:0,ignor:0,implement:0,index:0,inertia:0,inertia_:0,init:0,initi:0,initialis:0,instal:0,instanc:0,int32:0,introduc:0,iter:0,job:0,k_init:0,k_means_constrain:0,kmeansconstrain:0,label:0,labels_:0,latter:0,like:0,linear:0,mai:0,map:0,master:0,matrix:0,max_it:0,maximum:0,mcf:0,method:0,microsoft:0,min_cost_flow:0,minimum:0,mode:0,modifi:0,more:0,n_cluster:0,n_cpu:0,n_featur:0,n_init:0,n_job:0,n_sampl:0,name:0,ndarrai:0,nest:0,network:0,none:0,norm:0,note:0,np:0,number:0,numer:0,numpi:0,object:0,observ:0,one:0,onli:0,oper:0,opposit:0,optimis:0,option:0,origin:0,ortool:0,output:0,overridden:0,p:0,parallel:0,param:0,paramet:0,pass:0,pip:0,pipelin:0,point:0,posit:0,possibl:0,pre:0,predict:0,problem:0,project:0,provid:0,push:0,put:0,random:0,random_st:0,randomst:0,re:0,redmond:0,ref:0,regard:0,rel:0,relabel:0,research:0,result:0,row:0,run:0,sampl:0,scale:0,score:0,section:0,see:0,seed:0,select:0,self:0,set:0,set_param:0,shape:0,should:0,simpl:0,simplemincostflow:0,singl:0,size:0,size_max:0,size_min:0,small:0,smart:0,so:0,solv:0,sourc:0,space:0,spars:0,speed:0,squar:0,step:0,string:0,subobject:0,subtract:0,sum:0,tempor:0,term:0,thi:0,thu:0,time:0,tol:0,toler:0,tool:0,train:0,transform:0,two:0,typic:0,up:0,updat:0,us:0,valu:0,verbos:0,wai:0,well:0,when:0,which:0,work:0,x:0,x_new:0,y:0},titles:[\"Welcome to k-means-constrained\\u2019s documentation!\"],titleterms:{constrain:0,document:0,k:0,mean:0,s:0,welcom:0}})"
  },
  {
    "path": "docs_source/Makefile",
    "content": "# Minimal makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line, and also\n# from the environment for the first two.\nSPHINXOPTS    ?=\nSPHINXBUILD   ?= sphinx-build\nSOURCEDIR     = .\nBUILDDIR      = _build\n\n# Put it first so that \"make\" without argument is like \"make help\".\nhelp:\n\t@$(SPHINXBUILD) -M help \"$(SOURCEDIR)\" \"$(BUILDDIR)\" $(SPHINXOPTS) $(O)\n\n.PHONY: help Makefile\n\n# Catch-all target: route all unknown targets to Sphinx using the new\n# \"make mode\" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).\n%: Makefile\n\t@$(SPHINXBUILD) -M $@ \"$(SOURCEDIR)\" \"$(BUILDDIR)\" $(SPHINXOPTS) $(O)\n"
  },
  {
    "path": "docs_source/README.md",
    "content": "Build docs:\n```\nmake html\nmv _build/html ../docs\ntocuh ../docs/.nojekyll\n``"
  },
  {
    "path": "docs_source/conf.py",
    "content": "# Configuration file for the Sphinx documentation builder.\n#\n# This file only contains a selection of the most common options. For a full\n# list see the documentation:\n# https://www.sphinx-doc.org/en/master/usage/configuration.html\n\n# -- Path setup --------------------------------------------------------------\n\n# If extensions (or modules to document with autodoc) are in another directory,\n# add these directories to sys.path here. If the directory is relative to the\n# documentation root, use os.path.abspath to make it absolute, like shown here.\n#\nimport os\nimport sys\nsys.path.insert(0, os.path.abspath('../'))\nimport sphinx_rtd_theme\n\n\n# -- Project information -----------------------------------------------------\n\nproject = 'k-means-constrained'\ncopyright = '2020, Josh Levy-Kramer. Documentation derived from Scikit-Learn'\nauthor = 'Josh Levy-Kramer'\n\n# The full version, including alpha/beta/rc tags\nrelease = '0.5.1'\n\n\n# -- General configuration ---------------------------------------------------\n\n# Add any Sphinx extension module names here, as strings. They can be\n# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom\n# ones.\nextensions = [\n    'sphinx.ext.autodoc','sphinx.ext.viewcode',\n    \"sphinx_rtd_theme\",\n    \"numpydoc\",\n]\n\n# Include Python objects as they appear in source files\n# Default: alphabetically ('alphabetical')\nautodoc_member_order = 'bysource'\n# Default flags used by autodoc directives\nautodoc_default_flags = ['members', 'show-inheritance']\n\n# Add any paths that contain templates here, relative to this directory.\ntemplates_path = ['_templates']\n\n# List of patterns, relative to source directory, that match files and\n# directories to ignore when looking for source files.\n# This pattern also affects html_static_path and html_extra_path.\nexclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']\n\n\n# -- Options for HTML output -------------------------------------------------\n\n# The theme to use for HTML and HTML Help pages.  See the documentation for\n# a list of builtin themes.\n#\nhtml_theme = 'sphinx_rtd_theme' #'alabaster'\n\n# Add any paths that contain custom static files (such as style sheets) here,\n# relative to this directory. They are copied after the builtin static files,\n# so a file named \"default.css\" will overwrite the builtin \"default.css\".\nhtml_static_path = ['_static']"
  },
  {
    "path": "docs_source/index.rst",
    "content": ".. k-means-constrained documentation master file, created by\n   sphinx-quickstart on Fri Mar  6 13:31:12 2020.\n   You can adapt this file completely to your liking, but it should at least\n   contain the root `toctree` directive.\n\nWelcome to k-means-constrained's documentation!\n===============================================\n\nThe GitHub project can be found `here <https://github.com/joshlk/k-means-constrained>`_.\n\nTo install k-means-constrained using pip:\n\n.. code-block:: python\n\n   pip install k-means-constrained\n\n\nAPI documentation:\n\n\n.. automodule:: k_means_constrained\n   :members:\n   :undoc-members:\n   :inherited-members:\n\n\n\n\n\n"
  },
  {
    "path": "docs_source/make.bat",
    "content": "@ECHO OFF\r\n\r\npushd %~dp0\r\n\r\nREM Command file for Sphinx documentation\r\n\r\nif \"%SPHINXBUILD%\" == \"\" (\r\n\tset SPHINXBUILD=sphinx-build\r\n)\r\nset SOURCEDIR=.\r\nset BUILDDIR=_build\r\n\r\nif \"%1\" == \"\" goto help\r\n\r\n%SPHINXBUILD% >NUL 2>NUL\r\nif errorlevel 9009 (\r\n\techo.\r\n\techo.The 'sphinx-build' command was not found. Make sure you have Sphinx\r\n\techo.installed, then set the SPHINXBUILD environment variable to point\r\n\techo.to the full path of the 'sphinx-build' executable. Alternatively you\r\n\techo.may add the Sphinx directory to PATH.\r\n\techo.\r\n\techo.If you don't have Sphinx installed, grab it from\r\n\techo.http://sphinx-doc.org/\r\n\texit /b 1\r\n)\r\n\r\n%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%\r\ngoto end\r\n\r\n:help\r\n%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%\r\n\r\n:end\r\npopd\r\n"
  },
  {
    "path": "etc/benchmark.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"import psutil\\n\",\n    \"from subprocess import PIPE\\n\",\n    \"import shlex\\n\",\n    \"from time import sleep\\n\",\n    \"import regex\\n\",\n    \"import numpy as np\\n\",\n    \"import matplotlib.pyplot as plt\\n\",\n    \"from tqdm import tqdm\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"def run_km_constrained(n, d, k, min_clusters=None, max_clusters=None):\\n\",\n    \"    cmd = f'./benchmark_k_means_constrained.py -n {n} -d {d} -K {k}'\\n\",\n    \"    if min_clusters:\\n\",\n    \"        cmd += f' -ge {min_clusters}'\\n\",\n    \"    if max_clusters:\\n\",\n    \"        cmd += f' -le {max_clusters}'\\n\",\n    \"    p = psutil.Popen(shlex.split(cmd), stdout=PIPE)\\n\",\n    \"    peak_mem = 0\\n\",\n    \"    output = \\\"\\\"\\n\",\n    \"    while p.is_running():\\n\",\n    \"        sleep(0.1) # Sample frequency\\n\",\n    \"        # \\\"Resident Set Size\\\"/physical memory used in bytes\\n\",\n    \"        peak_mem = max(p.memory_info().rss, peak_mem)\\n\",\n    \"        output += str(p.communicate()[0])\\n\",\n    \"\\n\",\n    \"    # Time\\n\",\n    \"    time = regex.search(r'Total time: (\\\\d*\\\\.\\\\d*) seconds', output)\\n\",\n    \"    try:\\n\",\n    \"        time = float(time.groups()[0])\\n\",\n    \"    except AttributeError:\\n\",\n    \"        print('k-means-constrained failed:', cmd)\\n\",\n    \"        return None, float(peak_mem)\\n\",\n    \"    return time, float(peak_mem)\\n\",\n    \"\\n\",\n    \"def run_km(n, d, k):\\n\",\n    \"    cmd = f'./benchmark_k_means.py -n {n} -d {d} -K {k}'\\n\",\n    \"    p = psutil.Popen(shlex.split(cmd), stdout=PIPE)\\n\",\n    \"    peak_mem = 0\\n\",\n    \"    output = \\\"\\\"\\n\",\n    \"    while p.is_running():\\n\",\n    \"        sleep(0.1) # Sample frequency\\n\",\n    \"        # \\\"Resident Set Size\\\"/physical memory used in bytes\\n\",\n    \"        peak_mem = max(p.memory_info().rss, peak_mem)\\n\",\n    \"        output += str(p.communicate()[0])\\n\",\n    \"\\n\",\n    \"    # Time\\n\",\n    \"  \\n\",\n    \"    time = regex.search(r'Total time: (\\\\d*\\\\.\\\\d*) seconds', output)\\n\",\n    \"    try:\\n\",\n    \"        time = float(time.groups()[0])\\n\",\n    \"    except AttributeError:\\n\",\n    \"        print('k-means failed:', cmd)\\n\",\n    \"        return None, float(peak_mem)\\n\",\n    \"    return time, float(peak_mem)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"data\": {\n      \"text/plain\": [\n       \"(0.34, 21581824.0)\"\n      ]\n     },\n     \"execution_count\": 3,\n     \"metadata\": {},\n     \"output_type\": \"execute_result\"\n    }\n   ],\n   \"source\": [\n    \"run_km_constrained(10, 2, 4, min_clusters=1, max_clusters=8)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"data\": {\n      \"text/plain\": [\n       \"(0.03, 21663744.0)\"\n      ]\n     },\n     \"execution_count\": 4,\n     \"metadata\": {},\n     \"output_type\": \"execute_result\"\n    }\n   ],\n   \"source\": [\n    \"run_km(10, 2, 4)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 5,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"k-means: 10it [00:27,  2.73s/it]\\n\",\n      \"k-means-constrained: 10it [04:26, 26.64s/it]\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"# Fixed x and d. Increase cluster size (no min or max)\\n\",\n    \"k = [1, 10, 25, 50, 75, 100, 250, 500, 750, 1000]\\n\",\n    \"x = [10*ki for ki in k]\\n\",\n    \"d = 10\\n\",\n    \"min_clusters = None\\n\",\n    \"max_clusters = None\\n\",\n    \"km_time, km_mem = list(zip(*[run_km(xi, d, ki) for ki, xi in tqdm(zip(k, x), desc='k-means')]))\\n\",\n    \"con_time, con_mem = list(zip(*[run_km_constrained(xi, d, ki) for ki, xi in tqdm(zip(k, x), desc='k-means-constrained')]))\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 19,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"data\": {\n      \"image/png\": \"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NMHWrVs1htOJj4/H4sWLcz02Isonp38E4t9K5cZDAXP97M3Xm569zz77DH369NGqnzp1Km7fvo3Vq1fDxialazY4OBhr167FkiVLsHDhQrl+yZIlAKReKMob/v7+MDY2Rs+ePeHn54ddu3ahWLFiebrNcuXK4fvvv8eQIUNQrVo19O3bF87Oznj27BnCwsKwZcsWXL58GS4uLvD09ETZsmUxbtw4hIeHo1y5cjh//jxWr14Nd3f3bN+E8/btW9jb26Nz586oW7cuSpcujTt37uD777+HnZ0dOnXqlOE6Zs2ahYMHD2LIkCHYu3cvPD09IYTAuXPnkJiYiNWrVwMAli5diubNm8PLy0seeuXPP//Enj170KtXL62bMzKrWrVqaNKkCRo3bgwHBwc8evQIy5cvh4mJiTzsCwA0adIEISEhmDJlinydYKdOnTRufNHF398fEydORLt27dC9e3e8efMG69atk4c/yU0qlQqrV69GixYtUKtWLQwaNAg1atRATEwMbt68iU2bNmHu3LkYMGAAAOkUs4+PD5o1a4YPP/xQHnpF19h9RFQIxL4GTn0vlY0tgSYfKhtPHirwyd7q1avlC+2fPXuG+Ph4zJo1C4D0uKS+faVHmTRt2lTn8t988w3u3r0Lf39/jfoOHTqgY8eOWLRoEV6/fi0/QSMkJAR9+vTJ0Z2GlLEuXbpg06ZN6NGjB9q0aYM9e/ZoJON5YeDAgahcuTK++uor/Pjjj3j16hVKliyJKlWqYObMmfINIba2ttizZw/Gjx+PZcuWITExEfXr18fOnTsREhKS7WTPwsICo0ePxoEDB7B//35ERUXJyd/EiRMzNWi4nZ0dTp48iTlz5mDTpk3YvHkzrK2tUb16dYwcOVJu16BBA5w4cQJTp07Fd999h+joaLi5ueHLL7/EuHHjshU/IF3ftnPnTnz99dd4/fo1SpcujSZNmmDixImoXbu23G727NmIjIzEt99+i1evXkEIgTt37mSY7H366acQQiAkJAQff/wxypYti8DAQAwcODBPboSoU6cOzp07h7lz52Lbtm344YcfYG1tDRcXFwwYMEAjKW7atCn27duHCRMmYN68ebCxsZHHOnR3d8/12Igoj/21HIh7LZUbDgYsSygbTx5Sify48jsHfHx8dD61AACaN2+Ow4cPZ7j833//rXOU+9jYWMyaNQtr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arFLr0yfPt1t3927d5eGDRu61VetWiUAZOvWrY6afdmMixcvypAhQyQ0NFT0er307NlTfvnlF4/v6csvv5TevXtLSEiIBAQESIMGDaRv376yZMkSl3ZlOU6Fbdu2TRITE8VoNIpWq5W4uDhJTU11a1eWpVfs1q1bJ23btnX0++WXX3YsVVJ4LMxms8ydO1duu+02CQgIkJiYGHnhhRfkwIEDHo/7hg0bpF27dqLVagWAy5gvW7ZMWrZsKVqtVurVqycjR46Uy5cvl+n4lHWcCgoK5LXXXpMWLVpIQECAhISEyIMPPih79+51a+upH8X1zdPvkMVikQkTJkhUVJQolUrHsTx+/LiMHj1aWrRoIUajUQIDA6VFixYydepUuXbtWqneN5GvUIiU82pnIiKiUhg6dCjef//9ct9cQ0S3htfsEREREfkxhj0iIiIiP8awR0REROTHeM0eERERkR/jzB4RERGRH2PYIyIiIvJjDHtEREREfoxhj4iIiMiPMewRERER+TGGPSIiIiI/xrBHRERE5McY9oiIiIj8GMMeERERkR9j2CMiIiLyYwx7RERERH6MYY+IiIjIj/1/s81ZGSywoyMAAAAASUVORK5CYII=\",\n      \"text/plain\": [\n       \"<Figure size 650x650 with 1 Axes>\"\n      ]\n     },\n     \"metadata\": {},\n     \"output_type\": \"display_data\"\n    }\n   ],\n   \"source\": [\n    \"fig, ax1 = plt.subplots(1, 1, figsize=(5, 5), dpi=130)\\n\",\n    \"\\n\",\n    \"ax1.plot(x, km_time, label='k-means')\\n\",\n    \"ax1.plot(x, con_time, label='k-means-constrained')\\n\",\n    \"\\n\",\n    \"ax1.set_xlabel('x: number of data-points')\\n\",\n    \"ax1.set_ylabel('Time (s)')\\n\",\n    \"ax1.set_title('Data-points vs execution time.\\\\nData-points=10*clusters. No min/max constraints')\\n\",\n    \"ax1.legend()\\n\",\n    \"\\n\",\n    \"plt.tight_layout()\\n\",\n    \"\\n\",\n    \"plt.show()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": []\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"data\": {\n      \"image/png\": \"iVBORw0KGgoAAAANSUhEUgAABKUAAAJOCAYAAABm7rQwAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAADKiElEQVR4nOzdd3hUdfbH8fekF1KBNBIglFCkKoiKBQQJUVFEUbFgQV1dwEUWddG1gKyoK6tr+ekuKmBB1FVxVyWACAIaUUBsYCgCCb2EJKSXmd8fN5lkUiCEydyZ5PN6nvtkMvfOnTNRkrlnzjlfi81msyEiIiIiIiIiIuJCXmYHICIiIiIiIiIiLY+SUiIiIiIiIiIi4nJKSomIiIiIiIiIiMspKSUiIiIiIiIiIi6npJSIiIiIiIiIiLicklIiIiIiIiIiIuJySkqJiIiIiIiIiIjLKSklIiIiIiIiIiIup6SUiIiIiIiIiIi4nJJSIiIiIiIiIiLickpKiYiIiIhTrF69mlGjRhEXF4fFYmHx4sWn9PjHH38ci8VSawsODm6agEVERMRUSkqJiIiIiFPk5+fTt29fXn755UY9ftq0aezfv99h69mzJ2PHjnVypCIiIuIOlJQSEREREadISUlh1qxZXHXVVXXuLy4uZtq0abRr147g4GAGDRrEqlWr7PtbtWpFTEyMfTt48CCbN29mwoQJLnoFIiIi4kpKSomIiIiIS0yaNIm0tDQWLVrETz/9xNixYxk5ciTbtm2r8/jXXnuNpKQkLrjgAhdHKiIiIq6gpJSIiIiINLmMjAzmzZvHBx98wAUXXEDnzp2ZNm0a559/PvPmzat1fFFREe+8846qpERERJoxH7MDEBEREZHm7+eff6a8vJykpCSH+4uLi2ndunWt4z/++GOOHz/OLbfc4qoQRURExMWUlBIRERGRJpeXl4e3tzcbNmzA29vbYV+rVq1qHf/aa69x+eWXEx0d7aoQRURExMWUlBIRERGRJte/f3/Ky8s5dOjQSWdE7dy5k5UrV/Lf//7XRdGJiIiIGZSUEhERERGnyMvLY/v27fbvd+7cyaZNm4iMjCQpKYkbb7yR8ePHM2fOHPr378/hw4dZsWIFffr04bLLLrM/7o033iA2NpaUlBQzXoaIiIi4iMVms9nMDkJEREREPN+qVasYOnRorftvueUW5s+fT2lpKbNmzeLNN99k7969tGnThnPOOYcZM2bQu3dvAKxWKx06dGD8+PH87W9/c/VLEBERERdSUkpERERERERERFzOy+wARERERERERESk5VFSSkREREREREREXE6DzjFmF+zbt4+QkBAsFovZ4YiIiIjJbDYbx48fJy4uDi8vfYZ3InofJSIiIjU19L2UklLAvn37SEhIMDsMERERcTOZmZnEx8ebHYZb0/soERERqc/J3kspKQWEhIQAxg8rNDTU5GhERETEbLm5uSQkJNjfI0j99D5KREREamroeyklpcBeah4aGqo3UyIiImKndrST0/soERERqc/J3kuZOiRh9uzZDBw4kJCQEKKiohg9ejTp6ekOxxQVFTFx4kRat25Nq1atuPrqqzl48KDDMRkZGVx22WUEBQURFRXF/fffT1lZmStfioiIiIiIiIiInAJTk1JfffUVEydO5Ntvv2X58uWUlpYyYsQI8vPz7cfcd999/O9//+ODDz7gq6++Yt++fYwZM8a+v7y8nMsuu4ySkhK++eYbFixYwPz583n00UfNeEkiIiIiIiIiItIAFpvNZjM7iEqHDx8mKiqKr776igsvvJCcnBzatm3LwoULueaaawD47bff6NGjB2lpaZxzzjksWbKEyy+/nH379hEdHQ3Aq6++yoMPPsjhw4fx8/M76fPm5uYSFhZGTk6Oys5FRERE7w1OgX5WIiIiUlND3x+41UypnJwcACIjIwHYsGEDpaWlDB8+3H5M9+7dad++vT0plZaWRu/eve0JKYDk5GTuuecefv31V/r37++U2KxWKyUlJU45l4gn8vX1xdvb2+wwRERERETcQnl5OaWlpWaHIWIKZ10fuk1Symq1MmXKFAYPHkyvXr0AOHDgAH5+foSHhzscGx0dzYEDB+zHVE9IVe6v3FeX4uJiiouL7d/n5uaeMLaSkhJ27tyJ1Wo9pdck0tyEh4cTExOjwb8iIiIi0mLZbDYOHDhAdna22aGImMoZ14duk5SaOHEiv/zyC2vXrm3y55o9ezYzZsxo0LE2m439+/fj7e1NQkICXl6mjuESMYXNZqOgoIBDhw4BEBsba3JEIiIiIiLmqExIRUVFERQUpA9spcVx5vWhWySlJk2axKeffsrq1auJj4+33x8TE0NJSQnZ2dkO1VIHDx4kJibGfsx3333ncL7K1fkqj6lp+vTpTJ061f59bm4uCQkJdR5bVlZGQUEBcXFxBAUFNer1iTQHgYGBABw6dIioqCi18omIiIhIi1NeXm5PSLVu3drscERM46zrQ1PLfmw2G5MmTeLjjz/myy+/JDEx0WH/WWedha+vLytWrLDfl56eTkZGBueeey4A5557Lj///LM9QwewfPlyQkND6dmzZ53P6+/vT2hoqMNWn/LycoAGDUwXae4qE7PqnRcRERGRlqjyfbAKFkScc31oaqXUxIkTWbhwIZ988gkhISH2GVBhYWEEBgYSFhbGhAkTmDp1KpGRkYSGhjJ58mTOPfdczjnnHABGjBhBz549ufnmm3nmmWc4cOAAf/3rX5k4cSL+/v5Oi1UlmSL6dyAiIiIiAnpfLALO+XdgalLqlVdeAWDIkCEO98+bN49bb70VgOeeew4vLy+uvvpqiouLSU5O5v/+7//sx3p7e/Ppp59yzz33cO655xIcHMwtt9zCzJkzXfUyRERERERERETkFJmalLLZbCc9JiAggJdffpmXX3653mM6dOjA559/7szQPN6QIUPo168fzz//vNmhiIiIiIiIiMl0jSjuSEvJiYiIiIiIiIiIyykpJSIiIiIiIiIiLqekVAvx2WefERYWxjvvvFPn/iFDhjB58mSmTJlCREQE0dHRzJ07l/z8fG677TZCQkLo0qULS5YscXjcL7/8QkpKCq1atSI6Opqbb76ZI0eO2PenpqZy/vnnEx4eTuvWrbn88svZsWOHff+uXbuwWCx89NFHDB06lKCgIPr27UtaWpr9mN27dzNq1CgiIiIIDg7mjDPOULumiIiIiIjIadA1orgDJaVOkc1mo6CkzJStITO46rJw4ULGjRvHO++8w4033ljvcQsWLKBNmzZ89913TJ48mXvuuYexY8dy3nnnsXHjRkaMGMHNN99MQUEBANnZ2Vx88cX079+f9evXk5qaysGDB7n22mvt58zPz2fq1KmsX7+eFStW4OXlxVVXXYXVanV47ocffphp06axadMmkpKSGDduHGVlZYCxSmNxcTGrV6/m559/5umnn6ZVq1aN+lmIiIiIiIg4iydeH4KuEcV9WGyn839yM5Gbm0tYWBg5OTmEhoY67CsqKmLnzp0kJiYSEBBAQUkZPR9dakqcm2cmE+TXsNn0lUPsunbtysMPP8wnn3zCRRdddMLjy8vLWbNmDQDl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8nLi4uJMiMgT1a6G8rGvvue6Sqk9x7TynoiIiLMpKdWS2Gxq3RMREXGhv//970yePJn169fb71u/fj1/+tOfePbZZ02MzBNVVUr52Vffc2GlVFbFTCm174mIiDiN2vdakn0/QHYG+AZBl+FmRyMiItIsRUREOKzOlp+fz6BBg/DxMd52lZWV4ePjw+23387o0aNNitKD2OqolKqYKVXqoplSRaXlHDpeDKh9T0RExJmUlGpJKqukuo4AP72hEhERaQrPP/+82SE0MxWJp7pmSrlo9b292UbrXrCfNxFBvi55ThERkZZASamWQq17IiIiLnHLLbeYHUIzVb19r3L1Pdckpapa94IcquBERETk9GimVEtx4Gc4thN8AoxKKREREWkS+fn5TXp8i1NX+5599T3XtO9lVgw5j4/QPCkRERFnUlKqpaiskuoyHPxbmRuLiIhIM9alSxeeeuop9u/fX+8xNpuN5cuXk5KSwgsvvODC6DyYQ/teRaWUiwad7zlmVEppnpSIiIhzqX2vJbDZYPNi43bP0WZGIiIi0uytWrWKhx56iMcff5y+ffsyYMAA4uLiCAgI4NixY2zevJm0tDR8fHyYPn06f/jDH8wO2c3VroaqbN9zVaXUniyjUiohUkkpERERZ2p0Uqq0tJQDBw5QUFBA27ZtiYyMdGZc4kyHtsDR7eDtB0nJZkcjIiLSrHXr1o0PP/yQjIwMPvjgA9asWcM333xDYWEhbdq0oX///sydO5eUlBS8vb3NDteDVKuU8qpo33PVTCl7pZTa90RERJzplJJSx48f5+2332bRokV89913lJSUYLPZsFgsxMfHM2LECO666y4GDhzYVPFKY1S27nUeBgGh5sYiIiLSQrRv354///nP/PnPfzY7FM9W50ypyvY9F1VKVcyUSlD7noiIiFM1eKbUP/7xDzp27Mi8efMYPnw4ixcvZtOmTWzdupW0tDQee+wxysrKGDFiBCNHjmTbtm1NGbecisqk1BmjTQ1DRERE5NRVJJ4s1Vffqxx03vSVUvnFZWTllwAQH6lKKREREWdqcKXU999/z+rVqznjjDPq3H/22Wdz++238+qrrzJv3jzWrFlD165dnRaoNNLhdDi8Bbx8IWmk2dGIiIiINFLtQeeumClV2boXFuhLaIBvkz+fiIhIS9LgpNS7777boOP8/f25++67Gx2QONnm/xpfOw+FwHBTQxERERE5ZXW27xkJKlesvlc15FxVUiIiIs7W4Pa9E8nNzWXx4sVs2bLFGacTZ7KvunelqWGIiIiInJZq7Xu+XpWVUk2flKqslNI8KREREedrVFLq2muv5aWXXgKgsLCQAQMGcO2119KnTx8+/PBDpwYop+HIdjj4C3j5QLdLzY5GRERETsPs2bMZOHAgISEhREVFMXr0aNLT00/6uA8++IDu3bsTEBBA7969+fzzzx3222w2Hn30UWJjYwkMDGT48OFuNhu0dqWUb2X7ntUF7XsVlVJaeU9ERMT5GpWUWr16NRdccAEAH3/8MTabjezsbF544QVmzZrl1ADlNGypGHCeeCEERZobi4iISAvUsWNHZs6cSUZGxmmf66uvvmLixIl8++23LF++nNLSUkaMGEF+fn69j/nmm28YN24cEyZM4IcffmD06NGMHj2aX375xX7MM888wwsvvMCrr77KunXrCA4OJjk5maKiotOO2bmqz5RyYfteZaVUpCqlREREnK1RSamcnBwiI40kR2pqKldffTVBQUFcdtllbvbJWgtXueqeWvdERERMMWXKFD766CM6derEJZdcwqJFiyguLm7UuVJTU7n11ls544wz6Nu3L/PnzycjI4MNGzbU+5h//vOfjBw5kvvvv58ePXrwxBNPcOaZZ9or3m02G88//zx//etfufLKK+nTpw9vvvkm+/btY/HixY2K0+nqmCnla09KuWLQecVMKbXviYiIOF2jklIJCQmkpaWRn59PamoqI0aMAODYsWMEBAQ4NUBppKydsP9HsHhB98vNjkZERKRFmjJlCps2beK7776jR48eTJ48mdjYWCZNmsTGjRtP69w5OTkA9g8K65KWlsbw4cMd7ktOTiYtLQ2AnTt3cuDAAYdjwsLCGDRokP0Y81UknqrPlKpo3ytp4kopm83GniyjUkrteyIiIs7XqKTUlClTuPHGG4mPjycuLo4hQ4YARltf7969nRmfNNaWilX3Op4PwW3MjUVERKSFO/PMM3nhhRfYt28fjz32GK+99hoDBw6kX79+vPHGG9jqqAY6EavVypQpUxg8eDC9evWq97gDBw4QHR3tcF90dDQHDhyw76+8r75jaiouLiY3N9dhczWfiqRUU1dK5RaWcby4DIB4VUqJiIg4nU9jHvTHP/6RQYMGkZGRwSWXXIJXxQoonTp10kwpd6HWPREREbdRWlrKxx9/zLx581i+fDnnnHMOEyZMYM+ePTz00EN88cUXLFy4sMHnmzhxIr/88gtr165twqjrNnv2bGbMmOG6J7Qn7KqvvlfRvmdt2kqpypX32rTyJ9DPu0mfS0REpCVqVFIK4KyzzuKss85yuO+yyy477YDECbIzYO8GwALdR5kdjYiISIu1ceNG5s2bx7vvvouXlxfjx4/nueeeo3v37vZjrrrqKgYOHNjgc06aNIlPP/2U1atXEx8ff8JjY2JiOHjwoMN9Bw8eJCYmxr6/8r7Y2FiHY/r161fnOadPn87UqVPt3+fm5pKQkNDg+Butzva9pq2UylTrnoiISJNqcPveU089RWFhYYOOXbduHZ999lmjg5LTtOV/xtcOgyEk+sTHioiISJMZOHAg27Zt45VXXmHv3r08++yzDgkpgMTERK6//vqTnstmszFp0iQ+/vhjvvzySxITE0/6mHPPPZcVK1Y43Ld8+XLOPfdc+3PHxMQ4HJObm8u6devsx9Tk7+9PaGiow9a0aieeXLX63p7KIedaeU9ERKRJNLhSavPmzbRv356xY8cyatQoBgwYQNu2bQEoKytj8+bNrF27lrfffpt9+/bx5ptvNlnQchJq3RMRETFdeXk5b7zxBldccQURERH1HhccHMy8efNOer6JEyeycOFCPvnkE0JCQuwzn8LCwggMNCp5xo8fT7t27Zg9ezYAf/rTn7jooouYM2cOl112GYsWLWL9+vX8+9//BsBisTBlyhRmzZpF165dSUxM5JFHHiEuLo7Ro0ef5k+g6fi6aKZUZfueKqVERESaRoMrpd58802++OILSktLueGGG4iJicHPz4+QkBD8/f3p378/b7zxBuPHj+e3337jwgsvPOk5V69ezahRo4iLi8NisdRaethms/Hoo48SGxtLYGAgw4cPZ9u2bQ7HZGVlceONNxIaGkp4eDgTJkwgLy+voS+r+cndB5nrjNs91LonIiJiFm9vb/7whz+QnZ3tlPO98sor5OTkMGTIEGJjY+3be++9Zz8mIyOD/fv3278/77zzWLhwIf/+97/p27cv//nPf1i8eLHDcPQHHniAyZMnc9dddzFw4EDy8vJITU11nxWV6xgC76rV9yrb9xI05FxERKRJnNJMqb59+zJ37lz+9a9/8dNPP7F7924KCwtp06YN/fr1o02bU1vlLT8/n759+3L77bczZsyYWvufeeYZXnjhBRYsWGD/5C45OZnNmzfb3yjdeOON7N+/n+XLl1NaWsptt93GXXfddUrDQpuVzRWr7iWcA6GxJz5WREREmlSvXr34/fffG9RqdzINWaFv1apVte4bO3YsY8eOrfcxFouFmTNnMnPmzNMJrwlVvO5qM6Xs7XtNPOi8qn1PlVIiIiJNoVGDzr28vOjXr1+9AzAbKiUlhZSUlDr32Ww2nn/+ef76179y5ZVGG9qbb75JdHQ0ixcv5vrrr2fLli2kpqby/fffM2DAAABefPFFLr30Up599lni4uJOKz6PpNY9ERERtzFr1iymTZvGE088wVlnnUVwcLDD/qafx9Q8+Xo1ffuezWazJ6XiVSklIiLSJBrcvudqO3fu5MCBAwwfPtx+X1hYGIMGDSItLQ2AtLQ0wsPD7QkpgOHDh+Pl5cW6detcHrPpjh+ADONno9Y9ERER81166aX8+OOPXHHFFcTHxxMREUFERATh4eEnnDMl1dgrxGpXSjVl+96RvBIKS8uxWCAu3E1aGUVERJqZRlVKuULl8M7oaMfV46Kjo+37Dhw4QFRUlMN+Hx8fIiMj7cfUpbi4mOLiYvv3ubm5zgrbXFv+B9ig3QAId8HSzCIiInJCK1euNDuE5qNa+54rBp3vqRhyHhMagL+Pd5M9j4iISEvmtkmppjR79mxmzJhhdhjOp9Y9ERERt3LRRReZHUKz5Fs5U6oJK6Uy7a17miclIiLSVNw2KRUTEwPAwYMHiY2tGth98OBB+yyrmJgYDh065PC4srIysrKy7I+vy/Tp05k6dar9+9zcXBISPLyyKO8w7P7auN3zCnNjEREREbvs7Gxef/11tmzZAsAZZ5zB7bffTlhYmMmReZpq7XsVM6VKrU1XKaWV90RERJreac2U2r59O0uXLqWw0PgkqSGrwjRUYmIiMTExrFixwn5fbm4u69at49xzzwXg3HPPJTs7mw0bNtiP+fLLL7FarQwaNKjec/v7+xMaGuqwebzfPgWbFWL7QURHs6MRERERYP369XTu3JnnnnuOrKwssrKy+Mc//kHnzp3ZuHGj2eF5hjreX/r5GAmq0iaslLIPOY9UUkpERKSpNKpS6ujRo1x33XV8+eWXWCwWtm3bRqdOnZgwYQIRERHMmTOnQefJy8tj+/bt9u937tzJpk2biIyMpH379kyZMoVZs2bRtWtXEhMTeeSRR4iLi2P06NEA9OjRg5EjR3LnnXfy6quvUlpayqRJk7j++utb3sp7at0TERFxO/fddx9XXHEFc+fOxcfHeNtVVlbGHXfcwZQpU1i9erXJEXqCiqSUpXallCtmSql9T0REpOk0qlLqvvvuw8fHh4yMDIKCqj49uu6660hNTW3wedavX0///v3p378/AFOnTqV///48+uijADzwwANMnjyZu+66i4EDB5KXl0dqaioBAVUroLzzzjt0796dYcOGcemll3L++efz73//uzEvy3MVZMHOije1SkqJiIi4jfXr1/Pggw/aE1JgLMrywAMPsH79ehMj82yVq+81ZaWU2vdERESaXqMqpZYtW8bSpUuJj493uL9r167s3r27wecZMmTICVv+LBYLM2fOZObMmfUeExkZycKFCxv8nM3Sb5+BrRxiekPrzmZHIyIiIhVCQ0PJyMige/fuDvdnZmYSEhJiUlQexv5esapSyq9i9b2mSkpZrTb2ZhvtewmRqpQSERFpKo2qlMrPz3eokKqUlZWFv7//aQclp0iteyIiIm7puuuuY8KECbz33ntkZmaSmZnJokWLuOOOOxg3bpzZ4XmW6u17FUkpq81IIDnbweNFlJbb8PayEBMacPIHiIiISKM0qlLqggsu4M033+SJJ54AjIomq9XKM888w9ChQ50aoJxE4TH4fZVxu+doMyMRERGRGp599lksFgvjx4+nrKwMAF9fX+655x6eeuopk6PzFLWTTpXtewClViv+Xt5OfcbMLKNKKi48wJ4AExEREedrVFLqmWeeYdiwYaxfv56SkhIeeOABfv31V7Kysvj666+dHaOcSPoSsJZCVE9o09XsaERERKQaPz8//vnPfzJ79mx27NgBQOfOneusOJeTqd2+B1BabsO/Ue9o61c55FzzpERERJpWo/6E9+rVi61bt/LSSy8REhJCXl4eY8aMYeLEicTGxjo7RjkRte6JiIi4vaCgIHr37m12GJ6pjvmjPl5VCaqyJpgrVVkppZX3REREmlajP1cKCwvj4YcfdmYscqqKcmDHl8ZtJaVERETcTlFRES+++CIrV67k0KFDWK2OCZSNGzeaFJknqUhKVZsp5V0tKVVa7vyZUpmqlBIREXGJRielioqK+Omnn+p8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AAAIOEIpAAAAAAAABByhlJ/NmzdPffr0UXR0tLKysvTBBx/YPaSQsnbtWk2cOFE9evSQw+HQ4sWLfR43xujhhx9WWlqaYmJiNG7cOOXn5/vcc+TIEd10001KSEhQUlKSbrvtNpWXl/vcs23bNo0ePVrR0dFKT0/Xr3/9a3+/taCWk5OjkSNHKj4+Xt27d9eNN96o3bt3+9xz8uRJTZs2TV26dFFcXJwmTZqk4uJin3v27t2rG264QbGxserevbt+9rOfqaamxuee1atXa/jw4YqKitL555+v3Nxcf7+9oPXss89qyJAhSkhIUEJCgkaNGqV3333Xepw5D4zHHntMDodD99xzj3WNufePRx55RA6Hw+dr4MCB1uPMO1hHnRvWUfZgHWUf1lLBgbVU4ITFWsrAbxYsWGDcbrd54YUXzEcffWRuv/12k5SUZIqLi+0eWsh45513zM9//nOzcOFCI8ksWrTI5/HHHnvMJCYmmsWLF5sPP/zQ/Md//IfJzMw0J06csO657rrrzNChQ82GDRvMe++9Z84//3wzZcoU6/Fjx46ZlJQUc9NNN5kdO3aYV1991cTExJg//OEPgXqbQWf8+PFm/vz5ZseOHSYvL89cf/31JiMjw5SXl1v3TJ061aSnp5sVK1aYTZs2ma997Wvmsssusx6vqakxF110kRk3bpzZunWreeedd0zXrl3NrFmzrHs+/fRTExsba2bOnGl27txpfve735mIiAizdOnSgL7fYPG3v/3NLFmyxHzyySdm9+7d5sEHHzSRkZFmx44dxhjmPBA++OAD06dPHzNkyBBz9913W9eZe/+YPXu2GTRokDl48KD19eWXX1qPM+8dG+uoc8c6yh6so+zDWsp+rKUCKxzWUoRSfnTppZeaadOmWT/X1taaHj16mJycHBtHFbrOXEx5PB6TmppqHn/8ceva0aNHTVRUlHn11VeNMcbs3LnTSDL//ve/rXveffdd43A4zIEDB4wxxvz+9783nTt3NpWVldY9999/vxkwYICf31HoKCkpMZLMmjVrjDF18xwZGWlef/11656PP/7YSDLr1683xtQthJ1OpykqKrLuefbZZ01CQoI11/fdd58ZNGiQz++aPHmyGT9+vL/fUsjo3Lmzef7555nzACgrKzP9+vUzy5YtM1dccYW1kGLu/Wf27Nlm6NChDT7GvIN1VPti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VVVyu912DwMAAAQx1lENYx0FtAyVUkAHt2TJEiUmJurll19u8XO8ZdK/+c1vlJaWpi5dumjatGmqrq627mmoBDspKUm5ubmSpM8++0wOh0OvvfaaRo8erZiYGI0cOVKffPKJ/v3vf+uSSy5RXFycJkyYoC+//PKsMcyZM0fdunVTQkKCpk6dqqqqKusxj8ejnJwcZWZmKiYmRkOHDtUbb7xhPb569Wo5HA69++67GjFihKKiorRu3boG3+v27dt19dVXKyYmRl26dNEdd9yh8vJySXXl5hMnTpQkOZ3OJhdTH330kb7xjW8oISFB8fHxGj16tLUQO1NDn9ANGzZMjzzyiKS6xd8jjzyijIwMRUVFqUePHvqv//ovSXXbCj7//HPNmDFDDofDZ0zr1q2z5jo9PV3/9V//pYqKCp/f+6tf/Uo/+tGPlJCQoDvuuENVVVWaPn260tLSFB0drd69eysnJ6fR9wkAQEfCOop11Om/l3UU0HqEUkAH9sorr2jKlCl6+eWXddNNN0k6tdD47LPPmnzuqlWrVFBQoFWrVunFF19Ubm6utVBqjdmzZ+uhhx7Sli1b5HK59P3vf1/33Xefnn76ab333nvas2ePHn74YZ/nrFixQh9//LFWr16tV199VQsXLtScOXOsx3NycvTSSy/pueee00cffaQZM2boBz/4gdasWePzOg888IAee+wxffzxxxoyZMhZY6uoqND48ePVuXNn/fvf/9brr7+u5cuXa/r06ZKke++9V/Pnz5ckHTx4UAcPHmzwPR44cEBjxoxRVFSUVq5cqc2bN+vWW29VTU1Nq+dLkt5880099dRT+sMf/qD8/HwtXrxYgwcPliQtXLhQvXr10i9/+UufMRUUFOi6667TpEmTtG3bNv31r3/VunXrrPfi9Zvf/EZDhw7V1q1b9Ytf/EK//e1v9be//U2vvfaadu/erZdffll9+vRp07gBAAgnrKNYR7GOAtqBAdChXHHFFebuu+82zzzzjElMTDSrV6/2eXzjxo1mwIABZv/+/Y2+RnZ2tundu7epqamxrn3nO98xkydPtn6WZBYtWuTzvMTERDN//nxjjDGFhYVGknn++eetx1999VUjyaxYscK6lpOTYwYMGODzu5OTk01FRYV17dlnnzVxcXGmtrbWnDx50sTGxpp//etfPr/7tttuM1OmTDHGGLNq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\",\n      \"text/plain\": [\n       \"<Figure size 1200x600 with 2 Axes>\"\n      ]\n     },\n     \"metadata\": {},\n     \"output_type\": \"display_data\"\n    }\n   ],\n   \"source\": [\n    \"fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6))\\n\",\n    \"\\n\",\n    \"ax1.plot(x, km_time, label='k-means')\\n\",\n    \"ax1.plot(x, con_time, label='k-means-constrained')\\n\",\n    \"\\n\",\n    \"ax1.set_xlabel('x: number of data-points')\\n\",\n    \"ax1.set_ylabel('Time (s)')\\n\",\n    \"#ax1.set_title('First Plot')\\n\",\n    \"ax1.legend()\\n\",\n    \"\\n\",\n    \"ax2.plot(x, km_mem, label='k-means')\\n\",\n    \"ax2.plot(x, con_mem, label='k-means-constrained')\\n\",\n    \"\\n\",\n    \"ax2.set_xlabel('x: number of data-points')\\n\",\n    \"ax2.set_ylabel('Peak memory (bytes)')\\n\",\n    \"#ax2.set_title('Second Plot')\\n\",\n    \"ax2.legend()\\n\",\n    \"\\n\",\n    \"plt.tight_layout()\\n\",\n    \"\\n\",\n    \"plt.show()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 57,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"k-means-constrained: 100%|██████████| 8/8 [03:26<00:00, 25.77s/it]\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"# Fixed x, d, k. Increase min_cluster\\n\",\n    \"x = 10000\\n\",\n    \"d = 10\\n\",\n    \"k = 10 #list(range(1, x//2, 10))\\n\",\n    \"min_clusters = [1, 10, 50, 100, 250, 500, 750, 1000]\\n\",\n    \"max_clusters = None\\n\",\n    \"#km_time, km_mem = list(zip(*[run_km(x, d, k)]))\\n\",\n    \"con_time, con_mem = list(zip(*[run_km_constrained(x, d, k, min_clusters=mc) for mc in tqdm(min_clusters, desc='k-means-constrained')]))\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 60,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"data\": {\n      \"image/png\": \"iVBORw0KGgoAAAANSUhEUgAABKUAAAJOCAYAAABm7rQwAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAADhpElEQVR4nOzdd3hT9f4H8PdJ0r0H3YUOKGW0gCwZIrI3uEHvxQF69QJX3OLCgaDe6x74u4h4UQEXIDJFoAzZBaSsAh200N3SvZP8/khP2kpb2pLkm/F+PU+ex6YnJ58UoSeffIak1Wq1ICIiIiIiIiIiMiGF6ACIiIiIiIiIiMj2MClFREREREREREQmx6QUERERERERERGZHJNSRERERERERERkckxKERERERERERGRyTEpRUREREREREREJsekFBERERERERERmRyTUkREREREREREZHJMShERERERERERkckxKUVERERERERERCbHpBQRERER3ZA9e/Zg8uTJCAoKgiRJWL9+fZse/9prr0GSpGtuLi4uxgmYiIiIzAKTUkRERER0Q8rKytCrVy989tln7Xr8M888g8zMzEa37t274+677zZwpERERGROmJQiIiIiohsyfvx4LFq0CLfffnuT36+qqsIzzzyD4OBguLi4YODAgYiLi9N/39XVFQEBAfpbdnY2zpw5g1mzZpnoFRAREZEITEoRERERkVHNnTsXBw4cwJo1a3Dy5EncfffdGDduHC5cuNDk8V9++SWioqJwyy23mDhSIiIiMiUmpYiIiIjIaNLS0rBixQr8+OOPuOWWWxAZGYlnnnkGQ4cOxYoVK645vrKyEt999x2rpIiIiGyASnQARERERGS9EhISoFarERUV1ej+qqoq+Pj4XHP8unXrUFJSggceeMBUIRIREZEgTEoRERERkdGUlpZCqVQiPj4eSqWy0fdcXV2vOf7LL7/EpEmT4O/vb6oQiYiISBAmpYiIiIjIaPr06QO1Wo2cnJzrzohKSUnBrl27sGHDBhNFR0RERCIxKUVEREREN6S0tBQXL17Uf52SkoITJ07A29sbUVFRuP/++zFz5ky899576NOnD3Jzc7Fjxw7ExsZi4sSJ+sd99dVXCAwMxPjx40W8DCIiIjIxSavVakUHQURERESWKy4uDrfddts19z/wwAP4+uuvUVNTg0WLFmHlypW4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wRa+sipu4SMiIrqev27eA+orpbKLq66pmCciIiLLwqQUUTu0ZZ6UrEeQO8J8nFFVyy18RERErdFUUkoedF5dq0FRRY2QuIiIiMgwmJQiaofkVm7ea0iSJH21FLfwERERXV9uaV1SyrU+KeWgUsLL2Q4AN/ARERFZOialiNohSa6U8m19pRQATIzVJaXkLXxERETUvKYqpYCGLXycK0VERGTJmJQiaiOtVquvlOrs1/pKKQDoHljfwreDLXxEREQtul5SisPOiYiILBuTUkRtlFNShbJqNZQKCR2925aUkiRJXy21mS18RERELcrRb9/7a1JK93UOk1JEREQWjUkpojZKqquSCvVygr2q7X+F5LlSbOEjIiJqXlWtWj/IvPn2Pc6UIiIismRMShG1UXs27zXUPdAd4b4ubOEjIiJqQV5pNQDATinBw8mu0ff8OFOKiIjIKjApRdRGcqVUhG/bWvdkui18AQDYwkdERNQc/TwpVwdIktToewFMShEREVkFJqWI2kiulIr0a1+lFABMjAkCwBY+IiKi5jQ35ByonynF9j0iIiLLxqQUURsl591YpRQAdAt0YwsfERFRC1pOSukqpXJLq6DWaE0aFxERERkOk1JEbVBZo8blqxUA2j9TCqjbwlc38HzTyQyDxEZERGRNWkpK+bjYQyEBao0W+WWsliIiIrJUTEoRtUFqfhm0WsDNUQVfV/sbOpe8hS8uMRelbOEjIiJqJKdENy+qg5vjNd9TKRXwda1r4StiUoqIiMhSMSlF1Ab6eVIdXK8ZutpW3QLdECG38J3NNkR4REREVqOlSikACPDgsHMiIiJLx6QUURsky5v3OrR/npRMt4VPVy21OYFb+IiIiBrKLa3fvtcUv7oKquwSJqWIiIgsFZNSRG3QsFLKEOSk1C628BERETVyvUopbuAjIiKyfExKEbVBUp4uKXUjm/caklv4qtnCR0REpKfVavVJKb9mk1K6Sqkctu8RERFZLCaliFpJq9UiOUdu3zNMpVTDFr5NJ9nCR0REBAAlVbWoqtUAaGGmVF1SKotJKSIiIovFpBRRK+WWVqGkqhYKCejk42yw806MrdvCd54tfEREREB9656bowqOdsomj/Fj+x4REZHFY1KKqJXkeVIhXs7NXiC3R3QAW/iIiIga0mqBIZ190D/Mu9lj2L5HRERk+ZiUImolOSll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nVBv+Gkxp3FB6JaPNRSCam4qCDUqEt2mIGR+LoOdVIY0KgV0KgW06p8XhLQqJXTmYpFa8ZPHb/9Y4yJT4/t0agU0SgVnPZFwLEpRs4zuHoAQLx3ySmsQ7uMKtZLtyIiIiBxVTEwM1q9fjxkzZqCmpgb19fWYOHEiPvjgg1ueU1tbi9raWsvXZWVltohKRHYuKsjTsqpi6Wcp6ODr2qgQdKuCkLlgZE+FocaFnh+LOLpbFX1u/lr9kyLRHR4zF6A0SgUUChaGyHmxKEXNolIqMHtoB/zluzT0CGFTOyIiIkd29uxZLFmyBK+++irGjh2L/Px8vPTSS3j66aexatWqJs9Zvnw5/vd//9fGSYnIESwaEYmES0VIvnIDyVdu3PXzaJSKRgWbxsWcpgo7NxeMbv/Y7WYYsTBEJI4kc5uEnykrK4OXlxdKS0vh6ekpOo7d0BuM2Hw8B/d39Uewl4voOERERELY+zhBkiRs2bIFU6ZMueUxc+bMQU1NDTZt2mS5LyEhASNGjEBeXh6Cg4N/dk5TM6XCwsLs9joQke3IsowvknOQX1rz47Iz9S1mDTUx+8h8DAtDRG1Hc8dLnClFzaZWKjBjULjoGERERHSPqqqqoFI1HgYqlUoAuOW27lqtFlqt1urZiMjxSJKE6QPDRMcgIgfExkBEREREDq6iogIpKSlISUkBAGRkZCAlJQVZWVkAgGXLlmHu3LmW4ydOnIjNmzdj5cqVSE9Px8GDB7F48WIMHjwYISEhIt4CEREROSHOlCIiIiJycMeOHcODDz5o+fqFF14AAMybNw9r165Ffn6+pUAFAPPnz0d5eTnef/99vPjii/D29sZDDz2EN9980+bZiYiIyHmxp1QT7L1XBBEREYnDcYIJrwMRERHdSnPHCVy+R0RERERERERENseiFBERERERERER2RyLUkREREREREREZHMsShERERERERERkc2xKEVERERERERERDbHohQREREREREREdkci1JERERERERERGRzLEoREREREREREZHNsShFREREREREREQ2x6IUERERERERERHZHItSRERERERERERkcyxKERERERERERGRzbEoRURERERERERENseiFBERERERERER2RyLUkREREREREREZHMsShERERERERERkc2xKEVERERERERERDanEh3AHsmyDAAoKysTnISI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sk6nkzt27Cj/4Q9/aLRFLq9969i7d2+TP9/nzZsny3LrXeeTJ0/Kw4cPl7VarRwaGiqvWLHCVm+RboPjpdbF8ZJ94XjJdjheEoPjJdtpC+MlSZZl+d7nWxERERERERERETUfe0oREREREREREZHNsShFREREREREREQ2x6IUERERERERERHZHItSRERERERERERkcyxKERERERERERGRzbEoRURERERERERENseiFBERERERERER2RyLUkREREREREREZHMsShGRcCNHjsTSpUut9vyZmZmQJAkpKSlWew1baUvvhYiIiJqP46Xma0vvhaitY1GKiFrd/PnzIUkSnn766Z89FhsbC0mSMH/+fMt9mzdvxuuvv27DhPdm7dq18Pb2FvLaYWFhyM/PR69evYS8PhEREbUOjpesh+MlIsfBohQRWUVYWBji4+NRXV1tua+mpgYbNmxAeHh4o2N9fHzg4eFh64jCGQwGGI3GFp2jVCoRFBQElUplpVRERERkKxwv3RnHS0RtG4tSRGQV/fv3R1hYGDZv3my5b/PmzQgPD0e/fv0aHfvT6egRERH485//jIULF8LDwwPh4eH46KOPbvt6RqMRb731Fjp37gytVovw8HC88cYbTR7b1Cd3W7duhSRJlq9PnjyJBx98EB4eHvD09MSAAQNw7Ngx7Nu3DwsWLEBpaSkkSYIkSXjttdcAALW1tfjNb36D0NBQuLm5YciQIdi3b9/PXnfbtm3o0aMHtFotsrKyfpbvxo0bmD17Nvz9/eHi4oIuXbpgzZo1AH4+Hd38KetPb+bXvVMmIiIiEofjJY6XiJwdi1JEZDULFy60DA4AYPXq1ViwYEGzzv3rX/+KgQMH4sSJE3j22WfxzDPPIC0t7ZbHL1u2DCtWrMArr7yCs2fPYsOGDQgMDLzr7LNnz0b79u1x9OhRJCcn43e/+x3UajWGDRuGv//97/D09ER+fj7y8/Pxm9/8BgAQFxeHxMRExMfH49SpU5g+fTrGjRuHixcvWp63qqoKb775Jj7++GOcOXMGAQEBP3tt83v49ttvce7cOaxcuRJ+fn5N5vzHP/5hyZGfn48lS5YgICAAUVFRzc5ERERE4nC8xPESkVOTiYha2bx58+TJkyfLhYWFslarlTMzM+XMzExZp9PJ165dkydPnizPmzfPcvwDDzwgL1myxPJ1hw4d5CeffNLytdFolAMCAuSVK1c2+XplZWWyVquV//3vfzf5eEZGhgxAPnHihCzLsrxmzRrZy8ur0TFbtmyRb/6R6OHhIa9du7bJ52vq/CtXrshKpVLOzc1tdP+oUaPkZcuWWc4DIKekpDT5vGYTJ06UFyxY0Kz3crMvv/xS1ul0ckJCQrMzERERkRgcL/2I4yUi58VFtkRkNf7+/pgwYQLWrl0LWZYxYcKEW36C9VN9+vSx/LskSQgKCkJhYWGTx547dw61tbUYNWpUq+QGgBdeeAG//OUv8emnn2L06NGYPn06OnXqdMvjT58+DYPBgK5duza6v7a2Fr6+vpavNRpNo/fWlGeeeQbTpk3D8ePHMWbMGEyZMgXDhg277TknTpzAnDlz8P777yMmJqZFmYiIiEgcjpc4XiJyZixKEZFVLVy4EHFxcQCADz74oNnnqdXqRl9LknTLJpcuLi4tyqRQKCDLcqP79Hp9o69fe+01PPHEE/jmm2/w7bff4o9//CPi4+Px6KOPNvmcFRUVUCqVSE5OhlKpbPSYu7t7o6w392Joyvjx43HlyhXs2LEDu3btwqhRoxAbG4u33367yeMLCgowadIk/PKXv8SiRYtanImIiIjE4niJ4yUiZ8WeUkRkVePGjUNdXR30ej3Gjh1rldfo0qULXFxcsHv37mYd7+/vj/LyclRWVlruMzfCvFnXrl3x/PPP4/vvv8fUqVMt/R40Gg0MBkOjY/v16weDwYDCwkJ07ty50S0oKKjF78nf3x/z5s3DunXr8Pe///2WjUtramowefJkREVF4Z133rFqJiIiIrIOjpc4XiJyVpwpRURWpVQqce7cOcu/W4NOp8PLL7+M3/72t9BoNIiJicG1a9dw5syZRp+EmQ0ZMgSurq74/e9/j8WLFyMpKQlr1661PF5dXY2XXnoJjz32GCIjI5GTk4OjR49i2rRpAEy73VRUVGD37t3o27cvXF1d0bVrV8yePRtz587FX//6V/Tr1w/Xrl3D7t270adPH0yYMKHZ7+fVV1/FgAED0LNnT9TW1mL79u3o3r17k8f++te/RnZ2Nnbv3o1r165Z7vfx8WnVTERERGQ9HC9xvETkrDhTioisztPTE56enlZ9jVdeeQUvvvgiXn31VXTv3h0zZsy4ZU8FHx8frFu3Djt27EDv3r2xceNGyzbFgGkweP36dcydOxddu3bF448/jvHjx+N///d/AQDDhg3D008/jRkzZsDf3x9vvfUWAGDNmjWYO3cuXnzxRXTr1g1TpkzB0aNHER4e3qL3otFosGzZMvTp0wf3338/lEol4uPjmzx2//79yM/PR48ePRAcHGy5HTp0qFUzERERkXVxvMTxEpEzkuSfLhQmIiIiIiIiIiKyMs6UIiIiIiIiIiIim2NRioiIiIiIiIiIbI5FKSIiIiIiIiIisjkWpYiIiIiIiIiIyOZYlCIiIiIiIiIiIptjUYqIiIiIiIiIiGyORSkiIiIiIiIiIrI5FqWIiIiIiIiIiMjmWJQiIiIiIiIiIiKbY1GKiIiIiIiIiIhsjkUpIiIiIiIiIiKyORaliIiIiIiIiIjI5v4fEQwZdIM+iEYAAAAASUVORK5CYII=\",\n      \"text/plain\": [\n       \"<Figure size 1200x600 with 2 Axes>\"\n      ]\n     },\n     \"metadata\": {},\n     \"output_type\": \"display_data\"\n    }\n   ],\n   \"source\": [\n    \"fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6))\\n\",\n    \"\\n\",\n    \"ax1.plot(min_clusters, con_time, label='k-means-constrained')\\n\",\n    \"\\n\",\n    \"ax1.set_xlabel('Min cluster size')\\n\",\n    \"ax1.set_ylabel('Time (s)')\\n\",\n    \"#ax1.set_title('First Plot')\\n\",\n    \"ax1.legend()\\n\",\n    \"\\n\",\n    \"ax2.plot(min_clusters, con_mem, label='k-means-constrained')\\n\",\n    \"\\n\",\n    \"ax2.set_xlabel('Min cluster size')\\n\",\n    \"ax2.set_ylabel('Peak memory (bytes)')\\n\",\n    \"#ax2.set_title('Second Plot')\\n\",\n    \"ax2.legend()\\n\",\n    \"\\n\",\n    \"plt.tight_layout()\\n\",\n    \"\\n\",\n    \"plt.show()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 62,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"k-means-constrained: 100%|██████████| 9/9 [13:45<00:00, 91.77s/it] \\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"# Fixed x, d, k. Increase max_cluster\\n\",\n    \"x = 10000\\n\",\n    \"d = 10\\n\",\n    \"k = 100 #list(range(1, x//2, 10))\\n\",\n    \"min_clusters = None\\n\",\n    \"max_clusters = [100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000]\\n\",\n    \"#km_time, km_mem = list(zip(*[run_km(x, d, k)]))\\n\",\n    \"con_time, con_mem = list(zip(*[run_km_constrained(x, d, k, max_clusters=mc) for mc in tqdm(max_clusters, desc='k-means-constrained')]))\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 63,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"data\": {\n      \"image/png\": \"iVBORw0KGgoAAAANSUhEUgAABKMAAAJOCAYAAABr8MR3AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAADOA0lEQVR4nOzdeVhUdfsG8PvMxr4vAoqiILiDC264YJppvZYtmkuipa1qadpim1n+srdXWy0rK83SaFMrM81MXHEBxD0QUFAR2QRkG5iZ8/tjmFFSlGWYw8zcn+viel9mzjnzICmHe77P8xVEURRBRERERERERERkBjKpCyAiIiIiIiIiItvBMIqIiIiIiIiIiMyGYRQREREREREREZkNwygiIiIiIiIiIjIbhlFERERERERERGQ2DKOIiIiIiIiIiMhsGEYREREREREREZHZMIwiIiIiIiIiIiKzYRhFRERERERERERmwzCKiIiIiIiIiIjMhmEUERERETXKrl27MGbMGAQEBEAQBGzcuLFB57/++usQBOG6Dycnp+YpmIiIiFoEhlFERERE1ChlZWUIDw/Hxx9/3Kjz58+fj4sXL9b66NKlC8aNG2fiSomIiKglYRhFRERERI0yevRoLF68GPfee+8Nn1er1Zg/fz5at24NJycn9OvXD3FxccbnnZ2d4efnZ/y4dOkSTp48ienTp5vpKyAiIiIpMIwiIiIiomYxa9YsxMfHIzY2FkePHsW4ceMwatQonD59+obHf/HFFwgNDcXgwYPNXCkRERGZE8MoIiIiIjK5rKwsrFq1Cj/++CMGDx6M4OBgzJ8/H4MGDcKqVauuO76yshJr167lqigiIiIboJC6ACIiIiKyPseOHYNWq0VoaGitx9VqNby8vK47fsOGDbhy5QqmTp1qrhKJiIhIIgyjiIiIiMjkSktLIZfLkZiYCLlcXus5Z2fn647/4osv8J///AetWrUyV4lEREQkEYZRRERERGRyPXv2hFarRW5u7i1nQJ05cwY7duzAr7/+aqbqiIiISEoMo4iIiIioUUpLS5GWlmb8/MyZM0hOToanpydCQ0MxefJkxMTEYNmyZejZsyfy8vKwfft29OjRA3fddZfxvK+++gr+/v4YPXq0FF8GERERmZkgiqIodRFEREREZHni4uIwbNiw6x6fOnUqVq9ejerqaixevBhr1qzB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fnXUhsMXcPxCscQVERGZX6lag4dXH0JGfhlauztgzfS+cHdU3fK8nm3d4WKnQGFZFY7y308yMYZRVkj97wHmXBlFRERENqpHG3eMjQiAKAL/9/upBs0rJSKydGqNFo+tScDR88XwdFJhzfS+8HdzqNe5SrkMgzp6AwDiuKsemRjDKCtkbNP718yoCoZRREREZIPm3xEGlUKG+IwC7OAvVERkI7Q6EXO/T8a+9AI4qeRY/XAkgn2cG3QN49yoVM6NItNiGGWFrs6M4gBzIiIiojYejngkqj0A4K3N/0Cj5T0REVk3URTx6i/HsflYDlRyGT6P6YMebdwbfJ0hofowKvlcES6XVZm4SrJlDKOskHE3PRVnRhEREREBwFPDguHhqERabim+TzgndTlERM3qvW2pWHcgC4IAvD8hAlEh3o26jr+bAzr5uUAUgV2nuTqKTIdhlBUyDjBXcDc9IiIiIgBwtVfimeEdAeh/SStVaySuiIioeazaewYf/p0GAHjznm64s7t/k643lK161AwYRlkhtukRERERXW9Sv3Zo7+2E/NIqfLYzXepyiIhM7pfkC1j020kAwLO3h+Kh/u2afM3oUF8AwK7UPOh03ASCTINhlBUytukpa7fpcYA5ERER2TKVQoYXRnUCAKzcnYGLxRUSV0REZDpxKbmY98MRAMC0gUGYfVuISa7bu50HnFRy5JdW4UR2iUmuScQwygpdXRklq/lftukRERERAcAdXVshMsgDldU6LPszVepyiIhMIjHzMp78NgkanYi7wwPw2n+6QBAEk1xbpZAZZ07FcUdSMhGGUVao7jY9hlFERERk2wRBwEt3dgYA/Jx0HieyiyWuiIioaVIvXcEjqw+holqLIaE+WDouHDKZaYIog+gwfase50aRqTCMskLGNj0FZ0YRERER/VvPth4YEx4AUQTe2nwKosgZKERkmc5fLkfMlwdRXFGNiEB3fPpQL6gUpv813zDEPCnrMorLq01+fbI9DKOskHE3PSV30yMiIiK6kefvCINKLsPetALE8Z1+IrJABaVqxHx5EDkllQjxdcaqaZFwVCma5bVauzugo68zdCKwO43/ZlLTMYyyQte36clqPU5ERERk6wI9HTEtKggAsGTzKWi0XEFORJajVK3Bw6sPISO/DAFu9vhmel94OKma9TWja1ZH7UxhGEVNxzDKyoii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JYorqnHkfBF6t/OUuiS6gUaFUQDQu3dv9O7du9Zjd911V5MLovozhEh2jZ0ZVdPeV8GZUURERGaTlJSEVatW4bvvvoNMJkNMTAzee+89dOrUyXjMvffei8jISAmrJCIiskxymYDBHb2x6ehFxKXkMYxqoerd3/X222+joqKiXsceOHAAv//+e6OLovqpNAwwVzSyTU/FmVFERETmFhkZidOnT2PFihW4cOECli5dWiuIAoD27dtjwoQJElVIRERk2aJrWvXiUjg3qqWq98qokydPom3bthg3bhzGjBmDPn36wMdHPxhMo9Hg5MmT2LNnD7799ltkZ2djzZo1zVY06TW1Tc+wMophFBERkXlotVp89dVXuPvuu+Hh4VHncU5OTli1apUZKyMiIrIeQ0K9AQDHLhQj74oaPi52EldE/1bvJTVr1qzBX3/9herqakyaNAl+fn5QqVRwcXGBnZ0devbsia+++goxMTH4559/MGTIkOasm9D0Aeb2nBlFRERkVnK5HI8//jiKioqkLoWIiMhq+brYo2uAKwBg92mujmqJGjQzKjw8HCtXrsRnn32Go0ePIjMzExUVFfD29kZERAS8vb2bq066gathVONWRjmoDGEUZ0YRERGZS7du3ZCRkYH27dtLXQoREZHVig7zwYnsEsSl5OG+Xm2kLof+pVEDzGUyGSIiIhAREWHicqgh1JqaNj1FI3fTq5k1VcGVUURERGazePFizJ8/H2+++SZ69+4NJyenWs+7urpKVBkREZH1iA7zxcc70rHrdB60OhFymSB1SXSNRu+mR9Jrapve1ZVRDKOIiIjM5c477wQA3H333RCEqzfGoihCEARotfy5TERE1FQ9A93hYq9AUXk1jp4vQs+2dc9qJPNjGGXBmtqmZxxgrmGbHhERkbns2LFD6hKIiIisnkIuw+CO3th8LAdxKXkMo1oYhlEWzNBeZ9fYMMowwLyK78ASERGZy9ChQ6UugYiIyCZEh/rqw6jUPMy9PVTqcugajevvohbBMHi88W16+vMqNQyjiIiIzKmoqAjLli3DjBkzMGPGDLz33nsoLi5u0DWWLFmCyMhIuLi4wNfXF2PHjkVKSkq9z4+NjYUgCBg7dmwDqyciIrIMQ8N8AABHzxehoFQtcTV0rSaFUWlpadi6dSsqKioA6GcdkPkY2/QaOcDc2KbHmVFERERm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z5499cMPP6h9+/by8vKSJM2fP19TpkzRO++8oy5dumjz5s2699571aBBA40ZM8b+2k899ZRef/11denSRT4+Pme993//+1+98cYbWrhwodq3b6+MjAxt3br1nHXedtttuuGGG+x/T0xM1KhRo5SQkHBJNQEAAOdj7cTaCYAkAwAuw5gxY4zhw4cbWVlZhre3t7F//35j//79ho+Pj5GdnW0MHz7cGDNmzHmfn52dbUgytm3bZr/v2LFjRpMmTYwHH3zQiIiIMF588cUL1hAfH2+MHDnyvI83a9bMeOONNwzDMIx9+/YZkozNmzfbHz9+/LghyVixYoVhGIYxbNgwY9y4ced8rXM93zAMo2XLlsaCBQuq3Pf8888b8fHxVZ735ptvXvCzvP7660br1q2NkpKSi36WM+3Zs8do1KiRMW3atGrXBAAAnI+1kw1rJwCGYRi06QG4ImFhYRo6dKjmzJmj2bNna+jQoQoNDT3ruN27d+uOO+5QixYtFBgYqObNm0uS0tPT7cc0bNhQH374oaZPn66WLVvqqaeeuuB7b9myRQMHDqyxz/Lggw9q4cKFuvrqq/XEE09o9erVFzy+sLBQe/fu1d133y1/f3/77YUXXqiyjV6SunfvfsHXuuWWW1RcXKwWLVro3nvv1aJFi1RWVnbB5+Tl5enGG2/U0KFD9fjjj19yTQAAwPlYO7F2AkCbHoAacNddd2nChAmSpHffffecxwwbNkzNmjXTzJkzFR0dLavVqg4dOqikpKTKcStXrpS7u7uOHDmiwsJCBQQEnPd9fX19q12jm5stezcMw37f74dhDhkyRAcOHNCSJUu0bNkyDRw4UOPHj9drr712ztc8ceKEJGnmzJnq1atXlcfc3d2r/L1BgwYXrC8mJkYpKSn64YcftGzZMj300EN69dVXlZSUJE9Pz7OOLy8v12233abAwEDNmDHjsmoCAADmYO3E2gmo79gZBeCK3XDDDSopKVFpaakGDx581uNHjx5VSkqKnn76aQ0cOFDt2rXT8ePHzzpu9erVeuWVV/T111/L39/fvkg7n06dOmn58uXVqjEsLEySdOTIEft957rUcFhYmMaMGaNPPvlEb775pn2xUjnnoLy83H5sRESEoqOjlZaWplatWlW5VQ7tvBS+vr4aNmyY3nrrLSUmJmrNmjXatm3bOY999NFHtW3bNi1evLjKHIWargkAANQ81k6snYD6jp1RAK6Yu7u7du3aZf/z7zVs2FAhISGaMWOGoqKilJ6eftY28oKCAo0aNUoTJ07UkCFD1KRJE/Xo0UPDhg3TzTfffM73ffbZZzVw4EC1bNlSt99+u8rKyrRkyRI9+eSTZx3r6+ur3r176+WXX1ZsbKyysrL09NNPVzlmypQp6tatm9q3b69Tp07pm2++Ubt27SRJ4eHh8vX11dKlS9WkSRP5+PgoKChI//jHPzRx4kQFBQXphhtu0KlTp7Rx40YdP35cjz32WLXP4Zw5c1ReXq5evXrJz89Pn3zyiXx9fdWsWbOzjp09e7bee+89LVq0SBaLRRkZGZJk31ZeUzUBAADHYO3E2gmo79gZBaBGBAYGKjAw8JyPubm5aeHChdq0aZM6dOigRx99VK+++mqVYx555BE1aNBAL730kiSpY8eOeumll3T//ffr0KFD53zd/v376/PPP9dXX32lq6++Wtddd53Wr19/3ho/+ugjlZWVqVu3bpo0aZJeeOGFKo97eXlp8uTJ6tSpk6699lq5u7tr4cKFkiQPDw+99dZb+uCDDxQdHa3hw4dLku655x7NmjVLs2fPVseOHdWvXz/NmTPnkn+TFhwcrJkzZyohIUGdOnXSDz/8oK+//lohISFnHZuUlKTy8nL98Y9/VFRUlP1WuSW+pmoCAACOw9qJtRNQn1mMM5uAAQAAAAAAAAdiZxQAAAAAAACchjAKAAAAAAAATkMYBQAAAAAAAKchjAIAAAAAAIDTEEYBAAAAAADAaQijAAAAAAAA4DSEUQAAAAAAAHAawigAAAAAAAA4DWEUAAAAAAAAnIYwCgAAAAAAAE5DGAUAAAAAAACnIYwCAAAAAACA0/x/RH3oBpHTPYMAAAAASUVORK5CYII=\",\n      \"text/plain\": [\n       \"<Figure size 1200x600 with 2 Axes>\"\n      ]\n     },\n     \"metadata\": {},\n     \"output_type\": \"display_data\"\n    }\n   ],\n   \"source\": [\n    \"fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6))\\n\",\n    \"\\n\",\n    \"ax1.plot(max_clusters, con_time, label='k-means-constrained')\\n\",\n    \"\\n\",\n    \"ax1.set_xlabel('Max cluster size')\\n\",\n    \"ax1.set_ylabel('Time (s)')\\n\",\n    \"#ax1.set_title('First Plot')\\n\",\n    \"ax1.legend()\\n\",\n    \"\\n\",\n    \"ax2.plot(max_clusters, con_mem, label='k-means-constrained')\\n\",\n    \"\\n\",\n    \"ax2.set_xlabel('Max cluster size')\\n\",\n    \"ax2.set_ylabel('Peak memory (bytes)')\\n\",\n    \"#ax2.set_title('Second Plot')\\n\",\n    \"ax2.legend()\\n\",\n    \"\\n\",\n    \"plt.tight_layout()\\n\",\n    \"\\n\",\n    \"plt.show()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": []\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.10.6\"\n  },\n  \"orig_nbformat\": 4\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"
  },
  {
    "path": "etc/benchmark_k_means.py",
    "content": "#!/usr/bin/env python3\n\nfrom argparse import ArgumentParser\nfrom sklearn.cluster import KMeans\nimport numpy as np\nimport time\nimport os\n\np = ArgumentParser()\np.add_argument(\"-n\", \"--data-points\", required=True, type=int, help=\"Number of data-points\")\np.add_argument(\"-d\", \"--dimensions\", required=True, type=int, help=\"Number of dimensions/features each data-point has\")\np.add_argument(\"-K\", \"--clusters\", required=True, type=int, help=\"Number of clusters\")\np.add_argument(\"-ge\", \"--min-cluster-size\", default=None, help=\"Minimum number of clusters assigned to each data-point\")\np.add_argument(\"-le\", \"--max-cluster-size\", default=None, help=\"Maximum number of clusters assigned to each data-point\")\np.add_argument(\"-s\", \"--seed\", type=int, default=42, help=\"Random state seed\")\np.add_argument(\"-i\", \"--info\", action='store_true', default=False , help=\"Print system info. `cpuinfo` is required to be installed.\")\nargs = p.parse_args()\n\nprint(f\"K-means benchmark: data-points={args.data_points}, dimensions={args.dimensions}, clusters={args.clusters}, min-cluster-size={args.min_cluster_size}, max-cluster-size={args.max_cluster_size}, seed={args.seed}\")\n\nif args.info:\n    import scipy, ortools, joblib, platform, cpuinfo, sklearn, k_means_constrained\n    print(f\"OS: {platform.platform()}\")\n    print(f\"CPU: {cpuinfo.get_cpu_info()['brand_raw']}\")\n    print(f\"CPU cores: {cpuinfo.get_cpu_info()['count']}\")\n    print(f\"k-means-constrained version: {k_means_constrained.__version__}\")\n    print(f\"numpy version: {np.__version__}\")\n    print(f\"scipy version: {scipy.__version__}\")\n    print(f\"ortools version: {ortools.__version__}\")\n    print(f\"joblib version: {joblib.__version__}\")\n    print(f\"sklearn version: {sklearn.__version__}\")\n\nnp.random.seed(args.seed)\n\nX = np.random.rand(args.data_points, args.dimensions)\n\nos.environ['OMP_NUM_THREADS'] = '10'  # Used instead of joblib/n_jobs in latest version of sklearn\n\nt = time.perf_counter()\nclf = KMeans(\n     n_clusters=args.clusters,\n     random_state=args.seed+1,\n     algorithm='lloyd',\n     init='k-means++',\n     n_init=10,\n     max_iter=300,\n     tol=0.0001,\n )\nclf.fit_predict(X)\n\ntotal_time = time.perf_counter() - t\nprint(f\"Total time: {total_time:.2f} seconds\")\n\n"
  },
  {
    "path": "etc/benchmark_k_means_constrained.py",
    "content": "#!/usr/bin/env python3\n\nfrom argparse import ArgumentParser\nimport k_means_constrained\nimport numpy as np\nimport time\nimport logging\nimport os\n\np = ArgumentParser()\np.add_argument(\"-n\", \"--data-points\", required=True, type=int, help=\"Number of data-points\")\np.add_argument(\"-d\", \"--dimensions\", required=True, type=int, help=\"Number of dimensions/features each data-point has\")\np.add_argument(\"-K\", \"--clusters\", required=True, type=int, help=\"Number of clusters\")\np.add_argument(\"-ge\", \"--min-cluster-size\", default=None, help=\"Minimum number of clusters assigned to each data-point\")\np.add_argument(\"-le\", \"--max-cluster-size\", default=None, help=\"Maximum number of clusters assigned to each data-point\")\np.add_argument(\"-s\", \"--seed\", type=int, default=42, help=\"Random state seed\")\np.add_argument(\"-i\", \"--info\", action='store_true', default=False , help=\"Print system info. `cpuinfo` is required to be installed.\")\nargs = p.parse_args()\n\n\nlogging.basicConfig(\n    level=os.environ.get('LOGLEVEL', 'DEBUG').upper()\n)\n\nprint(f\"K-mean-constrained benchmark: data-points={args.data_points}, dimensions={args.dimensions}, clusters={args.clusters}, min-cluster-size={args.min_cluster_size}, max-cluster-size={args.max_cluster_size}, seed={args.seed}\")\n\nif args.info:\n    import scipy, ortools, joblib, platform, cpuinfo, sklearn, k_means_constrained\n    print(f\"OS: {platform.platform()}\")\n    print(f\"CPU: {cpuinfo.get_cpu_info()['brand_raw']}\")\n    print(f\"CPU cores: {cpuinfo.get_cpu_info()['count']}\")\n    print(f\"k-means-constrained version: {k_means_constrained.__version__}\")\n    print(f\"numpy version: {np.__version__}\")\n    print(f\"scipy version: {scipy.__version__}\")\n    print(f\"ortools version: {ortools.__version__}\")\n    print(f\"joblib version: {joblib.__version__}\")\n    print(f\"sklearn version: {sklearn.__version__}\")\n\nnp.random.seed(args.seed)\n\nX = np.random.rand(args.data_points, args.dimensions)\n\nt = time.perf_counter()\nclf = k_means_constrained.KMeansConstrained(\n     n_clusters=args.clusters,\n     size_min=int(args.min_cluster_size) if args.min_cluster_size else None,\n     size_max=int(args.max_cluster_size) if args.max_cluster_size else None,\n     random_state=args.seed+1,\n     #algorithm='lloyd', # implied\n     init='k-means++',\n     n_init=10,\n     max_iter=300,\n     tol=0.0001,\n     n_jobs=10,\n )\nclf.fit_predict(X)\n\ntotal_time = time.perf_counter() - t\nprint(f\"Total time: {total_time:.2f} seconds\")\n\n"
  },
  {
    "path": "etc/cython_benchmark.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 20,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"import numpy as np\\n\",\n    \"from ortools.graph.pywrapgraph import SimpleMinCostFlow\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 98,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# Create graph\\n\",\n    \"# 1 start and 1 stop. All intercenected via some nodes\\n\",\n    \"\\n\",\n    \"seed = 1\\n\",\n    \"n_int = int(1e7) # N intconecting_nodes\\n\",\n    \"\\n\",\n    \"edges = np.concatenate([\\n\",\n    \"    np.stack([0*np.ones(n_int), np.arange(2, n_int+2)], axis=1),\\n\",\n    \"    np.stack([np.arange(2, n_int+2), 1*np.ones(n_int)], axis=1)\\n\",\n    \"]).astype('int32')\\n\",\n    \"\\n\",\n    \"costs = np.random.randint(low=0, high=100, size=len(edges)).astype('int32')\\n\",\n    \"capacities = np.random.randint(low=1, high=n_int, size=len(edges)).astype('int32')\\n\",\n    \"\\n\",\n    \"supplies = np.concatenate([[1, -1], np.zeros(n_int)]).astype('int32')\\n\",\n    \"\\n\",\n    \"N_edges = edges.shape[0]\\n\",\n    \"N_nodes = len(supplies)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Current interface\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 99,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"min_cost_flow = SimpleMinCostFlow()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 100,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"CPU times: user 1min 15s, sys: 2.72 s, total: 1min 18s\\n\",\n      \"Wall time: 1min 30s\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%time\\n\",\n    \"for i in range(0, N_edges):\\n\",\n    \"    min_cost_flow.AddArcWithCapacityAndUnitCost(int(edges[i, 0]), int(edges[i, 1]),\\n\",\n    \"                                                int(capacities[i]), int(costs[i]))\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 101,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"CPU times: user 16.2 s, sys: 84 ms, total: 16.3 s\\n\",\n      \"Wall time: 18.2 s\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%time\\n\",\n    \"for i in range(0, N_nodes):\\n\",\n    \"    min_cost_flow.SetNodeSupply(i, int(supplies[i]))\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 102,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"CPU times: user 16.6 s, sys: 3.89 s, total: 20.5 s\\n\",\n      \"Wall time: 23.3 s\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%time\\n\",\n    \"if min_cost_flow.Solve() != min_cost_flow.OPTIMAL:\\n\",\n    \"    raise Exception('There was an issue with the min cost flow input.')\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 103,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"CPU times: user 19.7 s, sys: 504 ms, total: 20.2 s\\n\",\n      \"Wall time: 23.4 s\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%time\\n\",\n    \"flow = np.array([min_cost_flow.Flow(i) for i in range(N_edges)])\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Cython interface\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 104,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"min_cost_flow_vec = SimpleMinCostFlowVectorized()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 105,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"CPU times: user 11.3 s, sys: 664 ms, total: 12 s\\n\",\n      \"Wall time: 12.4 s\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%time\\n\",\n    \"min_cost_flow_vec.AddArcWithCapacityAndUnitCostVectorized(edges[:,0], edges[:,1], capacities, costs)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 106,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"CPU times: user 3.37 s, sys: 12 ms, total: 3.38 s\\n\",\n      \"Wall time: 3.39 s\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%time\\n\",\n    \"min_cost_flow_vec.SetNodeSupplyVectorized(np.arange(N_nodes, dtype='int32'), supplies)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 107,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"CPU times: user 15.2 s, sys: 3.63 s, total: 18.9 s\\n\",\n      \"Wall time: 20 s\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%time\\n\",\n    \"if min_cost_flow_vec.Solve() != min_cost_flow_vec.OPTIMAL:\\n\",\n    \"    raise Exception('There was an issue with the min cost flow input.')\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 108,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"CPU times: user 8.31 s, sys: 296 ms, total: 8.61 s\\n\",\n      \"Wall time: 9.07 s\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%time\\n\",\n    \"flow = min_cost_flow_vec.FlowVectorized(np.arange(N_edges, dtype='int32'))\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"| Step          | Current interface | Cython interface |\\n\",\n    \"|---------------|-------------------|------------------|\\n\",\n    \"| AddArc        | 90 s              | 12.4 s           |\\n\",\n    \"| SetNodeSupply | 18.2 s            | 3.39 ms          |\\n\",\n    \"| Solve         | 23.3 s            | 20 s             |\\n\",\n    \"| Flow          | 23.4 s            | 9.07 s           |\\n\",\n    \"| **Total**         | **154.9 s**           | **41.1 s**          |\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Time comparision\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Cython interface code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 76,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%%cython\\n\",\n    \"import numpy as np\\n\",\n    \"cimport numpy as np\\n\",\n    \"cimport cython\\n\",\n    \"\\n\",\n    \"from ortools.graph._pywrapgraph import \\\\\\n\",\n    \"    SimpleMinCostFlow_AddArcWithCapacityAndUnitCost,\\\\\\n\",\n    \"    SimpleMinCostFlow_SetNodeSupply,\\\\\\n\",\n    \"    SimpleMinCostFlow_Flow\\n\",\n    \"\\n\",\n    \"DTYPE = np.int32\\n\",\n    \"ctypedef np.int32_t DTYPE_t\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"@cython.boundscheck(False)\\n\",\n    \"@cython.wraparound(False)\\n\",\n    \"def SimpleMinCostFlow_AddArcWithCapacityAndUnitCostVectorized(\\n\",\n    \"        self,\\n\",\n    \"        np.ndarray[DTYPE_t, ndim=1] tail,\\n\",\n    \"        np.ndarray[DTYPE_t, ndim=1] head,\\n\",\n    \"        np.ndarray[DTYPE_t, ndim=1] capacity,\\n\",\n    \"        np.ndarray[DTYPE_t, ndim=1] unit_cost):\\n\",\n    \"\\n\",\n    \"    cdef int len = tail.shape[0]\\n\",\n    \"\\n\",\n    \"    assert tail.dtype == DTYPE\\n\",\n    \"    assert head.dtype == DTYPE\\n\",\n    \"    assert capacity.dtype == DTYPE\\n\",\n    \"    assert unit_cost.dtype == DTYPE\\n\",\n    \"    assert head.shape[0] == len\\n\",\n    \"    assert capacity.shape[0] == len\\n\",\n    \"    assert unit_cost.shape[0] == len\\n\",\n    \"\\n\",\n    \"    for i in range(len):\\n\",\n    \"        SimpleMinCostFlow_AddArcWithCapacityAndUnitCost(self, tail[i], head[i], capacity[i], unit_cost[i])\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"@cython.boundscheck(False)\\n\",\n    \"@cython.wraparound(False)\\n\",\n    \"def SimpleMinCostFlow_SetNodeSupplyVectorized(self,\\n\",\n    \"                                              np.ndarray[DTYPE_t, ndim=1] node,\\n\",\n    \"                                              np.ndarray[DTYPE_t, ndim=1] supply):\\n\",\n    \"    cdef int len = node.shape[0]\\n\",\n    \"\\n\",\n    \"    assert node.dtype == DTYPE\\n\",\n    \"    assert supply.dtype == DTYPE\\n\",\n    \"    assert supply.shape[0] == len\\n\",\n    \"\\n\",\n    \"    for i in range(len):\\n\",\n    \"        SimpleMinCostFlow_SetNodeSupply(self, node[i], supply[i])\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"@cython.boundscheck(False)\\n\",\n    \"@cython.wraparound(False)\\n\",\n    \"def SimpleMinCostFlow_FlowVectorized(self,\\n\",\n    \"                                     np.ndarray[DTYPE_t, ndim=1] arc):\\n\",\n    \"\\n\",\n    \"    cdef int len = arc.shape[0]\\n\",\n    \"\\n\",\n    \"    assert arc.dtype == DTYPE\\n\",\n    \"\\n\",\n    \"    cdef np.ndarray flow = np.zeros(len, dtype=DTYPE)\\n\",\n    \"\\n\",\n    \"    for i in range(len):\\n\",\n    \"        flow[i] = SimpleMinCostFlow_Flow(self, arc[i])\\n\",\n    \"\\n\",\n    \"    return flow\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 77,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class SimpleMinCostFlowVectorized(SimpleMinCostFlow):\\n\",\n    \"\\n\",\n    \"    def AddArcWithCapacityAndUnitCostVectorized(self, tail, head, capacity, unit_cost):\\n\",\n    \"        return SimpleMinCostFlow_AddArcWithCapacityAndUnitCostVectorized(self, tail, head, capacity, unit_cost)\\n\",\n    \"\\n\",\n    \"    def SetNodeSupplyVectorized(self, node, supply):\\n\",\n    \"        return SimpleMinCostFlow_SetNodeSupplyVectorized(self, node, supply)\\n\",\n    \"\\n\",\n    \"    def FlowVectorized(self, arc):\\n\",\n    \"        return SimpleMinCostFlow_FlowVectorized(self, arc)\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"creator\": \"josh\",\n  \"kernelspec\": {\n   \"display_name\": \"Python (env python3_dataiku)\",\n   \"language\": \"python\",\n   \"name\": \"py-dku-venv-python3_dataiku\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.6.4\"\n  },\n  \"tags\": []\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "k_means_constrained/__init__.py",
    "content": "\n__all__ = ['KMeansConstrained']\n__version__ = '0.9.0'\n\nfrom .k_means_constrained_ import KMeansConstrained\n\n"
  },
  {
    "path": "k_means_constrained/k_means_constrained_.py",
    "content": "\"\"\"k-means-constrained\"\"\"\n\n# Authors: Josh Levy-Kramer <josh@levykramer.co.uk>\n#          Gael Varoquaux <gael.varoquaux@normalesup.org>\n#          Thomas Rueckstiess <ruecksti@in.tum.de>\n#          James Bergstra <james.bergstra@umontreal.ca>\n#          Jan Schlueter <scikit-learn@jan-schlueter.de>\n#          Nelle Varoquaux\n#          Peter Prettenhofer <peter.prettenhofer@gmail.com>\n#          Olivier Grisel <olivier.grisel@ensta.org>\n#          Mathieu Blondel <mathieu@mblondel.org>\n#          Robert Layton <robertlayton@gmail.com>\n# License: BSD 3 clause\n\nimport warnings\nimport numpy as np\nimport scipy.sparse as sp\nfrom .sklearn_import.metrics.pairwise import euclidean_distances\nfrom .sklearn_import.utils.extmath import row_norms, squared_norm, cartesian\nfrom .sklearn_import.utils.validation import check_array, check_random_state, as_float_array, check_is_fitted\nfrom joblib import Parallel\nfrom joblib import delayed\n\n# Internal scikit learn methods imported into this project\nfrom k_means_constrained.sklearn_import.cluster._k_means import _centers_dense, _centers_sparse\nfrom k_means_constrained.sklearn_import.cluster.k_means_ import _validate_center_shape, _tolerance, KMeans, \\\n    _init_centroids\n\nfrom ortools.graph.python.min_cost_flow import SimpleMinCostFlow\n\n\ndef k_means_constrained(X, n_clusters, size_min=None, size_max=None, init='k-means++',\n                        n_init=10, max_iter=300, verbose=False,\n                        tol=1e-4, random_state=None, copy_x=True, n_jobs=1,\n                        return_n_iter=False):\n    \"\"\"K-Means clustering with minimum and maximum cluster size constraints.\n\n    Read more in the :ref:`User Guide <k_means>`.\n\n    Parameters\n    ----------\n    X : array-like, shape (n_samples, n_features)\n        The observations to cluster.\n\n    size_min : int, optional, default: None\n        Constrain the label assignment so that each cluster has a minimum\n        size of size_min. If None, no constrains will be applied\n\n    size_max : int, optional, default: None\n        Constrain the label assignment so that each cluster has a maximum\n        size of size_max. If None, no constrains will be applied\n\n    n_clusters : int\n        The number of clusters to form as well as the number of\n        centroids to generate.\n\n    init : {'k-means++', 'random', or ndarray, or a callable}, optional\n        Method for initialization, default to 'k-means++':\n\n        'k-means++' : selects initial cluster centers for k-mean\n        clustering in a smart way to speed up convergence. See section\n        Notes in k_init for more details.\n\n        'random': generate k centroids from a Gaussian with mean and\n        variance estimated from the data.\n\n        If an ndarray is passed, it should be of shape (n_clusters, n_features)\n        and gives the initial centers.\n\n        If a callable is passed, it should take arguments X, k and\n        and a random state and return an initialization.\n\n    n_init : int, optional, default: 10\n        Number of time the k-means algorithm will be run with different\n        centroid seeds. The final results will be the best output of\n        n_init consecutive runs in terms of inertia.\n\n    max_iter : int, optional, default 300\n        Maximum number of iterations of the k-means algorithm to run.\n\n    verbose : boolean, optional\n        Verbosity mode.\n\n    tol : float, optional\n        Relative tolerance with regards to Frobenius norm of the difference\n        in the cluster centers of two consecutive iterations to declare\n        convergence.\n\n    random_state : int, RandomState instance or None, optional, default: None\n        If int, random_state is the seed used by the random number generator;\n        If RandomState instance, random_state is the random number generator;\n        If None, the random number generator is the RandomState instance used\n        by `np.random`.\n\n    copy_x : boolean, optional\n        When pre-computing distances it is more numerically accurate to center\n        the data first.  If copy_x is True, then the original data is not\n        modified.  If False, the original data is modified, and put back before\n        the function returns, but small numerical differences may be introduced\n        by subtracting and then adding the data mean.\n\n    n_jobs : int\n        The number of jobs to use for the computation. This works by computing\n        each of the n_init runs in parallel.\n\n        If -1 all CPUs are used. If 1 is given, no parallel computing code is\n        used at all, which is useful for debugging. For n_jobs below -1,\n        (n_cpus + 1 + n_jobs) are used. Thus for n_jobs = -2, all CPUs but one\n        are used.\n\n    return_n_iter : bool, optional\n        Whether or not to return the number of iterations.\n\n    Returns\n    -------\n    centroid : float ndarray with shape (k, n_features)\n        Centroids found at the last iteration of k-means.\n\n    label : integer ndarray with shape (n_samples,)\n        label[i] is the code or index of the centroid the\n        i'th observation is closest to.\n\n    inertia : float\n        The final value of the inertia criterion (sum of squared distances to\n        the closest centroid for all observations in the training set).\n\n    best_n_iter : int\n        Number of iterations corresponding to the best results.\n        Returned only if `return_n_iter` is set to True.\n\n    \"\"\"\n    if sp.issparse(X):\n        raise NotImplementedError(\"Not implemented for sparse X\")\n\n    if n_init <= 0:\n        raise ValueError(\"Invalid number of initializations.\"\n                         \" n_init=%d must be bigger than zero.\" % n_init)\n    random_state = check_random_state(random_state)\n\n    if max_iter <= 0:\n        raise ValueError('Number of iterations should be a positive number,'\n                         ' got %d instead' % max_iter)\n\n    X = as_float_array(X, copy=copy_x)\n    tol = _tolerance(X, tol)\n\n    # Validate init array\n    if hasattr(init, '__array__'):\n        init = check_array(init, dtype=X.dtype.type)\n        _validate_center_shape(X, n_clusters, init)\n\n        if n_init != 1:\n            warnings.warn(\n                'Explicit initial center position passed: '\n                'performing only one init in k-means instead of n_init=%d'\n                % n_init, RuntimeWarning, stacklevel=2)\n            n_init = 1\n\n    # subtract of mean of x for more accurate distance computations\n    if not sp.issparse(X):\n        X_mean = X.mean(axis=0)\n        # The copy was already done above\n        X -= X_mean\n\n        if hasattr(init, '__array__'):\n            init -= X_mean\n\n    # precompute squared norms of data points\n    x_squared_norms = row_norms(X, squared=True)\n\n    best_labels, best_inertia, best_centers = None, None, None\n\n    if n_jobs == 1:\n        # For a single thread, less memory is needed if we just store one set\n        # of the best results (as opposed to one set per run per thread).\n        for it in range(n_init):\n            # run a k-means once\n            labels, inertia, centers, n_iter_ = kmeans_constrained_single(\n                X, n_clusters,\n                size_min=size_min, size_max=size_max,\n                max_iter=max_iter, init=init, verbose=verbose, tol=tol,\n                x_squared_norms=x_squared_norms, random_state=random_state)\n            # determine if these results are the best so far\n            if best_inertia is None or inertia < best_inertia:\n                best_labels = labels.copy()\n                best_centers = centers.copy()\n                best_inertia = inertia\n                best_n_iter = n_iter_\n    else:\n        # parallelisation of k-means runs\n        seeds = random_state.randint(np.iinfo(np.int32).max, size=n_init)\n        results = Parallel(n_jobs=n_jobs, verbose=0)(\n            delayed(kmeans_constrained_single)(X, n_clusters,\n                                               size_min=size_min, size_max=size_max,\n                                               max_iter=max_iter, init=init,\n                                               verbose=verbose, tol=tol,\n                                               x_squared_norms=x_squared_norms,\n                                               # Change seed to ensure variety\n                                               random_state=seed)\n            for seed in seeds)\n        # Get results with the lowest inertia\n        labels, inertia, centers, n_iters = zip(*results)\n        best = np.argmin(inertia)\n        best_labels = labels[best]\n        best_inertia = inertia[best]\n        best_centers = centers[best]\n        best_n_iter = n_iters[best]\n\n    if not sp.issparse(X):\n        if not copy_x:\n            X += X_mean\n        best_centers += X_mean\n\n    if return_n_iter:\n        return best_centers, best_labels, best_inertia, best_n_iter\n    else:\n        return best_centers, best_labels, best_inertia\n\n\ndef kmeans_constrained_single(X, n_clusters, size_min=None, size_max=None,\n                              max_iter=300, init='k-means++',\n                              verbose=False, x_squared_norms=None,\n                              random_state=None, tol=1e-4):\n    \"\"\"A single run of k-means constrained, assumes preparation completed prior.\n\n    Parameters\n    ----------\n    X : array-like of floats, shape (n_samples, n_features)\n        The observations to cluster.\n\n    size_min : int, optional, default: None\n        Constrain the label assignment so that each cluster has a minimum\n        size of size_min. If None, no constrains will be applied\n\n    size_max : int, optional, default: None\n        Constrain the label assignment so that each cluster has a maximum\n        size of size_max. If None, no constrains will be applied\n\n    n_clusters : int\n        The number of clusters to form as well as the number of\n        centroids to generate.\n\n    max_iter : int, optional, default 300\n        Maximum number of iterations of the k-means algorithm to run.\n\n    init : {'k-means++', 'random', or ndarray, or a callable}, optional\n        Method for initialization, default to 'k-means++':\n\n        'k-means++' : selects initial cluster centers for k-mean\n        clustering in a smart way to speed up convergence. See section\n        Notes in k_init for more details.\n\n        'random': generate k centroids from a Gaussian with mean and\n        variance estimated from the data.\n\n        If an ndarray is passed, it should be of shape (k, p) and gives\n        the initial centers.\n\n        If a callable is passed, it should take arguments X, k and\n        and a random state and return an initialization.\n\n    tol : float, optional\n        Relative tolerance with regards to Frobenius norm of the difference\n        in the cluster centers of two consecutive iterations to declare\n        convergence.\n\n    verbose : boolean, optional\n        Verbosity mode\n\n    x_squared_norms : array\n        Precomputed x_squared_norms.\n\n    random_state : int, RandomState instance or None, optional, default: None\n        If int, random_state is the seed used by the random number generator;\n        If RandomState instance, random_state is the random number generator;\n        If None, the random number generator is the RandomState instance used\n        by `np.random`.\n\n    Returns\n    -------\n    centroid : float ndarray with shape (k, n_features)\n        Centroids found at the last iteration of k-means.\n\n    label : integer ndarray with shape (n_samples,)\n        label[i] is the code or index of the centroid the\n        i'th observation is closest to.\n\n    inertia : float\n        The final value of the inertia criterion (sum of squared distances to\n        the closest centroid for all observations in the training set).\n\n    n_iter : int\n        Number of iterations run.\n    \"\"\"\n    if sp.issparse(X):\n        raise NotImplementedError(\"Not implemented for sparse X\")\n\n    random_state = check_random_state(random_state)\n    n_samples = X.shape[0]\n\n    best_labels, best_inertia, best_centers = None, None, None\n    # init\n    centers = _init_centroids(X, n_clusters, init, random_state=random_state, x_squared_norms=x_squared_norms)\n    if verbose:\n        print(\"Initialization complete\")\n\n    # Allocate memory to store the distances for each sample to its\n    # closer center for reallocation in case of ties\n    distances = np.zeros(shape=(n_samples,), dtype=X.dtype)\n\n    # Determine min and max sizes if non given\n    if size_min is None:\n        size_min = 0\n    if size_max is None:\n        size_max = n_samples  # Number of data points\n\n    # Check size min and max\n    if not ((size_min >= 0) and (size_min <= n_samples)\n            and (size_max >= 0) and (size_max <= n_samples)):\n        raise ValueError(\"size_min and size_max must be a positive number smaller \"\n                         \"than the number of data points or `None`\")\n    if size_max < size_min:\n        raise ValueError(\"size_max must be larger than size_min\")\n    if size_min * n_clusters > n_samples:\n        raise ValueError(\"The product of size_min and n_clusters cannot exceed the number of samples (X)\")\n    if size_max * n_clusters < n_samples:\n        raise ValueError(\"The product of size_max and n_clusters must be larger than or equal the number of samples (X)\")\n\n    # iterations\n    for i in range(max_iter):\n        centers_old = centers.copy()\n        # labels assignment is also called the E-step of EM\n        labels, inertia = \\\n            _labels_constrained(X, centers, size_min, size_max, distances=distances)\n\n        # computation of the means is also called the M-step of EM\n        if sp.issparse(X):\n            centers = _centers_sparse(X, labels, n_clusters, distances)\n        else:\n            centers = _centers_dense(X, labels, n_clusters, distances)\n\n        if verbose:\n            print(\"Iteration %2d, inertia %.3f\" % (i, inertia))\n\n        if best_inertia is None or inertia < best_inertia:\n            best_labels = labels.copy()\n            best_centers = centers.copy()\n            best_inertia = inertia\n\n        center_shift_total = squared_norm(centers_old - centers)\n        if center_shift_total <= tol:\n            if verbose:\n                print(\"Converged at iteration %d: \"\n                      \"center shift %e within tolerance %e\"\n                      % (i, center_shift_total, tol))\n            break\n\n    if center_shift_total > 0:\n        # rerun E-step in case of non-convergence so that predicted labels\n        # match cluster centers\n        best_labels, best_inertia = \\\n            _labels_constrained(X, centers, size_min, size_max, distances=distances)\n\n    return best_labels, best_inertia, best_centers, i + 1\n\n\ndef _labels_constrained(X, centers, size_min, size_max, distances):\n    \"\"\"Compute labels using the min and max cluster size constraint\n\n    This will overwrite the 'distances' array in-place.\n\n    Parameters\n    ----------\n    X : numpy array, shape (n_sample, n_features)\n        Input data.\n\n    size_min : int\n        Minimum size for each cluster\n\n    size_max : int\n        Maximum size for each cluster\n\n    centers : numpy array, shape (n_clusters, n_features)\n        Cluster centers which data is assigned to.\n\n    distances : numpy array, shape (n_samples,)\n        Pre-allocated array in which distances are stored.\n\n    Returns\n    -------\n    labels : numpy array, dtype=np.int, shape (n_samples,)\n        Indices of clusters that samples are assigned to.\n\n    inertia : float\n        Sum of squared distances of samples to their closest cluster center.\n\n    \"\"\"\n    C = centers\n\n    # Distances to each centre C. (the `distances` parameter is the distance to the closest centre)\n    # K-mean original uses squared distances but this equivalent for constrained k-means\n    D = euclidean_distances(X, C, squared=False)\n\n    edges, costs, capacities, supplies, n_C, n_X = minimum_cost_flow_problem_graph(X, C, D, size_min, size_max)\n    labels = solve_min_cost_flow_graph(edges, costs, capacities, supplies, n_C, n_X)\n\n    # cython k-means M step code assumes int32 inputs\n    labels = labels.astype(np.int32)\n\n    # Change distances in-place\n    distances[:] = D[np.arange(D.shape[0]), labels] ** 2  # Square for M step of EM\n    inertia = distances.sum()\n\n    return labels, inertia\n\n\ndef minimum_cost_flow_problem_graph(X, C, D, size_min, size_max):\n    # Setup minimum cost flow formulation graph\n    # Vertices indexes:\n    # X-nodes: [0, n(x)-1], C-nodes: [n(X), n(X)+n(C)-1], C-dummy nodes:[n(X)+n(C), n(X)+2*n(C)-1],\n    # Artificial node: [n(X)+2*n(C), n(X)+2*n(C)+1-1]\n\n    # Create indices of nodes\n    n_X = X.shape[0]\n    n_C = C.shape[0]\n    X_ix = np.arange(n_X)\n    C_dummy_ix = np.arange(X_ix[-1] + 1, X_ix[-1] + 1 + n_C)\n    C_ix = np.arange(C_dummy_ix[-1] + 1, C_dummy_ix[-1] + 1 + n_C)\n    art_ix = C_ix[-1] + 1\n\n    # Edges\n    edges_X_C_dummy = cartesian([X_ix, C_dummy_ix])  # All X's connect to all C dummy nodes (C')\n    edges_C_dummy_C = np.stack([C_dummy_ix, C_ix], axis=1)  # Each C' connects to a corresponding C (centroid)\n    edges_C_art = np.stack([C_ix, art_ix * np.ones(n_C)], axis=1)  # All C connect to artificial node\n\n    edges = np.concatenate([edges_X_C_dummy, edges_C_dummy_C, edges_C_art])\n\n    # Costs\n    costs_X_C_dummy = D.reshape(D.size)\n    costs = np.concatenate([costs_X_C_dummy, np.zeros(edges.shape[0] - len(costs_X_C_dummy))])\n\n    # Capacities - can set for max-k\n    capacities_C_dummy_C = size_max * np.ones(n_C)\n    cap_non = n_X  # The total supply and therefore wont restrict flow\n    capacities = np.concatenate([\n        np.ones(edges_X_C_dummy.shape[0]),\n        capacities_C_dummy_C,\n        cap_non * np.ones(n_C)\n    ])\n\n    # Sources and sinks\n    supplies_X = np.ones(n_X)\n    supplies_C = -1 * size_min * np.ones(n_C)  # Demand node\n    supplies_art = -1 * (n_X - n_C * size_min)  # Demand node\n    supplies = np.concatenate([\n        supplies_X,\n        np.zeros(n_C),  # C_dummies\n        supplies_C,\n        [supplies_art]\n    ])\n\n    # All arrays must be of int dtype for `SimpleMinCostFlow`\n    edges = edges.astype('int32')\n    costs = np.around(costs * 1000, 0).astype('int32')  # Times by 1000 to give extra precision\n    capacities = capacities.astype('int32')\n    supplies = supplies.astype('int32')\n\n    return edges, costs, capacities, supplies, n_C, n_X\n\n\ndef solve_min_cost_flow_graph(edges, costs, capacities, supplies, n_C, n_X):\n    # Instantiate a SimpleMinCostFlow solver.\n    min_cost_flow = SimpleMinCostFlow()\n\n    if (edges.dtype != 'int32') or (costs.dtype != 'int32') \\\n            or (capacities.dtype != 'int32') or (supplies.dtype != 'int32'):\n        raise ValueError(\"`edges`, `costs`, `capacities`, `supplies` must all be int dtype\")\n\n    N_edges = edges.shape[0]\n    N_nodes = len(supplies)\n\n    # Add each edge with associated capacities and cost\n    min_cost_flow.add_arcs_with_capacity_and_unit_cost(edges[:, 0], edges[:, 1], capacities, costs)\n\n    # Add node supplies\n    min_cost_flow.set_nodes_supplies(np.arange(len(supplies)), supplies)\n\n    # Find the minimum cost flow between node 0 and node 4.\n    if min_cost_flow.solve() != min_cost_flow.OPTIMAL:\n        raise Exception('There was an issue with the min cost flow input.')\n\n    # Assignment\n    labels_M = np.array([min_cost_flow.flow(i) for i in range(n_X * n_C)]).reshape(n_X, n_C).astype('int32')\n\n    labels = labels_M.argmax(axis=1)\n    return labels\n\n\nclass KMeansConstrained(KMeans):\n    \"\"\"K-Means clustering with minimum and maximum cluster size constraints\n\n    Parameters\n    ----------\n\n    n_clusters : int, optional, default: 8\n        The number of clusters to form as well as the number of\n        centroids to generate.\n\n    size_min : int, optional, default: None\n        Constrain the label assignment so that each cluster has a minimum\n        size of size_min. If None, no constrains will be applied\n\n    size_max : int, optional, default: None\n        Constrain the label assignment so that each cluster has a maximum\n        size of size_max. If None, no constrains will be applied\n\n    init : {'k-means++', 'random' or an ndarray}\n        Method for initialization, defaults to 'k-means++':\n\n        'k-means++' : selects initial cluster centers for k-mean\n        clustering in a smart way to speed up convergence. See section\n        Notes in k_init for more details.\n\n        'random': choose k observations (rows) at random from data for\n        the initial centroids.\n\n        If an ndarray is passed, it should be of shape (n_clusters, n_features)\n        and gives the initial centers.\n\n    n_init : int, default: 10\n        Number of times the k-means algorithm will be run with different\n        centroid seeds. The final results will be the best output of\n        n_init consecutive runs in terms of inertia.\n\n    max_iter : int, default: 300\n        Maximum number of iterations of the k-means algorithm for a\n        single run.\n\n    tol : float, default: 1e-4\n        Relative tolerance with regards to Frobenius norm of the difference\n        in the cluster centers of two consecutive iterations to declare\n        convergence.\n\n    verbose : int, default 0\n        Verbosity mode.\n\n    random_state : int, RandomState instance or None, optional, default: None\n        If int, random_state is the seed used by the random number generator;\n        If RandomState instance, random_state is the random number generator;\n        If None, the random number generator is the RandomState instance used\n        by `np.random`.\n\n    copy_x : boolean, default True\n        When pre-computing distances it is more numerically accurate to center\n        the data first.  If copy_x is True, then the original data is not\n        modified.  If False, the original data is modified, and put back before\n        the function returns, but small numerical differences may be introduced\n        by subtracting and then adding the data mean.\n\n    n_jobs : int\n        The number of jobs to use for the computation. This works by computing\n        each of the n_init runs in parallel.\n\n        If -1 all CPUs are used. If 1 is given, no parallel computing code is\n        used at all, which is useful for debugging. For n_jobs below -1,\n        (n_cpus + 1 + n_jobs) are used. Thus for n_jobs = -2, all CPUs but one\n        are used.\n\n    Attributes\n    ----------\n    cluster_centers_ : array, [n_clusters, n_features]\n        Coordinates of cluster centers\n\n    labels_ :\n        Labels of each point\n\n    inertia_ : float\n        Sum of squared distances of samples to their closest cluster center.\n\n    Examples\n    --------\n\n    >>> from k_means_constrained import KMeansConstrained\n    >>> import numpy as np\n    >>> X = np.array([[1, 2], [1, 4], [1, 0],\n    ...                [4, 2], [4, 4], [4, 0]])\n    >>> clf = KMeansConstrained(\n    ...     n_clusters=2,\n    ...     size_min=2,\n    ...     size_max=5,\n    ...     random_state=0\n    ... )\n    >>> clf.fit_predict(X)\n    array([0, 0, 0, 1, 1, 1], dtype=int32)\n    >>> clf.cluster_centers_\n    array([[ 1.,  2.],\n           [ 4.,  2.]])\n    >>> clf.labels_\n    array([0, 0, 0, 1, 1, 1], dtype=int32)\n\n    Notes\n    ------\n    K-means problem constrained with a minimum and/or maximum size for each cluster.\n\n    The constrained assignment is formulated as a Minimum Cost Flow (MCF) linear network optimisation\n    problem. This is then solved using a cost-scaling push-relabel algorithm. The implementation used is\n     Google's Operations Research tools's `SimpleMinCostFlow`.\n\n    Ref:\n    1. Bradley, P. S., K. P. Bennett, and Ayhan Demiriz. \"Constrained k-means clustering.\"\n        Microsoft Research, Redmond (2000): 1-8.\n    2. Google's SimpleMinCostFlow implementation:\n        https://github.com/google/or-tools/blob/master/ortools/graph/min_cost_flow.h\n    \"\"\"\n\n    def __init__(self, n_clusters=8, size_min=None, size_max=None, init='k-means++', n_init=10, max_iter=300, tol=1e-4,\n                 verbose=False, random_state=None, copy_x=True, n_jobs=1):\n\n        self.size_min = size_min\n        self.size_max = size_max\n\n        super().__init__(n_clusters=n_clusters, init=init, n_init=n_init, max_iter=max_iter, tol=tol,\n                         verbose=verbose, random_state=random_state, copy_x=copy_x, n_jobs=n_jobs)\n\n    def fit(self, X, y=None):\n        \"\"\"Compute k-means clustering with given constants.\n\n        Parameters\n        ----------\n        X : array-like, shape=(n_samples, n_features)\n            Training instances to cluster.\n\n        y : Ignored\n\n        \"\"\"\n        if sp.issparse(X):\n            raise NotImplementedError(\"Not implemented for sparse X\")\n\n        random_state = check_random_state(self.random_state)\n        X = self._check_fit_data(X)\n\n        self.cluster_centers_, self.labels_, self.inertia_, self.n_iter_ = \\\n            k_means_constrained(\n                X, n_clusters=self.n_clusters,\n                size_min=self.size_min, size_max=self.size_max,\n                init=self.init,\n                n_init=self.n_init, max_iter=self.max_iter, verbose=self.verbose,\n                tol=self.tol, random_state=random_state, copy_x=self.copy_x,\n                n_jobs=self.n_jobs,\n                return_n_iter=True)\n        return self\n\n    def predict(self, X, size_min='init', size_max='init'):\n        \"\"\"\n        Predict the closest cluster each sample in X belongs to given the provided constraints.\n        The constraints can be temporally overridden when determining which cluster each datapoint is assigned to.\n\n        Only computes the assignment step. It does not re-fit the cluster positions.\n\n        Parameters\n        ----------\n        X : array-like, shape = [n_samples, n_features]\n            New data to predict.\n\n        size_min : int, optional, default: size_min provided with initialisation\n            Constrain the label assignment so that each cluster has a minimum\n            size of size_min. If None, no constrains will be applied.\n            If 'init' the value provided during initialisation of the\n            class will be used.\n\n        size_max : int, optional, default: size_max provided with initialisation\n            Constrain the label assignment so that each cluster has a maximum\n            size of size_max. If None, no constrains will be applied.\n            If 'init' the value provided during initialisation of the\n            class will be used.\n\n        Returns\n        -------\n        labels : array, shape [n_samples,]\n            Index of the cluster each sample belongs to.\n        \"\"\"\n\n        if sp.issparse(X):\n            raise NotImplementedError(\"Not implemented for sparse X\")\n\n        if size_min == 'init':\n            size_min = self.size_min\n        if size_max == 'init':\n            size_max = self.size_max\n\n        n_clusters = self.n_clusters\n        n_samples = X.shape[0]\n\n        check_is_fitted(self, 'cluster_centers_')\n\n        X = self._check_test_data(X)\n\n        # Allocate memory to store the distances for each sample to its\n        # closer center for reallocation in case of ties\n        distances = np.zeros(shape=(n_samples,), dtype=X.dtype)\n\n        # Determine min and max sizes if non given\n        if size_min is None:\n            size_min = 0\n        if size_max is None:\n            size_max = n_samples  # Number of data points\n\n        # Check size min and max\n        if not ((size_min >= 0) and (size_min <= n_samples)\n                and (size_max >= 0) and (size_max <= n_samples)):\n            raise ValueError(\"size_min and size_max must be a positive number smaller \"\n                             \"than the number of data points or `None`\")\n        if size_max < size_min:\n            raise ValueError(\"size_max must be larger than size_min\")\n        if size_min * n_clusters > n_samples:\n            raise ValueError(\"The product of size_min and n_clusters cannot exceed the number of samples (X)\")\n\n        labels, inertia = \\\n            _labels_constrained(X, self.cluster_centers_, size_min, size_max, distances=distances)\n\n        return labels\n\n    def fit_predict(self, X, y=None):\n        \"\"\"Compute cluster centers and predict cluster index for each sample.\n\n        Equivalent to calling fit(X) followed by predict(X) but also more efficient.\n\n        Parameters\n        ----------\n        X : {array-like, sparse matrix}, shape = [n_samples, n_features]\n            New data to transform.\n\n        Returns\n        -------\n        labels : array, shape [n_samples,]\n            Index of the cluster each sample belongs to.\n        \"\"\"\n        return self.fit(X).labels_\n"
  },
  {
    "path": "k_means_constrained/sklearn_import/README",
    "content": "Code taken from and slightly modified:\nhttps://github.com/scikit-learn/scikit-learn/tree/0.19.X/sklearn/cluster\n\nSubject to Scikit-Learn licence:\nNew BSD License\n\nCopyright (c) 2007–2019 The scikit-learn developers.\nAll rights reserved.\n\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n  a. Redistributions of source code must retain the above copyright notice,\n     this list of conditions and the following disclaimer.\n  b. Redistributions in binary form must reproduce the above copyright\n     notice, this list of conditions and the following disclaimer in the\n     documentation and/or other materials provided with the distribution.\n  c. Neither the name of the Scikit-learn Developers  nor the names of\n     its contributors may be used to endorse or promote products\n     derived from this software without specific prior written\n     permission.\n\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR\nANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\nLIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\nOUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\nDAMAGE.\n"
  },
  {
    "path": "k_means_constrained/sklearn_import/__init__.py",
    "content": "import os\n\n\ndef get_config():\n    \"\"\"Retrieve current values for configuration set by :func:`set_config`\n\n    Returns\n    -------\n    config : dict\n        Keys are parameter names that can be passed to :func:`set_config`.\n    \"\"\"\n    return {'assume_finite': _ASSUME_FINITE}\n\n\n__version__ = '0.19.2'\n_ASSUME_FINITE = bool(os.environ.get('SKLEARN_ASSUME_FINITE', False))"
  },
  {
    "path": "k_means_constrained/sklearn_import/base.py",
    "content": "import warnings\nfrom collections import defaultdict\n\nimport numpy as np\nimport six\n\nfrom k_means_constrained.sklearn_import import __version__\nfrom k_means_constrained.sklearn_import.funcsigs import signature\n\n\nclass BaseEstimator(object):\n    \"\"\"Base class for all estimators in scikit-learn\n\n    Notes\n    -----\n    All estimators should specify all the parameters that can be set\n    at the class level in their ``__init__`` as explicit keyword\n    arguments (no ``*args`` or ``**kwargs``).\n    \"\"\"\n\n    @classmethod\n    def _get_param_names(cls):\n        \"\"\"Get parameter names for the estimator\"\"\"\n        # fetch the constructor or the original constructor before\n        # deprecation wrapping if any\n        init = getattr(cls.__init__, 'deprecated_original', cls.__init__)\n        if init is object.__init__:\n            # No explicit constructor to introspect\n            return []\n\n        # introspect the constructor arguments to find the model parameters\n        # to represent\n        init_signature = signature(init)\n        # Consider the constructor parameters excluding 'self'\n        parameters = [p for p in init_signature.parameters.values()\n                      if p.name != 'self' and p.kind != p.VAR_KEYWORD]\n        for p in parameters:\n            if p.kind == p.VAR_POSITIONAL:\n                raise RuntimeError(\"scikit-learn estimators should always \"\n                                   \"specify their parameters in the signature\"\n                                   \" of their __init__ (no varargs).\"\n                                   \" %s with constructor %s doesn't \"\n                                   \" follow this convention.\"\n                                   % (cls, init_signature))\n        # Extract and sort argument names excluding 'self'\n        return sorted([p.name for p in parameters])\n\n    def get_params(self, deep=True):\n        \"\"\"Get parameters for this estimator.\n\n        Parameters\n        ----------\n        deep : boolean, optional\n            If True, will return the parameters for this estimator and\n            contained subobjects that are estimators.\n\n        Returns\n        -------\n        params : mapping of string to any\n            Parameter names mapped to their values.\n        \"\"\"\n        out = dict()\n        for key in self._get_param_names():\n            # We need deprecation warnings to always be on in order to\n            # catch deprecated param values.\n            # This is set in utils/__init__.py but it gets overwritten\n            # when running under python3 somehow.\n            warnings.simplefilter(\"always\", DeprecationWarning)\n            try:\n                with warnings.catch_warnings(record=True) as w:\n                    value = getattr(self, key, None)\n                if len(w) and w[0].category == DeprecationWarning:\n                    # if the parameter is deprecated, don't show it\n                    continue\n            finally:\n                warnings.filters.pop(0)\n\n            # XXX: should we rather test if instance of estimator?\n            if deep and hasattr(value, 'get_params'):\n                deep_items = value.get_params().items()\n                out.update((key + '__' + k, val) for k, val in deep_items)\n            out[key] = value\n        return out\n\n    def set_params(self, **params):\n        \"\"\"Set the parameters of this estimator.\n\n        The method works on simple estimators as well as on nested objects\n        (such as pipelines). The latter have parameters of the form\n        ``<component>__<parameter>`` so that it's possible to update each\n        component of a nested object.\n\n        Returns\n        -------\n        self\n        \"\"\"\n        if not params:\n            # Simple optimization to gain speed (inspect is slow)\n            return self\n        valid_params = self.get_params(deep=True)\n\n        nested_params = defaultdict(dict)  # grouped by prefix\n        for key, value in params.items():\n            key, delim, sub_key = key.partition('__')\n            if key not in valid_params:\n                raise ValueError('Invalid parameter %s for estimator %s. '\n                                 'Check the list of available parameters '\n                                 'with `estimator.get_params().keys()`.' %\n                                 (key, self))\n\n            if delim:\n                nested_params[key][sub_key] = value\n            else:\n                setattr(self, key, value)\n\n        for key, sub_params in nested_params.items():\n            valid_params[key].set_params(**sub_params)\n\n        return self\n\n    def __repr__(self):\n        class_name = self.__class__.__name__\n        return '%s(%s)' % (class_name, _pprint(self.get_params(deep=False),\n                                               offset=len(class_name),),)\n\n    def __getstate__(self):\n        try:\n            state = super(BaseEstimator, self).__getstate__()\n        except AttributeError:\n            state = self.__dict__.copy()\n\n        if type(self).__module__.startswith('sklearn.'):\n            return dict(state.items(), _sklearn_version=__version__)\n        else:\n            return state\n\n    def __setstate__(self, state):\n        if type(self).__module__.startswith('sklearn.'):\n            pickle_version = state.pop(\"_sklearn_version\", \"pre-0.18\")\n            if pickle_version != __version__:\n                warnings.warn(\n                    \"Trying to unpickle estimator {0} from version {1} when \"\n                    \"using version {2}. This might lead to breaking code or \"\n                    \"invalid results. Use at your own risk.\".format(\n                        self.__class__.__name__, pickle_version, __version__),\n                    UserWarning)\n        try:\n            super(BaseEstimator, self).__setstate__(state)\n        except AttributeError:\n            self.__dict__.update(state)\n\n\nclass ClusterMixin(object):\n    \"\"\"Mixin class for all cluster estimators in scikit-learn.\"\"\"\n    _estimator_type = \"clusterer\"\n\n    def fit_predict(self, X, y=None):\n        \"\"\"Performs clustering on X and returns cluster labels.\n\n        Parameters\n        ----------\n        X : ndarray, shape (n_samples, n_features)\n            Input data.\n\n        Returns\n        -------\n        y : ndarray, shape (n_samples,)\n            cluster labels\n        \"\"\"\n        # non-optimized default implementation; override when a better\n        # method is possible for a given clustering algorithm\n        self.fit(X)\n        return self.labels_\n\n\nclass TransformerMixin(object):\n    \"\"\"Mixin class for all transformers in scikit-learn.\"\"\"\n\n    def fit_transform(self, X, y=None, **fit_params):\n        \"\"\"Fit to data, then transform it.\n\n        Fits transformer to X and y with optional parameters fit_params\n        and returns a transformed version of X.\n\n        Parameters\n        ----------\n        X : numpy array of shape [n_samples, n_features]\n            Training set.\n\n        y : numpy array of shape [n_samples]\n            Target values.\n\n        Returns\n        -------\n        X_new : numpy array of shape [n_samples, n_features_new]\n            Transformed array.\n\n        \"\"\"\n        # non-optimized default implementation; override when a better\n        # method is possible for a given clustering algorithm\n        if y is None:\n            # fit method of arity 1 (unsupervised transformation)\n            return self.fit(X, **fit_params).transform(X)\n        else:\n            # fit method of arity 2 (supervised transformation)\n            return self.fit(X, y, **fit_params).transform(X)\n\n\ndef _pprint(params, offset=0, printer=repr):\n    \"\"\"Pretty print the dictionary 'params'\n\n    Parameters\n    ----------\n    params : dict\n        The dictionary to pretty print\n\n    offset : int\n        The offset in characters to add at the begin of each line.\n\n    printer : callable\n        The function to convert entries to strings, typically\n        the builtin str or repr\n\n    \"\"\"\n    # Do a multi-line justified repr:\n    options = np.get_printoptions()\n    np.set_printoptions(precision=5, threshold=64, edgeitems=2)\n    params_list = list()\n    this_line_length = offset\n    line_sep = ',\\n' + (1 + offset // 2) * ' '\n    for i, (k, v) in enumerate(sorted(six.iteritems(params))):\n        if type(v) is float:\n            # use str for representing floating point numbers\n            # this way we get consistent representation across\n            # architectures and versions.\n            this_repr = '%s=%s' % (k, str(v))\n        else:\n            # use repr of the rest\n            this_repr = '%s=%s' % (k, printer(v))\n        if len(this_repr) > 500:\n            this_repr = this_repr[:300] + '...' + this_repr[-100:]\n        if i > 0:\n            if (this_line_length + len(this_repr) >= 75 or '\\n' in this_repr):\n                params_list.append(line_sep)\n                this_line_length = len(line_sep)\n            else:\n                params_list.append(', ')\n                this_line_length += 2\n        params_list.append(this_repr)\n        this_line_length += len(this_repr)\n\n    np.set_printoptions(**options)\n    lines = ''.join(params_list)\n    # Strip trailing space to avoid nightmare in doctests\n    lines = '\\n'.join(l.rstrip(' ') for l in lines.split('\\n'))\n    return lines"
  },
  {
    "path": "k_means_constrained/sklearn_import/cluster/__init__.py",
    "content": ""
  },
  {
    "path": "k_means_constrained/sklearn_import/cluster/_k_means.pyx",
    "content": "# cython: profile=True\n# distutils: define_macros=NPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION\n# Profiling is enabled by default as the overhead does not seem to be measurable\n# on this specific use case.\n\n# Author: Peter Prettenhofer <peter.prettenhofer@gmail.com>\n#         Olivier Grisel <olivier.grisel@ensta.org>\n#         Lars Buitinck\n#\n# License: BSD 3 clause\n\nimport numpy as np\ncimport numpy as np\ncimport cython\nfrom cython cimport floating\n\nfrom k_means_constrained.sklearn_import.utils.sparsefuncs_fast import assign_rows_csr\n\nctypedef np.float64_t DOUBLE\nctypedef np.int32_t INT\n\nctypedef floating (*DOT)(int N, floating *X, int incX, floating *Y,\n                         int incY)\n\n\nnp.import_array()\n\n@cython.boundscheck(False)\n@cython.wraparound(False)\n@cython.cdivision(True)\ndef _centers_dense(np.ndarray[floating, ndim=2] X,\n        np.ndarray[INT, ndim=1] labels, int n_clusters,\n        np.ndarray[floating, ndim=1] distances):\n    \"\"\"M step of the K-means EM algorithm\n\n    Computation of cluster centers / means.\n\n    Parameters\n    ----------\n    X : array-like, shape (n_samples, n_features)\n\n    labels : array of integers, shape (n_samples)\n        Current label assignment\n\n    n_clusters : int\n        Number of desired clusters\n\n    distances : array-like, shape (n_samples)\n        Distance to closest cluster for each sample.\n\n    Returns\n    -------\n    centers : array, shape (n_clusters, n_features)\n        The resulting centers\n    \"\"\"\n    ## TODO: add support for CSR input\n    cdef int n_samples, n_features\n    n_samples = X.shape[0]\n    n_features = X.shape[1]\n    cdef int i, j, c\n    cdef np.ndarray[floating, ndim=2] centers\n    if floating is float:\n        centers = np.zeros((n_clusters, n_features), dtype=np.float32)\n    else:\n        centers = np.zeros((n_clusters, n_features), dtype=np.float64)\n\n    n_samples_in_cluster = np.bincount(labels, minlength=n_clusters)\n    empty_clusters = np.where(n_samples_in_cluster == 0)[0]\n    # maybe also relocate small clusters?\n\n    if len(empty_clusters):\n        # find points to reassign empty clusters to\n        far_from_centers = distances.argsort()[::-1]\n\n        for i, cluster_id in enumerate(empty_clusters):\n            # XXX two relocated clusters could be close to each other\n            new_center = X[far_from_centers[i]]\n            centers[cluster_id] = new_center\n            n_samples_in_cluster[cluster_id] = 1\n\n    for i in range(n_samples):\n        for j in range(n_features):\n            centers[labels[i], j] += X[i, j]\n\n    centers /= n_samples_in_cluster[:, np.newaxis]\n\n    return centers\n\n\n@cython.boundscheck(False)\n@cython.wraparound(False)\n@cython.cdivision(True)\ndef _centers_sparse(X, np.ndarray[INT, ndim=1] labels, n_clusters,\n        np.ndarray[floating, ndim=1] distances):\n    \"\"\"M step of the K-means EM algorithm\n\n    Computation of cluster centers / means.\n\n    Parameters\n    ----------\n    X : scipy.sparse.csr_matrix, shape (n_samples, n_features)\n\n    labels : array of integers, shape (n_samples)\n        Current label assignment\n\n    n_clusters : int\n        Number of desired clusters\n\n    distances : array-like, shape (n_samples)\n        Distance to closest cluster for each sample.\n\n    Returns\n    -------\n    centers : array, shape (n_clusters, n_features)\n        The resulting centers\n    \"\"\"\n    cdef int n_features = X.shape[1]\n    cdef int curr_label\n\n    cdef np.ndarray[floating, ndim=1] data = X.data\n    cdef np.ndarray[int, ndim=1] indices = X.indices\n    cdef np.ndarray[int, ndim=1] indptr = X.indptr\n\n    cdef np.ndarray[floating, ndim=2, mode=\"c\"] centers\n    cdef np.ndarray[np.npy_intp, ndim=1] far_from_centers\n    cdef np.ndarray[np.npy_intp, ndim=1, mode=\"c\"] n_samples_in_cluster = \\\n        np.bincount(labels, minlength=n_clusters)\n    cdef np.ndarray[np.npy_intp, ndim=1, mode=\"c\"] empty_clusters = \\\n        np.where(n_samples_in_cluster == 0)[0]\n    cdef int n_empty_clusters = empty_clusters.shape[0]\n\n    if floating is float:\n        centers = np.zeros((n_clusters, n_features), dtype=np.float32)\n    else:\n        centers = np.zeros((n_clusters, n_features), dtype=np.float64)\n\n    # maybe also relocate small clusters?\n\n    if n_empty_clusters > 0:\n        # find points to reassign empty clusters to\n        far_from_centers = distances.argsort()[::-1][:n_empty_clusters]\n\n        # XXX two relocated clusters could be close to each other\n        assign_rows_csr(X, far_from_centers, empty_clusters, centers)\n\n        for i in range(n_empty_clusters):\n            n_samples_in_cluster[empty_clusters[i]] = 1\n\n    for i in range(labels.shape[0]):\n        curr_label = labels[i]\n        for ind in range(indptr[i], indptr[i + 1]):\n            j = indices[ind]\n            centers[curr_label, j] += data[ind]\n\n    centers /= n_samples_in_cluster[:, np.newaxis]\n\n    return centers"
  },
  {
    "path": "k_means_constrained/sklearn_import/cluster/k_means_.py",
    "content": "\"\"\"K-means clustering\"\"\"\n\n# Authors: Gael Varoquaux <gael.varoquaux@normalesup.org>\n#          Thomas Rueckstiess <ruecksti@in.tum.de>\n#          James Bergstra <james.bergstra@umontreal.ca>\n#          Jan Schlueter <scikit-learn@jan-schlueter.de>\n#          Nelle Varoquaux\n#          Peter Prettenhofer <peter.prettenhofer@gmail.com>\n#          Olivier Grisel <olivier.grisel@ensta.org>\n#          Mathieu Blondel <mathieu@mblondel.org>\n#          Robert Layton <robertlayton@gmail.com>\n# License: BSD 3 clause\n\nimport warnings\n\nimport numpy as np\nimport scipy.sparse as sp\nfrom k_means_constrained.sklearn_import.base import BaseEstimator, ClusterMixin, TransformerMixin\nfrom six import string_types\nfrom k_means_constrained.sklearn_import.metrics.pairwise import euclidean_distances, pairwise_distances_argmin_min\nfrom k_means_constrained.sklearn_import.utils.validation import check_array, check_random_state, FLOAT_DTYPES, \\\n    check_is_fitted\nfrom k_means_constrained.sklearn_import.utils.extmath import row_norms, stable_cumsum\nfrom k_means_constrained.sklearn_import.utils.sparsefuncs import mean_variance_axis\n\nfrom k_means_constrained.sklearn_import.cluster import _k_means\n\n\n###############################################################################\n# Initialization heuristic\n\n\ndef _k_init(X, n_clusters, x_squared_norms, random_state, n_local_trials=None):\n    \"\"\"Init n_clusters seeds according to k-means++\n\n    Parameters\n    -----------\n    X : array or sparse matrix, shape (n_samples, n_features)\n        The data to pick seeds for. To avoid memory copy, the input data\n        should be double precision (dtype=np.float64).\n\n    n_clusters : integer\n        The number of seeds to choose\n\n    x_squared_norms : array, shape (n_samples,)\n        Squared Euclidean norm of each data point.\n\n    random_state : numpy.RandomState\n        The generator used to initialize the centers.\n\n    n_local_trials : integer, optional\n        The number of seeding trials for each center (except the first),\n        of which the one reducing inertia the most is greedily chosen.\n        Set to None to make the number of trials depend logarithmically\n        on the number of seeds (2+log(k)); this is the default.\n\n    Notes\n    -----\n    Selects initial cluster centers for k-mean clustering in a smart way\n    to speed up convergence. see: Arthur, D. and Vassilvitskii, S.\n    \"k-means++: the advantages of careful seeding\". ACM-SIAM symposium\n    on Discrete algorithms. 2007\n\n    Version ported from http://www.stanford.edu/~darthur/kMeansppTest.zip,\n    which is the implementation used in the aforementioned paper.\n    \"\"\"\n    n_samples, n_features = X.shape\n\n    centers = np.empty((n_clusters, n_features), dtype=X.dtype)\n\n    assert x_squared_norms is not None, 'x_squared_norms None in _k_init'\n\n    # Set the number of local seeding trials if none is given\n    if n_local_trials is None:\n        # This is what Arthur/Vassilvitskii tried, but did not report\n        # specific results for other than mentioning in the conclusion\n        # that it helped.\n        n_local_trials = 2 + int(np.log(n_clusters))\n\n    # Pick first center randomly\n    center_id = random_state.randint(n_samples)\n    if sp.issparse(X):\n        centers[0] = X[center_id].toarray()\n    else:\n        centers[0] = X[center_id]\n\n    # Initialize list of closest distances and calculate current potential\n    closest_dist_sq = euclidean_distances(\n        centers[0, np.newaxis], X, Y_norm_squared=x_squared_norms,\n        squared=True)\n    current_pot = closest_dist_sq.sum()\n\n    # Pick the remaining n_clusters-1 points\n    for c in range(1, n_clusters):\n        # Choose center candidates by sampling with probability proportional\n        # to the squared distance to the closest existing center\n        rand_vals = random_state.random_sample(n_local_trials) * current_pot\n        candidate_ids = np.searchsorted(stable_cumsum(closest_dist_sq),\n                                        rand_vals)\n        \n        # XXX: numerical imprecision can result in a candidate_id out of range\n        np.clip(candidate_ids, None, closest_dist_sq.size - 1,\n                out=candidate_ids)\n\n        # Compute distances to center candidates\n        distance_to_candidates = euclidean_distances(\n            X[candidate_ids], X, Y_norm_squared=x_squared_norms, squared=True)\n\n        # Decide which candidate is the best\n        best_candidate = None\n        best_pot = None\n        best_dist_sq = None\n        for trial in range(n_local_trials):\n            # Compute potential when including center candidate\n            new_dist_sq = np.minimum(closest_dist_sq,\n                                     distance_to_candidates[trial])\n            new_pot = new_dist_sq.sum()\n\n            # Store result if it is the best local trial so far\n            if (best_candidate is None) or (new_pot < best_pot):\n                best_candidate = candidate_ids[trial]\n                best_pot = new_pot\n                best_dist_sq = new_dist_sq\n\n        # Permanently add best center candidate found in local tries\n        if sp.issparse(X):\n            centers[c] = X[best_candidate].toarray()\n        else:\n            centers[c] = X[best_candidate]\n        current_pot = best_pot\n        closest_dist_sq = best_dist_sq\n\n    return centers\n\n\n###############################################################################\n# K-means batch estimation by EM (expectation maximization)\n\ndef _validate_center_shape(X, n_centers, centers):\n    \"\"\"Check if centers is compatible with X and n_centers\"\"\"\n    if len(centers) != n_centers:\n        raise ValueError('The shape of the initial centers (%s) '\n                         'does not match the number of clusters %i'\n                         % (centers.shape, n_centers))\n    if centers.shape[1] != X.shape[1]:\n        raise ValueError(\n            \"The number of features of the initial centers %s \"\n            \"does not match the number of features of the data %s.\"\n            % (centers.shape[1], X.shape[1]))\n\n\ndef _tolerance(X, tol):\n    \"\"\"Return a tolerance which is independent of the dataset\"\"\"\n    if sp.issparse(X):\n        variances = mean_variance_axis(X, axis=0)[1]\n    else:\n        variances = np.var(X, axis=0)\n    return np.mean(variances) * tol\n\n\ndef _labels_inertia_precompute_dense(X, x_squared_norms, centers, distances):\n    \"\"\"Compute labels and inertia using a full distance matrix.\n\n    This will overwrite the 'distances' array in-place.\n\n    Parameters\n    ----------\n    X : numpy array, shape (n_sample, n_features)\n        Input data.\n\n    x_squared_norms : numpy array, shape (n_samples,)\n        Precomputed squared norms of X.\n\n    centers : numpy array, shape (n_clusters, n_features)\n        Cluster centers which data is assigned to.\n\n    distances : numpy array, shape (n_samples,)\n        Pre-allocated array in which distances are stored.\n\n    Returns\n    -------\n    labels : numpy array, dtype=np.int, shape (n_samples,)\n        Indices of clusters that samples are assigned to.\n\n    inertia : float\n        Sum of distances of samples to their closest cluster center.\n\n    \"\"\"\n    n_samples = X.shape[0]\n\n    # Breakup nearest neighbor distance computation into batches to prevent\n    # memory blowup in the case of a large number of samples and clusters.\n    # TODO: Once PR #7383 is merged use check_inputs=False in metric_kwargs.\n    labels, mindist = pairwise_distances_argmin_min(\n        X=X, Y=centers, metric='euclidean', metric_kwargs={'squared': True})\n    # cython k-means code assumes int32 inputs\n    labels = labels.astype(np.int32)\n    if n_samples == distances.shape[0]:\n        # distances will be changed in-place\n        distances[:] = mindist\n    inertia = mindist.sum()\n    return labels, inertia\n\n\ndef _labels_inertia(X, x_squared_norms, centers,\n                    precompute_distances=True, distances=None):\n    \"\"\"E step of the K-means EM algorithm.\n\n    Compute the labels and the inertia of the given samples and centers.\n    This will compute the distances in-place.\n\n    Parameters\n    ----------\n    X : float64 array-like or CSR sparse matrix, shape (n_samples, n_features)\n        The input samples to assign to the labels.\n\n    x_squared_norms : array, shape (n_samples,)\n        Precomputed squared euclidean norm of each data point, to speed up\n        computations.\n\n    centers : float array, shape (k, n_features)\n        The cluster centers.\n\n    precompute_distances : boolean, default: True\n        Precompute distances (faster but takes more memory).\n\n    distances : float array, shape (n_samples,)\n        Pre-allocated array to be filled in with each sample's distance\n        to the closest center.\n\n    Returns\n    -------\n    labels : int array of shape(n)\n        The resulting assignment\n\n    inertia : float\n        Sum of distances of samples to their closest cluster center.\n    \"\"\"\n    n_samples = X.shape[0]\n    # set the default value of centers to -1 to be able to detect any anomaly\n    # easily\n    labels = -np.ones(n_samples, np.int32)\n    if distances is None:\n        distances = np.zeros(shape=(0,), dtype=X.dtype)\n    # distances will be changed in-place\n    if sp.issparse(X):\n        inertia = _k_means._assign_labels_csr(\n            X, x_squared_norms, centers, labels, distances=distances)\n    else:\n        if precompute_distances:\n            return _labels_inertia_precompute_dense(X, x_squared_norms,\n                                                    centers, distances)\n        inertia = _k_means._assign_labels_array(\n            X, x_squared_norms, centers, labels, distances=distances)\n    return labels, inertia\n\n\ndef _init_centroids(X, k, init, random_state=None, x_squared_norms=None,\n                    init_size=None):\n    \"\"\"Compute the initial centroids\n\n    Parameters\n    ----------\n\n    X : array, shape (n_samples, n_features)\n\n    k : int\n        number of centroids\n\n    init : {'k-means++', 'random' or ndarray or callable} optional\n        Method for initialization\n\n    random_state : int, RandomState instance or None, optional, default: None\n        If int, random_state is the seed used by the random number generator;\n        If RandomState instance, random_state is the random number generator;\n        If None, the random number generator is the RandomState instance used\n        by `np.random`.\n\n    x_squared_norms :  array, shape (n_samples,), optional\n        Squared euclidean norm of each data point. Pass it if you have it at\n        hands already to avoid it being recomputed here. Default: None\n\n    init_size : int, optional\n        Number of samples to randomly sample for speeding up the\n        initialization (sometimes at the expense of accuracy): the\n        only algorithm is initialized by running a batch KMeans on a\n        random subset of the data. This needs to be larger than k.\n\n    Returns\n    -------\n    centers : array, shape(k, n_features)\n    \"\"\"\n    random_state = check_random_state(random_state)\n    n_samples = X.shape[0]\n\n    if x_squared_norms is None:\n        x_squared_norms = row_norms(X, squared=True)\n\n    if init_size is not None and init_size < n_samples:\n        if init_size < k:\n            warnings.warn(\n                \"init_size=%d should be larger than k=%d. \"\n                \"Setting it to 3*k\" % (init_size, k),\n                RuntimeWarning, stacklevel=2)\n            init_size = 3 * k\n        init_indices = random_state.randint(0, n_samples, init_size)\n        X = X[init_indices]\n        x_squared_norms = x_squared_norms[init_indices]\n        n_samples = X.shape[0]\n    elif n_samples < k:\n        raise ValueError(\n            \"n_samples=%d should be larger than k=%d\" % (n_samples, k))\n\n    if isinstance(init, string_types) and init == 'k-means++':\n        centers = _k_init(X, k, random_state=random_state,\n                          x_squared_norms=x_squared_norms)\n    elif isinstance(init, string_types) and init == 'random':\n        seeds = random_state.permutation(n_samples)[:k]\n        centers = X[seeds]\n    elif hasattr(init, '__array__'):\n        # ensure that the centers have the same dtype as X\n        # this is a requirement of fused types of cython\n        centers = np.array(init, dtype=X.dtype)\n    elif callable(init):\n        centers = init(X, k, random_state=random_state)\n        centers = np.asarray(centers, dtype=X.dtype)\n    else:\n        raise ValueError(\"the init parameter for the k-means should \"\n                         \"be 'k-means++' or 'random' or an ndarray, \"\n                         \"'%s' (type '%s') was passed.\" % (init, type(init)))\n\n    if sp.issparse(centers):\n        centers = centers.toarray()\n\n    _validate_center_shape(X, k, centers)\n    return centers\n\n\nclass KMeans(BaseEstimator, ClusterMixin, TransformerMixin):\n    \"\"\"K-Means clustering\n\n    Read more in the :ref:`User Guide <k_means>`.\n\n    Parameters\n    ----------\n\n    n_clusters : int, optional, default: 8\n        The number of clusters to form as well as the number of\n        centroids to generate.\n\n    init : {'k-means++', 'random' or an ndarray}\n        Method for initialization, defaults to 'k-means++':\n\n        'k-means++' : selects initial cluster centers for k-mean\n        clustering in a smart way to speed up convergence. See section\n        Notes in k_init for more details.\n\n        'random': choose k observations (rows) at random from data for\n        the initial centroids.\n\n        If an ndarray is passed, it should be of shape (n_clusters, n_features)\n        and gives the initial centers.\n\n    n_init : int, default: 10\n        Number of time the k-means algorithm will be run with different\n        centroid seeds. The final results will be the best output of\n        n_init consecutive runs in terms of inertia.\n\n    max_iter : int, default: 300\n        Maximum number of iterations of the k-means algorithm for a\n        single run.\n\n    tol : float, default: 1e-4\n        Relative tolerance with regards to inertia to declare convergence\n\n    precompute_distances : {'auto', True, False}\n        Precompute distances (faster but takes more memory).\n\n        'auto' : do not precompute distances if n_samples * n_clusters > 12\n        million. This corresponds to about 100MB overhead per job using\n        double precision.\n\n        True : always precompute distances\n\n        False : never precompute distances\n\n    verbose : int, default 0\n        Verbosity mode.\n\n    random_state : int, RandomState instance or None, optional, default: None\n        If int, random_state is the seed used by the random number generator;\n        If RandomState instance, random_state is the random number generator;\n        If None, the random number generator is the RandomState instance used\n        by `np.random`.\n\n    copy_x : boolean, default True\n        When pre-computing distances it is more numerically accurate to center\n        the data first.  If copy_x is True, then the original data is not\n        modified.  If False, the original data is modified, and put back before\n        the function returns, but small numerical differences may be introduced\n        by subtracting and then adding the data mean.\n\n    n_jobs : int\n        The number of jobs to use for the computation. This works by computing\n        each of the n_init runs in parallel.\n\n        If -1 all CPUs are used. If 1 is given, no parallel computing code is\n        used at all, which is useful for debugging. For n_jobs below -1,\n        (n_cpus + 1 + n_jobs) are used. Thus for n_jobs = -2, all CPUs but one\n        are used.\n\n    algorithm : \"auto\", \"full\" or \"elkan\", default=\"auto\"\n        K-means algorithm to use. The classical EM-style algorithm is \"full\".\n        The \"elkan\" variation is more efficient by using the triangle\n        inequality, but currently doesn't support sparse data. \"auto\" chooses\n        \"elkan\" for dense data and \"full\" for sparse data.\n\n    Attributes\n    ----------\n    cluster_centers_ : array, [n_clusters, n_features]\n        Coordinates of cluster centers\n\n    labels_ :\n        Labels of each point\n\n    inertia_ : float\n        Sum of distances of samples to their closest cluster center.\n\n    Examples\n    --------\n\n    >>> from sklearn.cluster import KMeans\n    >>> import numpy as np\n    >>> X = np.array([[1, 2], [1, 4], [1, 0],\n    ...               [4, 2], [4, 4], [4, 0]])\n    >>> kmeans = KMeans(n_clusters=2, random_state=0).fit(X)\n    >>> kmeans.labels_\n    array([0, 0, 0, 1, 1, 1], dtype=int32)\n    >>> kmeans.predict([[0, 0], [4, 4]])\n    array([0, 1], dtype=int32)\n    >>> kmeans.cluster_centers_\n    array([[ 1.,  2.],\n           [ 4.,  2.]])\n\n    See also\n    --------\n\n    MiniBatchKMeans\n        Alternative online implementation that does incremental updates\n        of the centers positions using mini-batches.\n        For large scale learning (say n_samples > 10k) MiniBatchKMeans is\n        probably much faster than the default batch implementation.\n\n    Notes\n    ------\n    The k-means problem is solved using Lloyd's algorithm.\n\n    The average complexity is given by O(k n T), were n is the number of\n    samples and T is the number of iteration.\n\n    The worst case complexity is given by O(n^(k+2/p)) with\n    n = n_samples, p = n_features. (D. Arthur and S. Vassilvitskii,\n    'How slow is the k-means method?' SoCG2006)\n\n    In practice, the k-means algorithm is very fast (one of the fastest\n    clustering algorithms available), but it falls in local minima. That's why\n    it can be useful to restart it several times.\n\n    \"\"\"\n\n    def __init__(self, n_clusters=8, init='k-means++', n_init=10,\n                 max_iter=300, tol=1e-4, precompute_distances='auto',\n                 verbose=0, random_state=None, copy_x=True,\n                 n_jobs=1, algorithm='auto'):\n\n        self.n_clusters = n_clusters\n        self.init = init\n        self.max_iter = max_iter\n        self.tol = tol\n        self.precompute_distances = precompute_distances\n        self.n_init = n_init\n        self.verbose = verbose\n        self.random_state = random_state\n        self.copy_x = copy_x\n        self.n_jobs = n_jobs\n        self.algorithm = algorithm\n\n    def _check_fit_data(self, X):\n        \"\"\"Verify that the number of samples given is larger than k\"\"\"\n        X = check_array(X, accept_sparse='csr', dtype=[np.float64, np.float32])\n        if X.shape[0] < self.n_clusters:\n            raise ValueError(\"n_samples=%d should be >= n_clusters=%d\" % (\n                X.shape[0], self.n_clusters))\n        return X\n\n    def _check_test_data(self, X):\n        X = check_array(X, accept_sparse='csr', dtype=FLOAT_DTYPES)\n        n_samples, n_features = X.shape\n        expected_n_features = self.cluster_centers_.shape[1]\n        if not n_features == expected_n_features:\n            raise ValueError(\"Incorrect number of features. \"\n                             \"Got %d features, expected %d\" % (\n                                 n_features, expected_n_features))\n\n        return X\n\n    def fit(self, X, y=None):\n        \"\"\"Compute k-means clustering.\n\n        Parameters\n        ----------\n        X : array-like or sparse matrix, shape=(n_samples, n_features)\n            Training instances to cluster.\n        \"\"\"\n        # Added to remove scikit-learn internal dependenceies\n        raise NotImplemented\n\n    def fit_predict(self, X, y=None):\n        \"\"\"Compute cluster centers and predict cluster index for each sample.\n\n        Convenience method; equivalent to calling fit(X) followed by\n        predict(X).\n\n        Parameters\n        ----------\n        X : {array-like, sparse matrix}, shape = [n_samples, n_features]\n            New data to transform.\n\n        Returns\n        -------\n        labels : array, shape [n_samples,]\n            Index of the cluster each sample belongs to.\n        \"\"\"\n        return self.fit(X).labels_\n\n    def fit_transform(self, X, y=None):\n        \"\"\"Compute clustering and transform X to cluster-distance space.\n\n        Equivalent to fit(X).transform(X), but more efficiently implemented.\n\n        Parameters\n        ----------\n        X : {array-like, sparse matrix}, shape = [n_samples, n_features]\n            New data to transform.\n\n        Returns\n        -------\n        X_new : array, shape [n_samples, k]\n            X transformed in the new space.\n        \"\"\"\n        # Currently, this just skips a copy of the data if it is not in\n        # np.array or CSR format already.\n        # XXX This skips _check_test_data, which may change the dtype;\n        # we should refactor the input validation.\n        X = self._check_fit_data(X)\n        return self.fit(X)._transform(X)\n\n    def transform(self, X):\n        \"\"\"Transform X to a cluster-distance space.\n\n        In the new space, each dimension is the distance to the cluster\n        centers.  Note that even if X is sparse, the array returned by\n        `transform` will typically be dense.\n\n        Parameters\n        ----------\n        X : {array-like, sparse matrix}, shape = [n_samples, n_features]\n            New data to transform.\n\n        Returns\n        -------\n        X_new : array, shape [n_samples, k]\n            X transformed in the new space.\n        \"\"\"\n        check_is_fitted(self, 'cluster_centers_')\n\n        X = self._check_test_data(X)\n        return self._transform(X)\n\n    def _transform(self, X):\n        \"\"\"guts of transform method; no input validation\"\"\"\n        return euclidean_distances(X, self.cluster_centers_)\n\n    def predict(self, X):\n        \"\"\"Predict the closest cluster each sample in X belongs to.\n\n        In the vector quantization literature, `cluster_centers_` is called\n        the code book and each value returned by `predict` is the index of\n        the closest code in the code book.\n\n        Parameters\n        ----------\n        X : {array-like, sparse matrix}, shape = [n_samples, n_features]\n            New data to predict.\n\n        Returns\n        -------\n        labels : array, shape [n_samples,]\n            Index of the cluster each sample belongs to.\n        \"\"\"\n        check_is_fitted(self, 'cluster_centers_')\n\n        X = self._check_test_data(X)\n        x_squared_norms = row_norms(X, squared=True)\n        return _labels_inertia(X, x_squared_norms, self.cluster_centers_)[0]\n\n    def score(self, X, y=None):\n        \"\"\"Opposite of the value of X on the K-means objective.\n\n        Parameters\n        ----------\n        X : {array-like, sparse matrix}, shape = [n_samples, n_features]\n            New data.\n\n        Returns\n        -------\n        score : float\n            Opposite of the value of X on the K-means objective.\n        \"\"\"\n        check_is_fitted(self, 'cluster_centers_')\n\n        X = self._check_test_data(X)\n        x_squared_norms = row_norms(X, squared=True)\n        return -_labels_inertia(X, x_squared_norms, self.cluster_centers_)[1]\n\n\n"
  },
  {
    "path": "k_means_constrained/sklearn_import/exceptions.py",
    "content": "class DataConversionWarning(UserWarning):\n    \"\"\"Warning used to notify implicit data conversions happening in the code.\n\n    This warning occurs when some input data needs to be converted or\n    interpreted in a way that may not match the user's expectations.\n\n    For example, this warning may occur when the user\n        - passes an integer array to a function which expects float input and\n          will convert the input\n        - requests a non-copying operation, but a copy is required to meet the\n          implementation's data-type expectations;\n        - passes an input whose shape can be interpreted ambiguously.\n\n    .. versionchanged:: 0.18\n       Moved from sklearn.utils.validation.\n    \"\"\"\n\n\nclass NotFittedError(ValueError, AttributeError):\n    \"\"\"Exception class to raise if estimator is used before fitting.\n\n    This class inherits from both ValueError and AttributeError to help with\n    exception handling and backward compatibility.\n\n    Examples\n    --------\n    >>> from sklearn.svm import LinearSVC\n    >>> from sklearn.exceptions import NotFittedError\n    >>> try:\n    ...     LinearSVC().predict([[1, 2], [2, 3], [3, 4]])\n    ... except NotFittedError as e:\n    ...     print(repr(e))\n    ...                        # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS\n    NotFittedError('This LinearSVC instance is not fitted yet'...)\n\n    .. versionchanged:: 0.18\n       Moved from sklearn.utils.validation.\n    \"\"\""
  },
  {
    "path": "k_means_constrained/sklearn_import/externals/__init__.py",
    "content": ""
  },
  {
    "path": "k_means_constrained/sklearn_import/externals/funcsigs.py",
    "content": "# Copyright 2001-2013 Python Software Foundation; All Rights Reserved\n\"\"\"Function signature objects for callables\n\nBack port of Python 3.3's function signature tools from the inspect module,\nmodified to be compatible with Python 2.7 and 3.2+.\n\"\"\"\nfrom __future__ import absolute_import, division, print_function\nimport itertools\nimport functools\nimport re\nimport types\n\nfrom collections import OrderedDict\n\n__version__ = \"0.4\"\n\n__all__ = ['BoundArguments', 'Parameter', 'Signature', 'signature']\n\n\n_WrapperDescriptor = type(type.__call__)\n_MethodWrapper = type(all.__call__)\n\n_NonUserDefinedCallables = (_WrapperDescriptor,\n                            _MethodWrapper,\n                            types.BuiltinFunctionType)\n\n\ndef formatannotation(annotation, base_module=None):\n    if isinstance(annotation, type):\n        if annotation.__module__ in ('builtins', '__builtin__', base_module):\n            return annotation.__name__\n        return annotation.__module__+'.'+annotation.__name__\n    return repr(annotation)\n\n\ndef _get_user_defined_method(cls, method_name, *nested):\n    try:\n        if cls is type:\n            return\n        meth = getattr(cls, method_name)\n        for name in nested:\n            meth = getattr(meth, name, meth)\n    except AttributeError:\n        return\n    else:\n        if not isinstance(meth, _NonUserDefinedCallables):\n            # Once '__signature__' will be added to 'C'-level\n            # callables, this check won't be necessary\n            return meth\n\n\ndef signature(obj):\n    '''Get a signature object for the passed callable.'''\n\n    if not callable(obj):\n        raise TypeError('{0!r} is not a callable object'.format(obj))\n\n    if isinstance(obj, types.MethodType):\n        sig = signature(obj.__func__)\n        if obj.__self__ is None:\n            # Unbound method: the first parameter becomes positional-only\n            if sig.parameters:\n                first = sig.parameters.values()[0].replace(\n                    kind=_POSITIONAL_ONLY)\n                return sig.replace(\n                    parameters=(first,) + tuple(sig.parameters.values())[1:])\n            else:\n                return sig\n        else:\n            # In this case we skip the first parameter of the underlying\n            # function (usually `self` or `cls`).\n            return sig.replace(parameters=tuple(sig.parameters.values())[1:])\n\n    try:\n        sig = obj.__signature__\n    except AttributeError:\n        pass\n    else:\n        if sig is not None:\n            return sig\n\n    try:\n        # Was this function wrapped by a decorator?\n        wrapped = obj.__wrapped__\n    except AttributeError:\n        pass\n    else:\n        return signature(wrapped)\n\n    if isinstance(obj, types.FunctionType):\n        return Signature.from_function(obj)\n\n    if isinstance(obj, functools.partial):\n        sig = signature(obj.func)\n\n        new_params = OrderedDict(sig.parameters.items())\n\n        partial_args = obj.args or ()\n        partial_keywords = obj.keywords or {}\n        try:\n            ba = sig.bind_partial(*partial_args, **partial_keywords)\n        except TypeError as ex:\n            msg = 'partial object {0!r} has incorrect arguments'.format(obj)\n            raise ValueError(msg)\n\n        for arg_name, arg_value in ba.arguments.items():\n            param = new_params[arg_name]\n            if arg_name in partial_keywords:\n                # We set a new default value, because the following code\n                # is correct:\n                #\n                #   >>> def foo(a): print(a)\n                #   >>> print(partial(partial(foo, a=10), a=20)())\n                #   20\n                #   >>> print(partial(partial(foo, a=10), a=20)(a=30))\n                #   30\n                #\n                # So, with 'partial' objects, passing a keyword argument is\n                # like setting a new default value for the corresponding\n                # parameter\n                #\n                # We also mark this parameter with '_partial_kwarg'\n                # flag.  Later, in '_bind', the 'default' value of this\n                # parameter will be added to 'kwargs', to simulate\n                # the 'functools.partial' real call.\n                new_params[arg_name] = param.replace(default=arg_value,\n                                                     _partial_kwarg=True)\n\n            elif (param.kind not in (_VAR_KEYWORD, _VAR_POSITIONAL) and\n                            not param._partial_kwarg):\n                new_params.pop(arg_name)\n\n        return sig.replace(parameters=new_params.values())\n\n    sig = None\n    if isinstance(obj, type):\n        # obj is a class or a metaclass\n\n        # First, let's see if it has an overloaded __call__ defined\n        # in its metaclass\n        call = _get_user_defined_method(type(obj), '__call__')\n        if call is not None:\n            sig = signature(call)\n        else:\n            # Now we check if the 'obj' class has a '__new__' method\n            new = _get_user_defined_method(obj, '__new__')\n            if new is not None:\n                sig = signature(new)\n            else:\n                # Finally, we should have at least __init__ implemented\n                init = _get_user_defined_method(obj, '__init__')\n                if init is not None:\n                    sig = signature(init)\n    elif not isinstance(obj, _NonUserDefinedCallables):\n        # An object with __call__\n        # We also check that the 'obj' is not an instance of\n        # _WrapperDescriptor or _MethodWrapper to avoid\n        # infinite recursion (and even potential segfault)\n        call = _get_user_defined_method(type(obj), '__call__', 'im_func')\n        if call is not None:\n            sig = signature(call)\n\n    if sig is not None:\n        # For classes and objects we skip the first parameter of their\n        # __call__, __new__, or __init__ methods\n        return sig.replace(parameters=tuple(sig.parameters.values())[1:])\n\n    if isinstance(obj, types.BuiltinFunctionType):\n        # Raise a nicer error message for builtins\n        msg = 'no signature found for builtin function {0!r}'.format(obj)\n        raise ValueError(msg)\n\n    raise ValueError('callable {0!r} is not supported by signature'.format(obj))\n\n\nclass _void(object):\n    '''A private marker - used in Parameter & Signature'''\n\n\nclass _empty(object):\n    pass\n\n\nclass _ParameterKind(int):\n    def __new__(self, *args, **kwargs):\n        obj = int.__new__(self, *args)\n        obj._name = kwargs['name']\n        return obj\n\n    def __str__(self):\n        return self._name\n\n    def __repr__(self):\n        return '<_ParameterKind: {0!r}>'.format(self._name)\n\n\n_POSITIONAL_ONLY        = _ParameterKind(0, name='POSITIONAL_ONLY')\n_POSITIONAL_OR_KEYWORD  = _ParameterKind(1, name='POSITIONAL_OR_KEYWORD')\n_VAR_POSITIONAL         = _ParameterKind(2, name='VAR_POSITIONAL')\n_KEYWORD_ONLY           = _ParameterKind(3, name='KEYWORD_ONLY')\n_VAR_KEYWORD            = _ParameterKind(4, name='VAR_KEYWORD')\n\n\nclass Parameter(object):\n    '''Represents a parameter in a function signature.\n\n    Has the following public attributes:\n\n    * name : str\n        The name of the parameter as a string.\n    * default : object\n        The default value for the parameter if specified.  If the\n        parameter has no default value, this attribute is not set.\n    * annotation\n        The annotation for the parameter if specified.  If the\n        parameter has no annotation, this attribute is not set.\n    * kind : str\n        Describes how argument values are bound to the parameter.\n        Possible values: `Parameter.POSITIONAL_ONLY`,\n        `Parameter.POSITIONAL_OR_KEYWORD`, `Parameter.VAR_POSITIONAL`,\n        `Parameter.KEYWORD_ONLY`, `Parameter.VAR_KEYWORD`.\n    '''\n\n    __slots__ = ('_name', '_kind', '_default', '_annotation', '_partial_kwarg')\n\n    POSITIONAL_ONLY         = _POSITIONAL_ONLY\n    POSITIONAL_OR_KEYWORD   = _POSITIONAL_OR_KEYWORD\n    VAR_POSITIONAL          = _VAR_POSITIONAL\n    KEYWORD_ONLY            = _KEYWORD_ONLY\n    VAR_KEYWORD             = _VAR_KEYWORD\n\n    empty = _empty\n\n    def __init__(self, name, kind, default=_empty, annotation=_empty,\n                 _partial_kwarg=False):\n\n        if kind not in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD,\n                        _VAR_POSITIONAL, _KEYWORD_ONLY, _VAR_KEYWORD):\n            raise ValueError(\"invalid value for 'Parameter.kind' attribute\")\n        self._kind = kind\n\n        if default is not _empty:\n            if kind in (_VAR_POSITIONAL, _VAR_KEYWORD):\n                msg = '{0} parameters cannot have default values'.format(kind)\n                raise ValueError(msg)\n        self._default = default\n        self._annotation = annotation\n\n        if name is None:\n            if kind != _POSITIONAL_ONLY:\n                raise ValueError(\"None is not a valid name for a \"\n                                 \"non-positional-only parameter\")\n            self._name = name\n        else:\n            name = str(name)\n            if kind != _POSITIONAL_ONLY and not re.match(r'[a-z_]\\w*$', name, re.I):\n                msg = '{0!r} is not a valid parameter name'.format(name)\n                raise ValueError(msg)\n            self._name = name\n\n        self._partial_kwarg = _partial_kwarg\n\n    @property\n    def name(self):\n        return self._name\n\n    @property\n    def default(self):\n        return self._default\n\n    @property\n    def annotation(self):\n        return self._annotation\n\n    @property\n    def kind(self):\n        return self._kind\n\n    def replace(self, name=_void, kind=_void, annotation=_void,\n                default=_void, _partial_kwarg=_void):\n        '''Creates a customized copy of the Parameter.'''\n\n        if name is _void:\n            name = self._name\n\n        if kind is _void:\n            kind = self._kind\n\n        if annotation is _void:\n            annotation = self._annotation\n\n        if default is _void:\n            default = self._default\n\n        if _partial_kwarg is _void:\n            _partial_kwarg = self._partial_kwarg\n\n        return type(self)(name, kind, default=default, annotation=annotation,\n                          _partial_kwarg=_partial_kwarg)\n\n    def __str__(self):\n        kind = self.kind\n\n        formatted = self._name\n        if kind == _POSITIONAL_ONLY:\n            if formatted is None:\n                formatted = ''\n            formatted = '<{0}>'.format(formatted)\n\n        # Add annotation and default value\n        if self._annotation is not _empty:\n            formatted = '{0}:{1}'.format(formatted,\n                                       formatannotation(self._annotation))\n\n        if self._default is not _empty:\n            formatted = '{0}={1}'.format(formatted, repr(self._default))\n\n        if kind == _VAR_POSITIONAL:\n            formatted = '*' + formatted\n        elif kind == _VAR_KEYWORD:\n            formatted = '**' + formatted\n\n        return formatted\n\n    def __repr__(self):\n        return '<{0} at {1:#x} {2!r}>'.format(self.__class__.__name__,\n                                           id(self), self.name)\n\n    def __hash__(self):\n        msg = \"unhashable type: '{0}'\".format(self.__class__.__name__)\n        raise TypeError(msg)\n\n    def __eq__(self, other):\n        return (issubclass(other.__class__, Parameter) and\n                self._name == other._name and\n                self._kind == other._kind and\n                self._default == other._default and\n                self._annotation == other._annotation)\n\n    def __ne__(self, other):\n        return not self.__eq__(other)\n\n\nclass BoundArguments(object):\n    '''Result of `Signature.bind` call.  Holds the mapping of arguments\n    to the function's parameters.\n\n    Has the following public attributes:\n\n    * arguments : OrderedDict\n        An ordered mutable mapping of parameters' names to arguments' values.\n        Does not contain arguments' default values.\n    * signature : Signature\n        The Signature object that created this instance.\n    * args : tuple\n        Tuple of positional arguments values.\n    * kwargs : dict\n        Dict of keyword arguments values.\n    '''\n\n    def __init__(self, signature, arguments):\n        self.arguments = arguments\n        self._signature = signature\n\n    @property\n    def signature(self):\n        return self._signature\n\n    @property\n    def args(self):\n        args = []\n        for param_name, param in self._signature.parameters.items():\n            if (param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY) or\n                                                    param._partial_kwarg):\n                # Keyword arguments mapped by 'functools.partial'\n                # (Parameter._partial_kwarg is True) are mapped\n                # in 'BoundArguments.kwargs', along with VAR_KEYWORD &\n                # KEYWORD_ONLY\n                break\n\n            try:\n                arg = self.arguments[param_name]\n            except KeyError:\n                # We're done here. Other arguments\n                # will be mapped in 'BoundArguments.kwargs'\n                break\n            else:\n                if param.kind == _VAR_POSITIONAL:\n                    # *args\n                    args.extend(arg)\n                else:\n                    # plain argument\n                    args.append(arg)\n\n        return tuple(args)\n\n    @property\n    def kwargs(self):\n        kwargs = {}\n        kwargs_started = False\n        for param_name, param in self._signature.parameters.items():\n            if not kwargs_started:\n                if (param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY) or\n                                                param._partial_kwarg):\n                    kwargs_started = True\n                else:\n                    if param_name not in self.arguments:\n                        kwargs_started = True\n                        continue\n\n            if not kwargs_started:\n                continue\n\n            try:\n                arg = self.arguments[param_name]\n            except KeyError:\n                pass\n            else:\n                if param.kind == _VAR_KEYWORD:\n                    # **kwargs\n                    kwargs.update(arg)\n                else:\n                    # plain keyword argument\n                    kwargs[param_name] = arg\n\n        return kwargs\n\n    def __hash__(self):\n        msg = \"unhashable type: '{0}'\".format(self.__class__.__name__)\n        raise TypeError(msg)\n\n    def __eq__(self, other):\n        return (issubclass(other.__class__, BoundArguments) and\n                self.signature == other.signature and\n                self.arguments == other.arguments)\n\n    def __ne__(self, other):\n        return not self.__eq__(other)\n\n\nclass Signature(object):\n    '''A Signature object represents the overall signature of a function.\n    It stores a Parameter object for each parameter accepted by the\n    function, as well as information specific to the function itself.\n\n    A Signature object has the following public attributes and methods:\n\n    * parameters : OrderedDict\n        An ordered mapping of parameters' names to the corresponding\n        Parameter objects (keyword-only arguments are in the same order\n        as listed in `code.co_varnames`).\n    * return_annotation : object\n        The annotation for the return type of the function if specified.\n        If the function has no annotation for its return type, this\n        attribute is not set.\n    * bind(*args, **kwargs) -> BoundArguments\n        Creates a mapping from positional and keyword arguments to\n        parameters.\n    * bind_partial(*args, **kwargs) -> BoundArguments\n        Creates a partial mapping from positional and keyword arguments\n        to parameters (simulating 'functools.partial' behavior.)\n    '''\n\n    __slots__ = ('_return_annotation', '_parameters')\n\n    _parameter_cls = Parameter\n    _bound_arguments_cls = BoundArguments\n\n    empty = _empty\n\n    def __init__(self, parameters=None, return_annotation=_empty,\n                 __validate_parameters__=True):\n        '''Constructs Signature from the given list of Parameter\n        objects and 'return_annotation'.  All arguments are optional.\n        '''\n\n        if parameters is None:\n            params = OrderedDict()\n        else:\n            if __validate_parameters__:\n                params = OrderedDict()\n                top_kind = _POSITIONAL_ONLY\n\n                for idx, param in enumerate(parameters):\n                    kind = param.kind\n                    if kind < top_kind:\n                        msg = 'wrong parameter order: {0} before {1}'\n                        msg = msg.format(top_kind, param.kind)\n                        raise ValueError(msg)\n                    else:\n                        top_kind = kind\n\n                    name = param.name\n                    if name is None:\n                        name = str(idx)\n                        param = param.replace(name=name)\n\n                    if name in params:\n                        msg = 'duplicate parameter name: {0!r}'.format(name)\n                        raise ValueError(msg)\n                    params[name] = param\n            else:\n                params = OrderedDict(((param.name, param)\n                                                for param in parameters))\n\n        self._parameters = params\n        self._return_annotation = return_annotation\n\n    @classmethod\n    def from_function(cls, func):\n        '''Constructs Signature for the given python function'''\n\n        if not isinstance(func, types.FunctionType):\n            raise TypeError('{0!r} is not a Python function'.format(func))\n\n        Parameter = cls._parameter_cls\n\n        # Parameter information.\n        func_code = func.__code__\n        pos_count = func_code.co_argcount\n        arg_names = func_code.co_varnames\n        positional = tuple(arg_names[:pos_count])\n        keyword_only_count = getattr(func_code, 'co_kwonlyargcount', 0)\n        keyword_only = arg_names[pos_count:(pos_count + keyword_only_count)]\n        annotations = getattr(func, '__annotations__', {})\n        defaults = func.__defaults__\n        kwdefaults = getattr(func, '__kwdefaults__', None)\n\n        if defaults:\n            pos_default_count = len(defaults)\n        else:\n            pos_default_count = 0\n\n        parameters = []\n\n        # Non-keyword-only parameters w/o defaults.\n        non_default_count = pos_count - pos_default_count\n        for name in positional[:non_default_count]:\n            annotation = annotations.get(name, _empty)\n            parameters.append(Parameter(name, annotation=annotation,\n                                        kind=_POSITIONAL_OR_KEYWORD))\n\n        # ... w/ defaults.\n        for offset, name in enumerate(positional[non_default_count:]):\n            annotation = annotations.get(name, _empty)\n            parameters.append(Parameter(name, annotation=annotation,\n                                        kind=_POSITIONAL_OR_KEYWORD,\n                                        default=defaults[offset]))\n\n        # *args\n        if func_code.co_flags & 0x04:\n            name = arg_names[pos_count + keyword_only_count]\n            annotation = annotations.get(name, _empty)\n            parameters.append(Parameter(name, annotation=annotation,\n                                        kind=_VAR_POSITIONAL))\n\n        # Keyword-only parameters.\n        for name in keyword_only:\n            default = _empty\n            if kwdefaults is not None:\n                default = kwdefaults.get(name, _empty)\n\n            annotation = annotations.get(name, _empty)\n            parameters.append(Parameter(name, annotation=annotation,\n                                        kind=_KEYWORD_ONLY,\n                                        default=default))\n        # **kwargs\n        if func_code.co_flags & 0x08:\n            index = pos_count + keyword_only_count\n            if func_code.co_flags & 0x04:\n                index += 1\n\n            name = arg_names[index]\n            annotation = annotations.get(name, _empty)\n            parameters.append(Parameter(name, annotation=annotation,\n                                        kind=_VAR_KEYWORD))\n\n        return cls(parameters,\n                   return_annotation=annotations.get('return', _empty),\n                   __validate_parameters__=False)\n\n    @property\n    def parameters(self):\n        try:\n            return types.MappingProxyType(self._parameters)\n        except AttributeError:\n            return OrderedDict(self._parameters.items())\n\n    @property\n    def return_annotation(self):\n        return self._return_annotation\n\n    def replace(self, parameters=_void, return_annotation=_void):\n        '''Creates a customized copy of the Signature.\n        Pass 'parameters' and/or 'return_annotation' arguments\n        to override them in the new copy.\n        '''\n\n        if parameters is _void:\n            parameters = self.parameters.values()\n\n        if return_annotation is _void:\n            return_annotation = self._return_annotation\n\n        return type(self)(parameters,\n                          return_annotation=return_annotation)\n\n    def __hash__(self):\n        msg = \"unhashable type: '{0}'\".format(self.__class__.__name__)\n        raise TypeError(msg)\n\n    def __eq__(self, other):\n        if (not issubclass(type(other), Signature) or\n                    self.return_annotation != other.return_annotation or\n                    len(self.parameters) != len(other.parameters)):\n            return False\n\n        other_positions = dict((param, idx)\n                           for idx, param in enumerate(other.parameters.keys()))\n\n        for idx, (param_name, param) in enumerate(self.parameters.items()):\n            if param.kind == _KEYWORD_ONLY:\n                try:\n                    other_param = other.parameters[param_name]\n                except KeyError:\n                    return False\n                else:\n                    if param != other_param:\n                        return False\n            else:\n                try:\n                    other_idx = other_positions[param_name]\n                except KeyError:\n                    return False\n                else:\n                    if (idx != other_idx or\n                                    param != other.parameters[param_name]):\n                        return False\n\n        return True\n\n    def __ne__(self, other):\n        return not self.__eq__(other)\n\n    def _bind(self, args, kwargs, partial=False):\n        '''Private method.  Don't use directly.'''\n\n        arguments = OrderedDict()\n\n        parameters = iter(self.parameters.values())\n        parameters_ex = ()\n        arg_vals = iter(args)\n\n        if partial:\n            # Support for binding arguments to 'functools.partial' objects.\n            # See 'functools.partial' case in 'signature()' implementation\n            # for details.\n            for param_name, param in self.parameters.items():\n                if (param._partial_kwarg and param_name not in kwargs):\n                    # Simulating 'functools.partial' behavior\n                    kwargs[param_name] = param.default\n\n        while True:\n            # Let's iterate through the positional arguments and corresponding\n            # parameters\n            try:\n                arg_val = next(arg_vals)\n            except StopIteration:\n                # No more positional arguments\n                try:\n                    param = next(parameters)\n                except StopIteration:\n                    # No more parameters. That's it. Just need to check that\n                    # we have no `kwargs` after this while loop\n                    break\n                else:\n                    if param.kind == _VAR_POSITIONAL:\n                        # That's OK, just empty *args.  Let's start parsing\n                        # kwargs\n                        break\n                    elif param.name in kwargs:\n                        if param.kind == _POSITIONAL_ONLY:\n                            msg = '{arg!r} parameter is positional only, ' \\\n                                  'but was passed as a keyword'\n                            msg = msg.format(arg=param.name)\n                            raise TypeError(msg)\n                        parameters_ex = (param,)\n                        break\n                    elif (param.kind == _VAR_KEYWORD or\n                                                param.default is not _empty):\n                        # That's fine too - we have a default value for this\n                        # parameter.  So, lets start parsing `kwargs`, starting\n                        # with the current parameter\n                        parameters_ex = (param,)\n                        break\n                    else:\n                        if partial:\n                            parameters_ex = (param,)\n                            break\n                        else:\n                            msg = '{arg!r} parameter lacking default value'\n                            msg = msg.format(arg=param.name)\n                            raise TypeError(msg)\n            else:\n                # We have a positional argument to process\n                try:\n                    param = next(parameters)\n                except StopIteration:\n                    raise TypeError('too many positional arguments')\n                else:\n                    if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):\n                        # Looks like we have no parameter for this positional\n                        # argument\n                        raise TypeError('too many positional arguments')\n\n                    if param.kind == _VAR_POSITIONAL:\n                        # We have an '*args'-like argument, let's fill it with\n                        # all positional arguments we have left and move on to\n                        # the next phase\n                        values = [arg_val]\n                        values.extend(arg_vals)\n                        arguments[param.name] = tuple(values)\n                        break\n\n                    if param.name in kwargs:\n                        raise TypeError('multiple values for argument '\n                                        '{arg!r}'.format(arg=param.name))\n\n                    arguments[param.name] = arg_val\n\n        # Now, we iterate through the remaining parameters to process\n        # keyword arguments\n        kwargs_param = None\n        for param in itertools.chain(parameters_ex, parameters):\n            if param.kind == _POSITIONAL_ONLY:\n                # This should never happen in case of a properly built\n                # Signature object (but let's have this check here\n                # to ensure correct behaviour just in case)\n                raise TypeError('{arg!r} parameter is positional only, '\n                                'but was passed as a keyword'. \\\n                                format(arg=param.name))\n\n            if param.kind == _VAR_KEYWORD:\n                # Memorize that we have a '**kwargs'-like parameter\n                kwargs_param = param\n                continue\n\n            param_name = param.name\n            try:\n                arg_val = kwargs.pop(param_name)\n            except KeyError:\n                # We have no value for this parameter.  It's fine though,\n                # if it has a default value, or it is an '*args'-like\n                # parameter, left alone by the processing of positional\n                # arguments.\n                if (not partial and param.kind != _VAR_POSITIONAL and\n                                                    param.default is _empty):\n                    raise TypeError('{arg!r} parameter lacking default value'. \\\n                                    format(arg=param_name))\n\n            else:\n                arguments[param_name] = arg_val\n\n        if kwargs:\n            if kwargs_param is not None:\n                # Process our '**kwargs'-like parameter\n                arguments[kwargs_param.name] = kwargs\n            else:\n                raise TypeError('too many keyword arguments')\n\n        return self._bound_arguments_cls(self, arguments)\n\n    def bind(self, *args, **kwargs):\n        '''Get a BoundArguments object, that maps the passed `args`\n        and `kwargs` to the function's signature.  Raises `TypeError`\n        if the passed arguments can not be bound.\n        '''\n        return self._bind(args, kwargs)\n\n    def bind_partial(self, *args, **kwargs):\n        '''Get a BoundArguments object, that partially maps the\n        passed `args` and `kwargs` to the function's signature.\n        Raises `TypeError` if the passed arguments can not be bound.\n        '''\n        return self._bind(args, kwargs, partial=True)\n\n    def __str__(self):\n        result = []\n        render_kw_only_separator = True\n        for idx, param in enumerate(self.parameters.values()):\n            formatted = str(param)\n\n            kind = param.kind\n            if kind == _VAR_POSITIONAL:\n                # OK, we have an '*args'-like parameter, so we won't need\n                # a '*' to separate keyword-only arguments\n                render_kw_only_separator = False\n            elif kind == _KEYWORD_ONLY and render_kw_only_separator:\n                # We have a keyword-only parameter to render and we haven't\n                # rendered an '*args'-like parameter before, so add a '*'\n                # separator to the parameters list (\"foo(arg1, *, arg2)\" case)\n                result.append('*')\n                # This condition should be only triggered once, so\n                # reset the flag\n                render_kw_only_separator = False\n\n            result.append(formatted)\n\n        rendered = '({0})'.format(', '.join(result))\n\n        if self.return_annotation is not _empty:\n            anno = formatannotation(self.return_annotation)\n            rendered += ' -> {0}'.format(anno)\n\n        return rendered"
  },
  {
    "path": "k_means_constrained/sklearn_import/fixes.py",
    "content": "def _parse_version(version_string):\n    version = []\n    for x in version_string.split('.'):\n        try:\n            version.append(int(x))\n        except ValueError:\n            # x may be of the form dev-1ea1592\n            version.append(x)\n    return tuple(version)"
  },
  {
    "path": "k_means_constrained/sklearn_import/funcsigs.py",
    "content": "import functools\nimport types\nfrom collections import OrderedDict\n\nfrom k_means_constrained.sklearn_import.externals.funcsigs import _NonUserDefinedCallables, _get_user_defined_method, \\\n    _POSITIONAL_ONLY, _VAR_POSITIONAL, _VAR_KEYWORD, Signature\n\n\ndef signature(obj):\n    '''Get a signature object for the passed callable.'''\n\n    if not callable(obj):\n        raise TypeError('{0!r} is not a callable object'.format(obj))\n\n    if isinstance(obj, types.MethodType):\n        sig = signature(obj.__func__)\n        if obj.__self__ is None:\n            # Unbound method: the first parameter becomes positional-only\n            if sig.parameters:\n                first = sig.parameters.values()[0].replace(\n                    kind=_POSITIONAL_ONLY)\n                return sig.replace(\n                    parameters=(first,) + tuple(sig.parameters.values())[1:])\n            else:\n                return sig\n        else:\n            # In this case we skip the first parameter of the underlying\n            # function (usually `self` or `cls`).\n            return sig.replace(parameters=tuple(sig.parameters.values())[1:])\n\n    try:\n        sig = obj.__signature__\n    except AttributeError:\n        pass\n    else:\n        if sig is not None:\n            return sig\n\n    try:\n        # Was this function wrapped by a decorator?\n        wrapped = obj.__wrapped__\n    except AttributeError:\n        pass\n    else:\n        return signature(wrapped)\n\n    if isinstance(obj, types.FunctionType):\n        return Signature.from_function(obj)\n\n    if isinstance(obj, functools.partial):\n        sig = signature(obj.func)\n\n        new_params = OrderedDict(sig.parameters.items())\n\n        partial_args = obj.args or ()\n        partial_keywords = obj.keywords or {}\n        try:\n            ba = sig.bind_partial(*partial_args, **partial_keywords)\n        except TypeError as ex:\n            msg = 'partial object {0!r} has incorrect arguments'.format(obj)\n            raise ValueError(msg)\n\n        for arg_name, arg_value in ba.arguments.items():\n            param = new_params[arg_name]\n            if arg_name in partial_keywords:\n                # We set a new default value, because the following code\n                # is correct:\n                #\n                #   >>> def foo(a): print(a)\n                #   >>> print(partial(partial(foo, a=10), a=20)())\n                #   20\n                #   >>> print(partial(partial(foo, a=10), a=20)(a=30))\n                #   30\n                #\n                # So, with 'partial' objects, passing a keyword argument is\n                # like setting a new default value for the corresponding\n                # parameter\n                #\n                # We also mark this parameter with '_partial_kwarg'\n                # flag.  Later, in '_bind', the 'default' value of this\n                # parameter will be added to 'kwargs', to simulate\n                # the 'functools.partial' real call.\n                new_params[arg_name] = param.replace(default=arg_value,\n                                                     _partial_kwarg=True)\n\n            elif (param.kind not in (_VAR_KEYWORD, _VAR_POSITIONAL) and\n                            not param._partial_kwarg):\n                new_params.pop(arg_name)\n\n        return sig.replace(parameters=new_params.values())\n\n    sig = None\n    if isinstance(obj, type):\n        # obj is a class or a metaclass\n\n        # First, let's see if it has an overloaded __call__ defined\n        # in its metaclass\n        call = _get_user_defined_method(type(obj), '__call__')\n        if call is not None:\n            sig = signature(call)\n        else:\n            # Now we check if the 'obj' class has a '__new__' method\n            new = _get_user_defined_method(obj, '__new__')\n            if new is not None:\n                sig = signature(new)\n            else:\n                # Finally, we should have at least __init__ implemented\n                init = _get_user_defined_method(obj, '__init__')\n                if init is not None:\n                    sig = signature(init)\n    elif not isinstance(obj, _NonUserDefinedCallables):\n        # An object with __call__\n        # We also check that the 'obj' is not an instance of\n        # _WrapperDescriptor or _MethodWrapper to avoid\n        # infinite recursion (and even potential segfault)\n        call = _get_user_defined_method(type(obj), '__call__', 'im_func')\n        if call is not None:\n            sig = signature(call)\n\n    if sig is not None:\n        # For classes and objects we skip the first parameter of their\n        # __call__, __new__, or __init__ methods\n        return sig.replace(parameters=tuple(sig.parameters.values())[1:])\n\n    if isinstance(obj, types.BuiltinFunctionType):\n        # Raise a nicer error message for builtins\n        msg = 'no signature found for builtin function {0!r}'.format(obj)\n        raise ValueError(msg)\n\n    raise ValueError('callable {0!r} is not supported by signature'.format(obj))"
  },
  {
    "path": "k_means_constrained/sklearn_import/metrics/__init__.py",
    "content": ""
  },
  {
    "path": "k_means_constrained/sklearn_import/metrics/pairwise.py",
    "content": "import itertools\nimport warnings\nfrom functools import partial\n\nimport numpy as np\nfrom scipy.sparse import issparse, csr_matrix\nfrom scipy.spatial import distance\nfrom joblib import cpu_count, delayed, Parallel\n\nfrom k_means_constrained.sklearn_import.metrics.pairwise_fast import _sparse_manhattan\n\nfrom k_means_constrained.sklearn_import.preprocessing.data import normalize\n\nfrom k_means_constrained.sklearn_import.utils import gen_batches, gen_even_slices\n\nfrom k_means_constrained.sklearn_import.utils.validation import check_array\nfrom k_means_constrained.sklearn_import.utils.extmath import row_norms, safe_sparse_dot\n\n\ndef euclidean_distances(X, Y=None, Y_norm_squared=None, squared=False,\n                        X_norm_squared=None):\n    \"\"\"\n    Considering the rows of X (and Y=X) as vectors, compute the\n    distance matrix between each pair of vectors.\n\n    For efficiency reasons, the euclidean distance between a pair of row\n    vector x and y is computed as::\n\n        dist(x, y) = sqrt(dot(x, x) - 2 * dot(x, y) + dot(y, y))\n\n    This formulation has two advantages over other ways of computing distances.\n    First, it is computationally efficient when dealing with sparse data.\n    Second, if one argument varies but the other remains unchanged, then\n    `dot(x, x)` and/or `dot(y, y)` can be pre-computed.\n\n    However, this is not the most precise way of doing this computation, and\n    the distance matrix returned by this function may not be exactly\n    symmetric as required by, e.g., ``scipy.spatial.distance`` functions.\n\n    Read more in the :ref:`User Guide <metrics>`.\n\n    Parameters\n    ----------\n    X : {array-like, sparse matrix}, shape (n_samples_1, n_features)\n\n    Y : {array-like, sparse matrix}, shape (n_samples_2, n_features)\n\n    Y_norm_squared : array-like, shape (n_samples_2, ), optional\n        Pre-computed dot-products of vectors in Y (e.g.,\n        ``(Y**2).sum(axis=1)``)\n\n    squared : boolean, optional\n        Return squared Euclidean distances.\n\n    X_norm_squared : array-like, shape = [n_samples_1], optional\n        Pre-computed dot-products of vectors in X (e.g.,\n        ``(X**2).sum(axis=1)``)\n\n    Returns\n    -------\n    distances : {array, sparse matrix}, shape (n_samples_1, n_samples_2)\n\n    Examples\n    --------\n    >>> from sklearn.metrics.pairwise import euclidean_distances\n    >>> X = [[0, 1], [1, 1]]\n    >>> # distance between rows of X\n    >>> euclidean_distances(X, X)\n    array([[ 0.,  1.],\n           [ 1.,  0.]])\n    >>> # get distance to origin\n    >>> euclidean_distances(X, [[0, 0]])\n    array([[ 1.        ],\n           [ 1.41421356]])\n\n    See also\n    --------\n    paired_distances : distances betweens pairs of elements of X and Y.\n    \"\"\"\n    X, Y = check_pairwise_arrays(X, Y)\n\n    if X_norm_squared is not None:\n        XX = check_array(X_norm_squared)\n        if XX.shape == (1, X.shape[0]):\n            XX = XX.T\n        elif XX.shape != (X.shape[0], 1):\n            raise ValueError(\n                \"Incompatible dimensions for X and X_norm_squared\")\n    else:\n        XX = row_norms(X, squared=True)[:, np.newaxis]\n\n    if X is Y:  # shortcut in the common case euclidean_distances(X, X)\n        YY = XX.T\n    elif Y_norm_squared is not None:\n        YY = np.atleast_2d(Y_norm_squared)\n\n        if YY.shape != (1, Y.shape[0]):\n            raise ValueError(\n                \"Incompatible dimensions for Y and Y_norm_squared\")\n    else:\n        YY = row_norms(Y, squared=True)[np.newaxis, :]\n\n    distances = safe_sparse_dot(X, Y.T, dense_output=True)\n    distances *= -2\n    distances += XX\n    distances += YY\n    np.maximum(distances, 0, out=distances)\n\n    if X is Y:\n        # Ensure that distances between vectors and themselves are set to 0.0.\n        # This may not be the case due to floating point rounding errors.\n        distances.flat[::distances.shape[0] + 1] = 0.0\n\n    return distances if squared else np.sqrt(distances, out=distances)\n\n\ndef pairwise_distances_argmin_min(X, Y, axis=1, metric=\"euclidean\",\n                                  batch_size=500, metric_kwargs=None):\n    \"\"\"Compute minimum distances between one point and a set of points.\n\n    This function computes for each row in X, the index of the row of Y which\n    is closest (according to the specified distance). The minimal distances are\n    also returned.\n\n    This is mostly equivalent to calling:\n\n        (pairwise_distances(X, Y=Y, metric=metric).argmin(axis=axis),\n         pairwise_distances(X, Y=Y, metric=metric).min(axis=axis))\n\n    but uses much less memory, and is faster for large arrays.\n\n    Parameters\n    ----------\n    X : {array-like, sparse matrix}, shape (n_samples1, n_features)\n        Array containing points.\n\n    Y : {array-like, sparse matrix}, shape (n_samples2, n_features)\n        Arrays containing points.\n\n    axis : int, optional, default 1\n        Axis along which the argmin and distances are to be computed.\n\n    metric : string or callable, default 'euclidean'\n        metric to use for distance computation. Any metric from scikit-learn\n        or scipy.spatial.distance can be used.\n\n        If metric is a callable function, it is called on each\n        pair of instances (rows) and the resulting value recorded. The callable\n        should take two arrays as input and return one value indicating the\n        distance between them. This works for Scipy's metrics, but is less\n        efficient than passing the metric name as a string.\n\n        Distance matrices are not supported.\n\n        Valid values for metric are:\n\n        - from scikit-learn: ['cityblock', 'cosine', 'euclidean', 'l1', 'l2',\n          'manhattan']\n\n        - from scipy.spatial.distance: ['braycurtis', 'canberra', 'chebyshev',\n          'correlation', 'dice', 'hamming', 'jaccard', 'kulsinski',\n          'mahalanobis', 'matching', 'minkowski', 'rogerstanimoto',\n          'russellrao', 'seuclidean', 'sokalmichener', 'sokalsneath',\n          'sqeuclidean', 'yule']\n\n        See the documentation for scipy.spatial.distance for details on these\n        metrics.\n\n    batch_size : integer\n        To reduce memory consumption over the naive solution, data are\n        processed in batches, comprising batch_size rows of X and\n        batch_size rows of Y. The default value is quite conservative, but\n        can be changed for fine-tuning. The larger the number, the larger the\n        memory usage.\n\n    metric_kwargs : dict, optional\n        Keyword arguments to pass to specified metric function.\n\n    Returns\n    -------\n    argmin : numpy.ndarray\n        Y[argmin[i], :] is the row in Y that is closest to X[i, :].\n\n    distances : numpy.ndarray\n        distances[i] is the distance between the i-th row in X and the\n        argmin[i]-th row in Y.\n\n    See also\n    --------\n    sklearn.metrics.pairwise_distances\n    sklearn.metrics.pairwise_distances_argmin\n    \"\"\"\n    dist_func = None\n    if metric in PAIRWISE_DISTANCE_FUNCTIONS:\n        dist_func = PAIRWISE_DISTANCE_FUNCTIONS[metric]\n    elif not callable(metric) and not isinstance(metric, str):\n        raise ValueError(\"'metric' must be a string or a callable\")\n\n    X, Y = check_pairwise_arrays(X, Y)\n\n    if metric_kwargs is None:\n        metric_kwargs = {}\n\n    if axis == 0:\n        X, Y = Y, X\n\n    # Allocate output arrays\n    indices = np.empty(X.shape[0], dtype=np.intp)\n    values = np.empty(X.shape[0])\n    values.fill(np.inf)\n\n    for chunk_x in gen_batches(X.shape[0], batch_size):\n        X_chunk = X[chunk_x, :]\n\n        for chunk_y in gen_batches(Y.shape[0], batch_size):\n            Y_chunk = Y[chunk_y, :]\n\n            if dist_func is not None:\n                if metric == 'euclidean':  # special case, for speed\n                    d_chunk = safe_sparse_dot(X_chunk, Y_chunk.T,\n                                              dense_output=True)\n                    d_chunk *= -2\n                    d_chunk += row_norms(X_chunk, squared=True)[:, np.newaxis]\n                    d_chunk += row_norms(Y_chunk, squared=True)[np.newaxis, :]\n                    np.maximum(d_chunk, 0, d_chunk)\n                else:\n                    d_chunk = dist_func(X_chunk, Y_chunk, **metric_kwargs)\n            else:\n                d_chunk = pairwise_distances(X_chunk, Y_chunk,\n                                             metric=metric, **metric_kwargs)\n\n            # Update indices and minimum values using chunk\n            min_indices = d_chunk.argmin(axis=1)\n            min_values = d_chunk[np.arange(chunk_x.stop - chunk_x.start),\n                                 min_indices]\n\n            flags = values[chunk_x] > min_values\n            indices[chunk_x][flags] = min_indices[flags] + chunk_y.start\n            values[chunk_x][flags] = min_values[flags]\n\n    if metric == \"euclidean\" and not metric_kwargs.get(\"squared\", False):\n        np.sqrt(values, values)\n    return indices, values\n\n\ndef check_pairwise_arrays(X, Y, precomputed=False, dtype=None):\n    \"\"\" Set X and Y appropriately and checks inputs\n\n    If Y is None, it is set as a pointer to X (i.e. not a copy).\n    If Y is given, this does not happen.\n    All distance metrics should use this function first to assert that the\n    given parameters are correct and safe to use.\n\n    Specifically, this function first ensures that both X and Y are arrays,\n    then checks that they are at least two dimensional while ensuring that\n    their elements are floats (or dtype if provided). Finally, the function\n    checks that the size of the second dimension of the two arrays is equal, or\n    the equivalent check for a precomputed distance matrix.\n\n    Parameters\n    ----------\n    X : {array-like, sparse matrix}, shape (n_samples_a, n_features)\n\n    Y : {array-like, sparse matrix}, shape (n_samples_b, n_features)\n\n    precomputed : bool\n        True if X is to be treated as precomputed distances to the samples in\n        Y.\n\n    dtype : string, type, list of types or None (default=None)\n        Data type required for X and Y. If None, the dtype will be an\n        appropriate float type selected by _return_float_dtype.\n\n        .. versionadded:: 0.18\n\n    Returns\n    -------\n    safe_X : {array-like, sparse matrix}, shape (n_samples_a, n_features)\n        An array equal to X, guaranteed to be a numpy array.\n\n    safe_Y : {array-like, sparse matrix}, shape (n_samples_b, n_features)\n        An array equal to Y if Y was not None, guaranteed to be a numpy array.\n        If Y was None, safe_Y will be a pointer to X.\n\n    \"\"\"\n    X, Y, dtype_float = _return_float_dtype(X, Y)\n\n    warn_on_dtype = dtype is not None\n    estimator = 'check_pairwise_arrays'\n    if dtype is None:\n        dtype = dtype_float\n\n    if Y is X or Y is None:\n        X = Y = check_array(X, accept_sparse='csr', dtype=dtype,\n                            warn_on_dtype=warn_on_dtype, estimator=estimator)\n    else:\n        X = check_array(X, accept_sparse='csr', dtype=dtype,\n                        warn_on_dtype=warn_on_dtype, estimator=estimator)\n        Y = check_array(Y, accept_sparse='csr', dtype=dtype,\n                        warn_on_dtype=warn_on_dtype, estimator=estimator)\n\n    if precomputed:\n        if X.shape[1] != Y.shape[0]:\n            raise ValueError(\"Precomputed metric requires shape \"\n                             \"(n_queries, n_indexed). Got (%d, %d) \"\n                             \"for %d indexed.\" %\n                             (X.shape[0], X.shape[1], Y.shape[0]))\n    elif X.shape[1] != Y.shape[1]:\n        raise ValueError(\"Incompatible dimension for X and Y matrices: \"\n                         \"X.shape[1] == %d while Y.shape[1] == %d\" % (\n                             X.shape[1], Y.shape[1]))\n\n    return X, Y\n\n\ndef manhattan_distances(X, Y=None, sum_over_features=True,\n                        size_threshold=None):\n    \"\"\" Compute the L1 distances between the vectors in X and Y.\n\n    With sum_over_features equal to False it returns the componentwise\n    distances.\n\n    Read more in the :ref:`User Guide <metrics>`.\n\n    Parameters\n    ----------\n    X : array_like\n        An array with shape (n_samples_X, n_features).\n\n    Y : array_like, optional\n        An array with shape (n_samples_Y, n_features).\n\n    sum_over_features : bool, default=True\n        If True the function returns the pairwise distance matrix\n        else it returns the componentwise L1 pairwise-distances.\n        Not supported for sparse matrix inputs.\n\n    size_threshold : int, default=5e8\n        Unused parameter.\n\n    Returns\n    -------\n    D : array\n        If sum_over_features is False shape is\n        (n_samples_X * n_samples_Y, n_features) and D contains the\n        componentwise L1 pairwise-distances (ie. absolute difference),\n        else shape is (n_samples_X, n_samples_Y) and D contains\n        the pairwise L1 distances.\n\n    Examples\n    --------\n    >>> from sklearn.metrics.pairwise import manhattan_distances\n    >>> manhattan_distances([[3]], [[3]])#doctest:+ELLIPSIS\n    array([[ 0.]])\n    >>> manhattan_distances([[3]], [[2]])#doctest:+ELLIPSIS\n    array([[ 1.]])\n    >>> manhattan_distances([[2]], [[3]])#doctest:+ELLIPSIS\n    array([[ 1.]])\n    >>> manhattan_distances([[1, 2], [3, 4]],\\\n         [[1, 2], [0, 3]])#doctest:+ELLIPSIS\n    array([[ 0.,  2.],\n           [ 4.,  4.]])\n    >>> import numpy as np\n    >>> X = np.ones((1, 2))\n    >>> y = 2 * np.ones((2, 2))\n    >>> manhattan_distances(X, y, sum_over_features=False)#doctest:+ELLIPSIS\n    array([[ 1.,  1.],\n           [ 1.,  1.]]...)\n    \"\"\"\n    if size_threshold is not None:\n        warnings.warn('Use of the \"size_threshold\" is deprecated '\n                      'in 0.19 and it will be removed version '\n                      '0.21 of scikit-learn', DeprecationWarning)\n    X, Y = check_pairwise_arrays(X, Y)\n\n    if issparse(X) or issparse(Y):\n        if not sum_over_features:\n            raise TypeError(\"sum_over_features=%r not supported\"\n                            \" for sparse matrices\" % sum_over_features)\n\n        X = csr_matrix(X, copy=False)\n        Y = csr_matrix(Y, copy=False)\n        D = np.zeros((X.shape[0], Y.shape[0]))\n        _sparse_manhattan(X.data, X.indices, X.indptr,\n                          Y.data, Y.indices, Y.indptr,\n                          X.shape[1], D)\n        return D\n\n    if sum_over_features:\n        return distance.cdist(X, Y, 'cityblock')\n\n    D = X[:, np.newaxis, :] - Y[np.newaxis, :, :]\n    D = np.abs(D, D)\n    return D.reshape((-1, X.shape[1]))\n\n\ndef cosine_distances(X, Y=None):\n    \"\"\"Compute cosine distance between samples in X and Y.\n\n    Cosine distance is defined as 1.0 minus the cosine similarity.\n\n    Read more in the :ref:`User Guide <metrics>`.\n\n    Parameters\n    ----------\n    X : array_like, sparse matrix\n        with shape (n_samples_X, n_features).\n\n    Y : array_like, sparse matrix (optional)\n        with shape (n_samples_Y, n_features).\n\n    Returns\n    -------\n    distance matrix : array\n        An array with shape (n_samples_X, n_samples_Y).\n\n    See also\n    --------\n    sklearn.metrics.pairwise.cosine_similarity\n    scipy.spatial.distance.cosine (dense matrices only)\n    \"\"\"\n    # 1.0 - cosine_similarity(X, Y) without copy\n    S = cosine_similarity(X, Y)\n    S *= -1\n    S += 1\n    np.clip(S, 0, 2, out=S)\n    if X is Y or Y is None:\n        # Ensure that distances between vectors and themselves are set to 0.0.\n        # This may not be the case due to floating point rounding errors.\n        S[np.diag_indices_from(S)] = 0.0\n    return S\n\n\nPAIRWISE_DISTANCE_FUNCTIONS = {\n    # If updating this dictionary, update the doc in both distance_metrics()\n    # and also in pairwise_distances()!\n    'cityblock': manhattan_distances,\n    'cosine': cosine_distances,\n    'euclidean': euclidean_distances,\n    'l2': euclidean_distances,\n    'l1': manhattan_distances,\n    'manhattan': manhattan_distances,\n    'precomputed': None,  # HACK: precomputed is always allowed, never called\n}\n\n\ndef pairwise_distances(X, Y=None, metric=\"euclidean\", n_jobs=1, **kwds):\n    \"\"\" Compute the distance matrix from a vector array X and optional Y.\n\n    This method takes either a vector array or a distance matrix, and returns\n    a distance matrix. If the input is a vector array, the distances are\n    computed. If the input is a distances matrix, it is returned instead.\n\n    This method provides a safe way to take a distance matrix as input, while\n    preserving compatibility with many other algorithms that take a vector\n    array.\n\n    If Y is given (default is None), then the returned matrix is the pairwise\n    distance between the arrays from both X and Y.\n\n    Valid values for metric are:\n\n    - From scikit-learn: ['cityblock', 'cosine', 'euclidean', 'l1', 'l2',\n      'manhattan']. These metrics support sparse matrix inputs.\n\n    - From scipy.spatial.distance: ['braycurtis', 'canberra', 'chebyshev',\n      'correlation', 'dice', 'hamming', 'jaccard', 'kulsinski', 'mahalanobis',\n      'matching', 'minkowski', 'rogerstanimoto', 'russellrao', 'seuclidean',\n      'sokalmichener', 'sokalsneath', 'sqeuclidean', 'yule']\n      See the documentation for scipy.spatial.distance for details on these\n      metrics. These metrics do not support sparse matrix inputs.\n\n    Note that in the case of 'cityblock', 'cosine' and 'euclidean' (which are\n    valid scipy.spatial.distance metrics), the scikit-learn implementation\n    will be used, which is faster and has support for sparse matrices (except\n    for 'cityblock'). For a verbose description of the metrics from\n    scikit-learn, see the __doc__ of the sklearn.pairwise.distance_metrics\n    function.\n\n    Read more in the :ref:`User Guide <metrics>`.\n\n    Parameters\n    ----------\n    X : array [n_samples_a, n_samples_a] if metric == \"precomputed\", or, \\\n             [n_samples_a, n_features] otherwise\n        Array of pairwise distances between samples, or a feature array.\n\n    Y : array [n_samples_b, n_features], optional\n        An optional second feature array. Only allowed if metric != \"precomputed\".\n\n    metric : string, or callable\n        The metric to use when calculating distance between instances in a\n        feature array. If metric is a string, it must be one of the options\n        allowed by scipy.spatial.distance.pdist for its metric parameter, or\n        a metric listed in pairwise.PAIRWISE_DISTANCE_FUNCTIONS.\n        If metric is \"precomputed\", X is assumed to be a distance matrix.\n        Alternatively, if metric is a callable function, it is called on each\n        pair of instances (rows) and the resulting value recorded. The callable\n        should take two arrays from X as input and return a value indicating\n        the distance between them.\n\n    n_jobs : int\n        The number of jobs to use for the computation. This works by breaking\n        down the pairwise matrix into n_jobs even slices and computing them in\n        parallel.\n\n        If -1 all CPUs are used. If 1 is given, no parallel computing code is\n        used at all, which is useful for debugging. For n_jobs below -1,\n        (n_cpus + 1 + n_jobs) are used. Thus for n_jobs = -2, all CPUs but one\n        are used.\n\n    **kwds : optional keyword parameters\n        Any further parameters are passed directly to the distance function.\n        If using a scipy.spatial.distance metric, the parameters are still\n        metric dependent. See the scipy docs for usage examples.\n\n    Returns\n    -------\n    D : array [n_samples_a, n_samples_a] or [n_samples_a, n_samples_b]\n        A distance matrix D such that D_{i, j} is the distance between the\n        ith and jth vectors of the given matrix X, if Y is None.\n        If Y is not None, then D_{i, j} is the distance between the ith array\n        from X and the jth array from Y.\n\n    \"\"\"\n    if (metric not in _VALID_METRICS and\n            not callable(metric) and metric != \"precomputed\"):\n        raise ValueError(\"Unknown metric %s. \"\n                         \"Valid metrics are %s, or 'precomputed', or a \"\n                         \"callable\" % (metric, _VALID_METRICS))\n\n    if metric == \"precomputed\":\n        X, _ = check_pairwise_arrays(X, Y, precomputed=True)\n        return X\n    elif metric in PAIRWISE_DISTANCE_FUNCTIONS:\n        func = PAIRWISE_DISTANCE_FUNCTIONS[metric]\n    elif callable(metric):\n        func = partial(_pairwise_callable, metric=metric, **kwds)\n    else:\n        if issparse(X) or issparse(Y):\n            raise TypeError(\"scipy distance metrics do not\"\n                            \" support sparse matrices.\")\n\n        dtype = bool if metric in PAIRWISE_BOOLEAN_FUNCTIONS else None\n\n        X, Y = check_pairwise_arrays(X, Y, dtype=dtype)\n\n        if n_jobs == 1 and X is Y:\n            return distance.squareform(distance.pdist(X, metric=metric,\n                                                      **kwds))\n        func = partial(distance.cdist, metric=metric, **kwds)\n\n    return _parallel_pairwise(X, Y, func, n_jobs, **kwds)\n\n\ndef _return_float_dtype(X, Y):\n    \"\"\"\n    1. If dtype of X and Y is float32, then dtype float32 is returned.\n    2. Else dtype float is returned.\n    \"\"\"\n    if not issparse(X) and not isinstance(X, np.ndarray):\n        X = np.asarray(X)\n\n    if Y is None:\n        Y_dtype = X.dtype\n    elif not issparse(Y) and not isinstance(Y, np.ndarray):\n        Y = np.asarray(Y)\n        Y_dtype = Y.dtype\n    else:\n        Y_dtype = Y.dtype\n\n    if X.dtype == Y_dtype == np.float32:\n        dtype = np.float32\n    else:\n        dtype = float\n\n    return X, Y, dtype\n\n\ndef _parallel_pairwise(X, Y, func, n_jobs, **kwds):\n    \"\"\"Break the pairwise matrix in n_jobs even slices\n    and compute them in parallel\"\"\"\n    if n_jobs < 0:\n        n_jobs = max(cpu_count() + 1 + n_jobs, 1)\n\n    if Y is None:\n        Y = X\n\n    if n_jobs == 1:\n        # Special case to avoid picklability checks in delayed\n        return func(X, Y, **kwds)\n\n    # TODO: in some cases, backend='threading' may be appropriate\n    fd = delayed(func)\n    ret = Parallel(n_jobs=n_jobs, verbose=0)(\n        fd(X, Y[s], **kwds)\n        for s in gen_even_slices(Y.shape[0], n_jobs))\n\n    return np.hstack(ret)\n\n\ndef _pairwise_callable(X, Y, metric, **kwds):\n    \"\"\"Handle the callable case for pairwise_{distances,kernels}\n    \"\"\"\n    X, Y = check_pairwise_arrays(X, Y)\n\n    if X is Y:\n        # Only calculate metric for upper triangle\n        out = np.zeros((X.shape[0], Y.shape[0]), dtype='float')\n        iterator = itertools.combinations(range(X.shape[0]), 2)\n        for i, j in iterator:\n            out[i, j] = metric(X[i], Y[j], **kwds)\n\n        # Make symmetric\n        # NB: out += out.T will produce incorrect results\n        out = out + out.T\n\n        # Calculate diagonal\n        # NB: nonzero diagonals are allowed for both metrics and kernels\n        for i in range(X.shape[0]):\n            x = X[i]\n            out[i, i] = metric(x, x, **kwds)\n\n    else:\n        # Calculate all cells\n        out = np.empty((X.shape[0], Y.shape[0]), dtype='float')\n        iterator = itertools.product(range(X.shape[0]), range(Y.shape[0]))\n        for i, j in iterator:\n            out[i, j] = metric(X[i], Y[j], **kwds)\n\n    return out\n\n\nPAIRWISE_BOOLEAN_FUNCTIONS = [\n    'dice',\n    'jaccard',\n    'kulsinski',\n    'matching',\n    'rogerstanimoto',\n    'russellrao',\n    'sokalmichener',\n    'sokalsneath',\n    'yule',\n]\n\n\ndef cosine_similarity(X, Y=None, dense_output=True):\n    \"\"\"Compute cosine similarity between samples in X and Y.\n\n    Cosine similarity, or the cosine kernel, computes similarity as the\n    normalized dot product of X and Y:\n\n        K(X, Y) = <X, Y> / (||X||*||Y||)\n\n    On L2-normalized data, this function is equivalent to linear_kernel.\n\n    Read more in the :ref:`User Guide <cosine_similarity>`.\n\n    Parameters\n    ----------\n    X : ndarray or sparse array, shape: (n_samples_X, n_features)\n        Input data.\n\n    Y : ndarray or sparse array, shape: (n_samples_Y, n_features)\n        Input data. If ``None``, the output will be the pairwise\n        similarities between all samples in ``X``.\n\n    dense_output : boolean (optional), default True\n        Whether to return dense output even when the input is sparse. If\n        ``False``, the output is sparse if both input arrays are sparse.\n\n        .. versionadded:: 0.17\n           parameter ``dense_output`` for dense output.\n\n    Returns\n    -------\n    kernel matrix : array\n        An array with shape (n_samples_X, n_samples_Y).\n    \"\"\"\n    # to avoid recursive import\n\n    X, Y = check_pairwise_arrays(X, Y)\n\n    X_normalized = normalize(X, copy=True)\n    if X is Y:\n        Y_normalized = X_normalized\n    else:\n        Y_normalized = normalize(Y, copy=True)\n\n    K = safe_sparse_dot(X_normalized, Y_normalized.T, dense_output=dense_output)\n\n    return K\n\n\n_VALID_METRICS = ['euclidean', 'l2', 'l1', 'manhattan', 'cityblock',\n                  'braycurtis', 'canberra', 'chebyshev', 'correlation',\n                  'cosine', 'dice', 'hamming', 'jaccard', 'kulsinski',\n                  'mahalanobis', 'matching', 'minkowski', 'rogerstanimoto',\n                  'russellrao', 'seuclidean', 'sokalmichener',\n                  'sokalsneath', 'sqeuclidean', 'yule', \"wminkowski\"]"
  },
  {
    "path": "k_means_constrained/sklearn_import/metrics/pairwise_fast.pyx",
    "content": "#cython: boundscheck=False\n#cython: cdivision=True\n#cython: wraparound=False\n# distutils: define_macros=NPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION\n\n# Author: Andreas Mueller <amueller@ais.uni-bonn.de>\n#         Lars Buitinck\n#\n# License: BSD 3 clause\n\nfrom libc.string cimport memset\nimport numpy as np\ncimport numpy as np\n\nctypedef float [:, :] float_array_2d_t\nctypedef double [:, :] double_array_2d_t\n\ncdef fused floating1d:\n    float[::1]\n    double[::1]\n\ncdef fused floating_array_2d_t:\n    float_array_2d_t\n    double_array_2d_t\n\n\nnp.import_array()\n\n\ndef _sparse_manhattan(floating1d X_data, int[:] X_indices, int[:] X_indptr,\n                      floating1d Y_data, int[:] Y_indices, int[:] Y_indptr,\n                      np.npy_intp n_features, double[:, ::1] D):\n    \"\"\"Pairwise L1 distances for CSR matrices.\n\n    Usage:\n\n    >>> D = np.zeros(X.shape[0], Y.shape[0])\n    >>> sparse_manhattan(X.data, X.indices, X.indptr,\n    ...                  Y.data, Y.indices, Y.indptr,\n    ...                  X.shape[1], D)\n    \"\"\"\n    cdef double[::1] row = np.empty(n_features)\n    cdef np.npy_intp ix, iy, j\n\n    with nogil:\n        for ix in range(D.shape[0]):\n            for iy in range(D.shape[1]):\n                # Simple strategy: densify current row of X, then subtract the\n                # corresponding row of Y.\n                memset(&row[0], 0, n_features * sizeof(double))\n                for j in range(X_indptr[ix], X_indptr[ix + 1]):\n                    row[X_indices[j]] = X_data[j]\n                for j in range(Y_indptr[iy], Y_indptr[iy + 1]):\n                    row[Y_indices[j]] -= Y_data[j]\n\n                with gil:\n                    D[ix, iy] = row[0].abs().sum()"
  },
  {
    "path": "k_means_constrained/sklearn_import/preprocessing/__init__.py",
    "content": ""
  },
  {
    "path": "k_means_constrained/sklearn_import/preprocessing/data.py",
    "content": "import numpy as np\nfrom scipy import sparse\n\nfrom k_means_constrained.sklearn_import.utils.sparsefuncs_fast import inplace_csr_row_normalize_l1, inplace_csr_row_normalize_l2\n\nfrom k_means_constrained.sklearn_import.utils.sparsefuncs import min_max_axis\n\nfrom k_means_constrained.sklearn_import.utils.extmath import row_norms\nfrom k_means_constrained.sklearn_import.utils.validation import check_array, FLOAT_DTYPES\n\n\ndef normalize(X, norm='l2', axis=1, copy=True, return_norm=False):\n    \"\"\"Scale input vectors individually to unit norm (vector length).\n\n    Read more in the :ref:`User Guide <preprocessing_normalization>`.\n\n    Parameters\n    ----------\n    X : {array-like, sparse matrix}, shape [n_samples, n_features]\n        The data to normalize, element by element.\n        scipy.sparse matrices should be in CSR format to avoid an\n        un-necessary copy.\n\n    norm : 'l1', 'l2', or 'max', optional ('l2' by default)\n        The norm to use to normalize each non zero sample (or each non-zero\n        feature if axis is 0).\n\n    axis : 0 or 1, optional (1 by default)\n        axis used to normalize the data along. If 1, independently normalize\n        each sample, otherwise (if 0) normalize each feature.\n\n    copy : boolean, optional, default True\n        set to False to perform inplace row normalization and avoid a\n        copy (if the input is already a numpy array or a scipy.sparse\n        CSR matrix and if axis is 1).\n\n    return_norm : boolean, default False\n        whether to return the computed norms\n\n    Returns\n    -------\n    X : {array-like, sparse matrix}, shape [n_samples, n_features]\n        Normalized input X.\n\n    norms : array, shape [n_samples] if axis=1 else [n_features]\n        An array of norms along given axis for X.\n        When X is sparse, a NotImplementedError will be raised\n        for norm 'l1' or 'l2'.\n\n    See also\n    --------\n    Normalizer: Performs normalization using the ``Transformer`` API\n        (e.g. as part of a preprocessing :class:`sklearn.pipeline.Pipeline`).\n\n    Notes\n    -----\n    For a comparison of the different scalers, transformers, and normalizers,\n    see :ref:`examples/preprocessing/plot_all_scaling.py\n    <sphx_glr_auto_examples_preprocessing_plot_all_scaling.py>`.\n\n    \"\"\"\n    if norm not in ('l1', 'l2', 'max'):\n        raise ValueError(\"'%s' is not a supported norm\" % norm)\n\n    if axis == 0:\n        sparse_format = 'csc'\n    elif axis == 1:\n        sparse_format = 'csr'\n    else:\n        raise ValueError(\"'%d' is not a supported axis\" % axis)\n\n    X = check_array(X, sparse_format, copy=copy,\n                    estimator='the normalize function', dtype=FLOAT_DTYPES)\n    if axis == 0:\n        X = X.T\n\n    if sparse.issparse(X):\n        if return_norm and norm in ('l1', 'l2'):\n            raise NotImplementedError(\"return_norm=True is not implemented \"\n                                      \"for sparse matrices with norm 'l1' \"\n                                      \"or norm 'l2'\")\n        if norm == 'l1':\n            inplace_csr_row_normalize_l1(X)\n        elif norm == 'l2':\n            inplace_csr_row_normalize_l2(X)\n        elif norm == 'max':\n            _, norms = min_max_axis(X, 1)\n            norms_elementwise = norms.repeat(np.diff(X.indptr))\n            mask = norms_elementwise != 0\n            X.data[mask] /= norms_elementwise[mask]\n    else:\n        if norm == 'l1':\n            norms = np.abs(X).sum(axis=1)\n        elif norm == 'l2':\n            norms = row_norms(X)\n        elif norm == 'max':\n            norms = np.max(X, axis=1)\n        norms = _handle_zeros_in_scale(norms, copy=False)\n        X /= norms[:, np.newaxis]\n\n    if axis == 0:\n        X = X.T\n\n    if return_norm:\n        return X, norms\n    else:\n        return X\n\n\ndef _handle_zeros_in_scale(scale, copy=True):\n    ''' Makes sure that whenever scale is zero, we handle it correctly.\n\n    This happens in most scalers when we have constant features.'''\n\n    # if we are fitting on 1D arrays, scale might be a scalar\n    if np.isscalar(scale):\n        if scale == .0:\n            scale = 1.\n        return scale\n    elif isinstance(scale, np.ndarray):\n        if copy:\n            # New array to avoid side-effects\n            scale = scale.copy()\n        scale[scale == 0.0] = 1.0\n        return scale"
  },
  {
    "path": "k_means_constrained/sklearn_import/utils/__init__.py",
    "content": "def gen_batches(n, batch_size):\n    \"\"\"Generator to create slices containing batch_size elements, from 0 to n.\n\n    The last slice may contain less than batch_size elements, when batch_size\n    does not divide n.\n\n    Examples\n    --------\n    >>> from sklearn.utils import gen_batches\n    >>> list(gen_batches(7, 3))\n    [slice(0, 3, None), slice(3, 6, None), slice(6, 7, None)]\n    >>> list(gen_batches(6, 3))\n    [slice(0, 3, None), slice(3, 6, None)]\n    >>> list(gen_batches(2, 3))\n    [slice(0, 2, None)]\n    \"\"\"\n    start = 0\n    for _ in range(int(n // batch_size)):\n        end = start + batch_size\n        yield slice(start, end)\n        start = end\n    if start < n:\n        yield slice(start, n)\n\n\ndef gen_even_slices(n, n_packs, n_samples=None):\n    \"\"\"Generator to create n_packs slices going up to n.\n\n    Pass n_samples when the slices are to be used for sparse matrix indexing;\n    slicing off-the-end raises an exception, while it works for NumPy arrays.\n\n    Examples\n    --------\n    >>> from sklearn.utils import gen_even_slices\n    >>> list(gen_even_slices(10, 1))\n    [slice(0, 10, None)]\n    >>> list(gen_even_slices(10, 10))                     #doctest: +ELLIPSIS\n    [slice(0, 1, None), slice(1, 2, None), ..., slice(9, 10, None)]\n    >>> list(gen_even_slices(10, 5))                      #doctest: +ELLIPSIS\n    [slice(0, 2, None), slice(2, 4, None), ..., slice(8, 10, None)]\n    >>> list(gen_even_slices(10, 3))\n    [slice(0, 4, None), slice(4, 7, None), slice(7, 10, None)]\n    \"\"\"\n    start = 0\n    if n_packs < 1:\n        raise ValueError(\"gen_even_slices got n_packs=%s, must be >=1\"\n                         % n_packs)\n    for pack_num in range(n_packs):\n        this_n = n // n_packs\n        if pack_num < n % n_packs:\n            this_n += 1\n        if this_n > 0:\n            end = start + this_n\n            if n_samples is not None:\n                end = min(n_samples, end)\n            yield slice(start, end, None)\n            start = end"
  },
  {
    "path": "k_means_constrained/sklearn_import/utils/extmath.py",
    "content": "import warnings\n\nimport numpy as np\nfrom scipy.sparse import issparse, csr_matrix\nfrom k_means_constrained.sklearn_import.utils.sparsefuncs_fast import csr_row_norms\n\nfrom k_means_constrained.sklearn_import.utils.fixes import np_version\n\n\ndef row_norms(X, squared=False):\n    \"\"\"Row-wise (squared) Euclidean norm of X.\n\n    Equivalent to np.sqrt((X * X).sum(axis=1)), but also supports sparse\n    matrices and does not create an X.shape-sized temporary.\n\n    Performs no input validation.\n    \"\"\"\n    if issparse(X):\n        if not isinstance(X, csr_matrix):\n            X = csr_matrix(X)\n        norms = csr_row_norms(X)\n    else:\n        norms = np.einsum('ij,ij->i', X, X)\n\n    if not squared:\n        np.sqrt(norms, norms)\n    return norms\n\n\ndef squared_norm(x):\n    \"\"\"Squared Euclidean or Frobenius norm of x.\n\n    Returns the Euclidean norm when x is a vector, the Frobenius norm when x\n    is a matrix (2-d array). Faster than norm(x) ** 2.\n    \"\"\"\n    x = np.ravel(x, order='K')\n    if np.issubdtype(x.dtype, np.integer):\n        warnings.warn('Array type is integer, np.dot may overflow. '\n                      'Data should be float type to avoid this issue',\n                      UserWarning)\n    return np.dot(x, x)\n\n\ndef cartesian(arrays, out=None):\n    \"\"\"Generate a cartesian product of input arrays.\n\n    Parameters\n    ----------\n    arrays : list of array-like\n        1-D arrays to form the cartesian product of.\n    out : ndarray\n        Array to place the cartesian product in.\n\n    Returns\n    -------\n    out : ndarray\n        2-D array of shape (M, len(arrays)) containing cartesian products\n        formed of input arrays.\n\n    Examples\n    --------\n    >>> cartesian(([1, 2, 3], [4, 5], [6, 7]))\n    array([[1, 4, 6],\n           [1, 4, 7],\n           [1, 5, 6],\n           [1, 5, 7],\n           [2, 4, 6],\n           [2, 4, 7],\n           [2, 5, 6],\n           [2, 5, 7],\n           [3, 4, 6],\n           [3, 4, 7],\n           [3, 5, 6],\n           [3, 5, 7]])\n\n    \"\"\"\n    arrays = [np.asarray(x) for x in arrays]\n    shape = (len(x) for x in arrays)\n    dtype = arrays[0].dtype\n\n    ix = np.indices(shape)\n    ix = ix.reshape(len(arrays), -1).T\n\n    if out is None:\n        out = np.empty_like(ix, dtype=dtype)\n\n    for n, arr in enumerate(arrays):\n        out[:, n] = arrays[n][ix[:, n]]\n\n    return out\n\n\ndef stable_cumsum(arr, axis=None, rtol=1e-05, atol=1e-08):\n    \"\"\"Use high precision for cumsum and check that final value matches sum\n\n    Parameters\n    ----------\n    arr : array-like\n        To be cumulatively summed as flat\n    axis : int, optional\n        Axis along which the cumulative sum is computed.\n        The default (None) is to compute the cumsum over the flattened array.\n    rtol : float\n        Relative tolerance, see ``np.allclose``\n    atol : float\n        Absolute tolerance, see ``np.allclose``\n    \"\"\"\n    # sum is as unstable as cumsum for numpy < 1.9\n    if np_version < (1, 9):\n        return np.cumsum(arr, axis=axis, dtype=np.float64)\n\n    out = np.cumsum(arr, axis=axis, dtype=np.float64)\n    expected = np.sum(arr, axis=axis, dtype=np.float64)\n    if not np.all(np.isclose(out.take(-1, axis=axis), expected, rtol=rtol,\n                             atol=atol, equal_nan=True)):\n        warnings.warn('cumsum was found to be unstable: '\n                      'its last element does not correspond to sum',\n                      RuntimeWarning)\n    return out\n\n\ndef safe_sparse_dot(a, b, dense_output=False):\n    \"\"\"Dot product that handle the sparse matrix case correctly\n\n    Uses BLAS GEMM as replacement for numpy.dot where possible\n    to avoid unnecessary copies.\n\n    Parameters\n    ----------\n    a : array or sparse matrix\n    b : array or sparse matrix\n    dense_output : boolean, default False\n        When False, either ``a`` or ``b`` being sparse will yield sparse\n        output. When True, output will always be an array.\n\n    Returns\n    -------\n    dot_product : array or sparse matrix\n        sparse if ``a`` or ``b`` is sparse and ``dense_output=False``.\n    \"\"\"\n    if issparse(a) or issparse(b):\n        ret = a * b\n        if dense_output and hasattr(ret, \"toarray\"):\n            ret = ret.toarray()\n        return ret\n    else:\n        return np.dot(a, b)"
  },
  {
    "path": "k_means_constrained/sklearn_import/utils/fixes.py",
    "content": "import numpy as np\nfrom k_means_constrained.sklearn_import.fixes import _parse_version\n\nnp_version = _parse_version(np.__version__)\n\n\ndef sparse_min_max(X, axis):\n    return (X.min(axis=axis).toarray().ravel(),\n            X.max(axis=axis).toarray().ravel())"
  },
  {
    "path": "k_means_constrained/sklearn_import/utils/sparsefuncs.py",
    "content": "from scipy import sparse as sp\nfrom k_means_constrained.sklearn_import.utils.fixes import sparse_min_max\n\nfrom .sparsefuncs_fast import (\n    csr_mean_variance_axis0 as _csr_mean_var_axis0,\n    csc_mean_variance_axis0 as _csc_mean_var_axis0)\n\n\ndef mean_variance_axis(X, axis):\n    \"\"\"Compute mean and variance along an axix on a CSR or CSC matrix\n\n    Parameters\n    ----------\n    X : CSR or CSC sparse matrix, shape (n_samples, n_features)\n        Input data.\n\n    axis : int (either 0 or 1)\n        Axis along which the axis should be computed.\n\n    Returns\n    -------\n\n    means : float array with shape (n_features,)\n        Feature-wise means\n\n    variances : float array with shape (n_features,)\n        Feature-wise variances\n\n    \"\"\"\n    _raise_error_wrong_axis(axis)\n\n    if isinstance(X, sp.csr_matrix):\n        if axis == 0:\n            return _csr_mean_var_axis0(X)\n        else:\n            return _csc_mean_var_axis0(X.T)\n    elif isinstance(X, sp.csc_matrix):\n        if axis == 0:\n            return _csc_mean_var_axis0(X)\n        else:\n            return _csr_mean_var_axis0(X.T)\n    else:\n        _raise_typeerror(X)\n\n\ndef min_max_axis(X, axis):\n    \"\"\"Compute minimum and maximum along an axis on a CSR or CSC matrix\n\n    Parameters\n    ----------\n    X : CSR or CSC sparse matrix, shape (n_samples, n_features)\n        Input data.\n\n    axis : int (either 0 or 1)\n        Axis along which the axis should be computed.\n\n    Returns\n    -------\n\n    mins : float array with shape (n_features,)\n        Feature-wise minima\n\n    maxs : float array with shape (n_features,)\n        Feature-wise maxima\n    \"\"\"\n    if isinstance(X, sp.csr_matrix) or isinstance(X, sp.csc_matrix):\n        return sparse_min_max(X, axis=axis)\n    else:\n        _raise_typeerror(X)\n\n\ndef _raise_typeerror(X):\n    \"\"\"Raises a TypeError if X is not a CSR or CSC matrix\"\"\"\n    input_type = X.format if sp.issparse(X) else type(X)\n    err = \"Expected a CSR or CSC sparse matrix, got %s.\" % input_type\n    raise TypeError(err)\n\n\ndef _raise_error_wrong_axis(axis):\n    if axis not in (0, 1):\n        raise ValueError(\n            \"Unknown axis value: %d. Use 0 for rows, or 1 for columns\" % axis)"
  },
  {
    "path": "k_means_constrained/sklearn_import/utils/sparsefuncs_fast.pyx",
    "content": "# Authors: Mathieu Blondel\n#          Olivier Grisel\n#          Peter Prettenhofer\n#          Lars Buitinck\n#          Giorgio Patrini\n#\n# License: BSD 3 clause\n\n#!python\n#cython: boundscheck=False, wraparound=False, cdivision=True\n# distutils: define_macros=NPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION\n\nfrom libc.math cimport fabs, sqrt, pow\ncimport numpy as np\nimport numpy as np\nimport scipy.sparse as sp\ncimport cython\nfrom cython cimport floating\n\nnp.import_array()\n\n\nctypedef np.float64_t DOUBLE\n\ndef csr_row_norms(X):\n    \"\"\"L2 norm of each row in CSR matrix X.\"\"\"\n    if X.dtype != np.float32:\n        X = X.astype(np.float64)\n    return _csr_row_norms(X.data, X.shape, X.indices, X.indptr)\n\n\ndef _csr_row_norms(np.ndarray[floating, ndim=1, mode=\"c\"] X_data,\n                   shape,\n                   np.ndarray[int, ndim=1, mode=\"c\"] X_indices,\n                   np.ndarray[int, ndim=1, mode=\"c\"] X_indptr):\n    cdef:\n        unsigned int n_samples = shape[0]\n        unsigned int n_features = shape[1]\n        np.ndarray[DOUBLE, ndim=1, mode=\"c\"] norms\n\n        np.npy_intp i, j\n        double sum_\n\n    norms = np.zeros(n_samples, dtype=np.float64)\n\n    for i in range(n_samples):\n        sum_ = 0.0\n        for j in range(X_indptr[i], X_indptr[i + 1]):\n            sum_ += X_data[j] * X_data[j]\n        norms[i] = sum_\n\n    return norms\n\n\ndef csr_mean_variance_axis0(X):\n    \"\"\"Compute mean and variance along axis 0 on a CSR matrix\n\n    Parameters\n    ----------\n    X : CSR sparse matrix, shape (n_samples, n_features)\n        Input data.\n\n    Returns\n    -------\n\n    means : float array with shape (n_features,)\n        Feature-wise means\n\n    variances : float array with shape (n_features,)\n        Feature-wise variances\n\n    \"\"\"\n    if X.dtype != np.float32:\n        X = X.astype(np.float64)\n    return _csr_mean_variance_axis0(X.data, X.shape, X.indices)\n\n\ndef _csr_mean_variance_axis0(np.ndarray[floating, ndim=1, mode=\"c\"] X_data,\n                             shape,\n                             np.ndarray[int, ndim=1] X_indices):\n    # Implement the function here since variables using fused types\n    # cannot be declared directly and can only be passed as function arguments\n    cdef unsigned int n_samples = shape[0]\n    cdef unsigned int n_features = shape[1]\n\n    cdef unsigned int i\n    cdef unsigned int non_zero = X_indices.shape[0]\n    cdef unsigned int col_ind\n    cdef floating diff\n\n    # means[j] contains the mean of feature j\n    cdef np.ndarray[floating, ndim=1] means\n    # variances[j] contains the variance of feature j\n    cdef np.ndarray[floating, ndim=1] variances\n\n    if floating is float:\n        dtype = np.float32\n    else:\n        dtype = np.float64\n\n    means = np.zeros(n_features, dtype=dtype)\n    variances = np.zeros_like(means, dtype=dtype)\n\n    # counts[j] contains the number of samples where feature j is non-zero\n    cdef np.ndarray[int, ndim=1] counts = np.zeros(n_features,\n                                                   dtype=np.int32)\n\n    for i in xrange(non_zero):\n        col_ind = X_indices[i]\n        means[col_ind] += X_data[i]\n\n    means /= n_samples\n\n    for i in xrange(non_zero):\n        col_ind = X_indices[i]\n        diff = X_data[i] - means[col_ind]\n        variances[col_ind] += diff * diff\n        counts[col_ind] += 1\n\n    for i in xrange(n_features):\n        variances[i] += (n_samples - counts[i]) * means[i] ** 2\n        variances[i] /= n_samples\n\n    return means, variances\n\n\ndef csc_mean_variance_axis0(X):\n    \"\"\"Compute mean and variance along axis 0 on a CSC matrix\n\n    Parameters\n    ----------\n    X : CSC sparse matrix, shape (n_samples, n_features)\n        Input data.\n\n    Returns\n    -------\n\n    means : float array with shape (n_features,)\n        Feature-wise means\n\n    variances : float array with shape (n_features,)\n        Feature-wise variances\n\n    \"\"\"\n    if X.dtype != np.float32:\n        X = X.astype(np.float64)\n    return _csc_mean_variance_axis0(X.data, X.shape, X.indices, X.indptr)\n\n\ndef _csc_mean_variance_axis0(np.ndarray[floating, ndim=1] X_data,\n                             shape,\n                             np.ndarray[int, ndim=1] X_indices,\n                             np.ndarray[int, ndim=1] X_indptr):\n    # Implement the function here since variables using fused types\n    # cannot be declared directly and can only be passed as function arguments\n    cdef unsigned int n_samples = shape[0]\n    cdef unsigned int n_features = shape[1]\n\n    cdef unsigned int i\n    cdef unsigned int j\n    cdef unsigned int counts\n    cdef unsigned int startptr\n    cdef unsigned int endptr\n    cdef floating diff\n\n    # means[j] contains the mean of feature j\n    cdef np.ndarray[floating, ndim=1] means\n    # variances[j] contains the variance of feature j\n    cdef np.ndarray[floating, ndim=1] variances\n    if floating is float:\n        dtype = np.float32\n    else:\n        dtype = np.float64\n\n    means = np.zeros(n_features, dtype=dtype)\n    variances = np.zeros_like(means, dtype=dtype)\n\n    for i in xrange(n_features):\n\n        startptr = X_indptr[i]\n        endptr = X_indptr[i + 1]\n        counts = endptr - startptr\n\n        for j in xrange(startptr, endptr):\n            means[i] += X_data[j]\n        means[i] /= n_samples\n\n        for j in xrange(startptr, endptr):\n            diff = X_data[j] - means[i]\n            variances[i] += diff * diff\n\n        variances[i] += (n_samples - counts) * means[i] * means[i]\n        variances[i] /= n_samples\n\n    return means, variances\n\n\ndef incr_mean_variance_axis0(X, last_mean, last_var, unsigned long last_n):\n    \"\"\"Compute mean and variance along axis 0 on a CSR or CSC matrix.\n\n    last_mean, last_var are the statistics computed at the last step by this\n    function. Both must be initilized to 0.0. last_n is the\n    number of samples encountered until now and is initialized at 0.\n\n    Parameters\n    ----------\n    X : CSR or CSC sparse matrix, shape (n_samples, n_features)\n      Input data.\n\n    last_mean : float array with shape (n_features,)\n      Array of feature-wise means to update with the new data X.\n\n    last_var : float array with shape (n_features,)\n      Array of feature-wise var to update with the new data X.\n\n    last_n : int\n      Number of samples seen so far, before X.\n\n    Returns\n    -------\n\n    updated_mean : float array with shape (n_features,)\n      Feature-wise means\n\n    updated_variance : float array with shape (n_features,)\n      Feature-wise variances\n\n    updated_n : int\n      Updated number of samples seen\n\n    References\n    ----------\n\n    T. Chan, G. Golub, R. LeVeque. Algorithms for computing the sample\n      variance: recommendations, The American Statistician, Vol. 37, No. 3,\n      pp. 242-247\n\n    Also, see the non-sparse implementation of this in\n    `utils.extmath._batch_mean_variance_update`.\n\n    \"\"\"\n    if X.dtype != np.float32:\n        X = X.astype(np.float64)\n    return _incr_mean_variance_axis0(X.data, X.shape, X.indices, X.indptr,\n                                     X.format, last_mean, last_var, last_n)\n\n\ndef _incr_mean_variance_axis0(np.ndarray[floating, ndim=1] X_data,\n                              shape,\n                              np.ndarray[int, ndim=1] X_indices,\n                              np.ndarray[int, ndim=1] X_indptr,\n                              X_format,\n                              last_mean,\n                              last_var,\n                              unsigned long last_n):\n    # Implement the function here since variables using fused types\n    # cannot be declared directly and can only be passed as function arguments\n    cdef unsigned long n_samples = shape[0]\n    cdef unsigned int n_features = shape[1]\n    cdef unsigned int i\n\n    # last = stats until now\n    # new = the current increment\n    # updated = the aggregated stats\n    # when arrays, they are indexed by i per-feature\n    cdef np.ndarray[floating, ndim=1] new_mean\n    cdef np.ndarray[floating, ndim=1] new_var\n    cdef np.ndarray[floating, ndim=1] updated_mean\n    cdef np.ndarray[floating, ndim=1] updated_var\n    if floating is float:\n        dtype = np.float32\n    else:\n        dtype = np.float64\n\n    new_mean = np.zeros(n_features, dtype=dtype)\n    new_var = np.zeros_like(new_mean, dtype=dtype)\n    updated_mean = np.zeros_like(new_mean, dtype=dtype)\n    updated_var = np.zeros_like(new_mean, dtype=dtype)\n\n    cdef unsigned long new_n\n    cdef unsigned long updated_n\n    cdef floating last_over_new_n\n\n    # Obtain new stats first\n    new_n = n_samples\n\n    if X_format == 'csr':\n        # X is a CSR matrix\n        new_mean, new_var = _csr_mean_variance_axis0(X_data, shape, X_indices)\n    else:\n        # X is a CSC matrix\n        new_mean, new_var = _csc_mean_variance_axis0(X_data, shape, X_indices,\n                                                     X_indptr)\n\n    # First pass\n    if last_n == 0:\n        return new_mean, new_var, new_n\n    # Next passes\n    else:\n        updated_n = last_n + new_n\n        last_over_new_n = last_n / new_n\n\n    for i in xrange(n_features):\n        # Unnormalized old stats\n        last_mean[i] *= last_n\n        last_var[i] *= last_n\n\n        # Unnormalized new stats\n        new_mean[i] *= new_n\n        new_var[i] *= new_n\n\n        # Update stats\n        updated_var[i] = (last_var[i] + new_var[i] +\n                          last_over_new_n / updated_n *\n                          (last_mean[i] / last_over_new_n - new_mean[i]) ** 2)\n\n        updated_mean[i] = (last_mean[i] + new_mean[i]) / updated_n\n        updated_var[i] = updated_var[i] / updated_n\n\n    return updated_mean, updated_var, updated_n\n\n\ndef inplace_csr_row_normalize_l1(X):\n    \"\"\"Inplace row normalize using the l1 norm\"\"\"\n    _inplace_csr_row_normalize_l1(X.data, X.shape, X.indices, X.indptr)\n\n\ndef _inplace_csr_row_normalize_l1(np.ndarray[floating, ndim=1] X_data,\n                                  shape,\n                                  np.ndarray[int, ndim=1] X_indices,\n                                  np.ndarray[int, ndim=1] X_indptr):\n    cdef unsigned int n_samples = shape[0]\n    cdef unsigned int n_features = shape[1]\n\n    # the column indices for row i are stored in:\n    #    indices[indptr[i]:indices[i+1]]\n    # and their corresponding values are stored in:\n    #    data[indptr[i]:indptr[i+1]]\n    cdef unsigned int i\n    cdef unsigned int j\n    cdef double sum_\n\n    for i in xrange(n_samples):\n        sum_ = 0.0\n\n        for j in xrange(X_indptr[i], X_indptr[i + 1]):\n            sum_ += fabs(X_data[j])\n\n        if sum_ == 0.0:\n            # do not normalize empty rows (can happen if CSR is not pruned\n            # correctly)\n            continue\n\n        for j in xrange(X_indptr[i], X_indptr[i + 1]):\n            X_data[j] /= sum_\n\n\ndef inplace_csr_row_normalize_l2(X):\n    \"\"\"Inplace row normalize using the l2 norm\"\"\"\n    _inplace_csr_row_normalize_l2(X.data, X.shape, X.indices, X.indptr)\n\n\ndef _inplace_csr_row_normalize_l2(np.ndarray[floating, ndim=1] X_data,\n                                  shape,\n                                  np.ndarray[int, ndim=1] X_indices,\n                                  np.ndarray[int, ndim=1] X_indptr):\n    cdef unsigned int n_samples = shape[0]\n    cdef unsigned int n_features = shape[1]\n\n    cdef unsigned int i\n    cdef unsigned int j\n    cdef double sum_\n\n    for i in xrange(n_samples):\n        sum_ = 0.0\n\n        for j in xrange(X_indptr[i], X_indptr[i + 1]):\n            sum_ += (X_data[j] * X_data[j])\n\n        if sum_ == 0.0:\n            # do not normalize empty rows (can happen if CSR is not pruned\n            # correctly)\n            continue\n\n        sum_ = sqrt(sum_)\n\n        for j in xrange(X_indptr[i], X_indptr[i + 1]):\n            X_data[j] /= sum_\n\n\ndef assign_rows_csr(X,\n                    np.ndarray[np.npy_intp, ndim=1] X_rows,\n                    np.ndarray[np.npy_intp, ndim=1] out_rows,\n                    np.ndarray[floating, ndim=2, mode=\"c\"] out):\n    \"\"\"Densify selected rows of a CSR matrix into a preallocated array.\n\n    Like out[out_rows] = X[X_rows].toarray() but without copying.\n    No-copy supported for both dtype=np.float32 and dtype=np.float64.\n\n    Parameters\n    ----------\n    X : scipy.sparse.csr_matrix, shape=(n_samples, n_features)\n    X_rows : array, dtype=np.intp, shape=n_rows\n    out_rows : array, dtype=np.intp, shape=n_rows\n    out : array, shape=(arbitrary, n_features)\n    \"\"\"\n    cdef:\n        # npy_intp (np.intp in Python) is what np.where returns,\n        # but int is what scipy.sparse uses.\n        int i, ind, j\n        np.npy_intp rX\n        np.ndarray[floating, ndim=1] data = X.data\n        np.ndarray[int, ndim=1] indices = X.indices, indptr = X.indptr\n\n    if X_rows.shape[0] != out_rows.shape[0]:\n        raise ValueError(\"cannot assign %d rows to %d\"\n                         % (X_rows.shape[0], out_rows.shape[0]))\n\n    out[out_rows] = 0.\n    for i in range(X_rows.shape[0]):\n        rX = X_rows[i]\n        for ind in range(indptr[rX], indptr[rX + 1]):\n            j = indices[ind]\n            out[out_rows[i], j] = data[ind]"
  },
  {
    "path": "k_means_constrained/sklearn_import/utils/validation.py",
    "content": "import numbers\nimport warnings\n\nimport numpy as np\nfrom scipy import sparse as sp\nfrom k_means_constrained.sklearn_import.exceptions import NotFittedError\n\nfrom k_means_constrained.sklearn_import import get_config as _get_config\n\nfrom k_means_constrained.sklearn_import.exceptions import DataConversionWarning\nimport six\n\n\ndef check_array(array, accept_sparse=False, dtype=\"numeric\", order=None,\n                force_all_finite=True, ensure_2d=True,\n                allow_nd=False, ensure_min_samples=1, ensure_min_features=1,\n                warn_on_dtype=False, estimator=None):\n    \"\"\"Input validation on an array, list, sparse matrix or similar.\n\n    By default, the input is converted to an at least 2D numpy array.\n    If the dtype of the array is object, attempt converting to float,\n    raising on failure.\n\n    Parameters\n    ----------\n    array : object\n        Input object to check / convert.\n\n    accept_sparse : string, boolean or list/tuple of strings (default=False)\n        String[s] representing allowed sparse matrix formats, such as 'csc',\n        'csr', etc. If the input is sparse but not in the allowed format,\n        it will be converted to the first listed format. True allows the input\n        to be any format. False means that a sparse matrix input will\n        raise an error.\n\n        .. deprecated:: 0.19\n           Passing 'None' to parameter ``accept_sparse`` in methods is\n           deprecated in version 0.19 \"and will be removed in 0.21. Use\n           ``accept_sparse=False`` instead.\n\n    dtype : string, type, list of types or None (default=\"numeric\")\n        Data type of result. If None, the dtype of the input is preserved.\n        If \"numeric\", dtype is preserved unless array.dtype is object.\n        If dtype is a list of types, conversion on the first type is only\n        performed if the dtype of the input is not in the list.\n\n    order : 'F', 'C' or None (default=None)\n        Whether an array will be forced to be fortran or c-style.\n        When order is None (default), the memory layout of the\n        returned array is kept as close as possible\n        to the original array.\n\n    force_all_finite : boolean (default=True)\n        Whether to raise an error on np.inf and np.nan in X.\n\n    ensure_2d : boolean (default=True)\n        Whether to raise a value error if X is not 2d.\n\n    allow_nd : boolean (default=False)\n        Whether to allow X.ndim > 2.\n\n    ensure_min_samples : int (default=1)\n        Make sure that the array has a minimum number of samples in its first\n        axis (rows for a 2D array). Setting to 0 disables this check.\n\n    ensure_min_features : int (default=1)\n        Make sure that the 2D array has some minimum number of features\n        (columns). The default value of 1 rejects empty datasets.\n        This check is only enforced when the input data has effectively 2\n        dimensions or is originally 1D and ``ensure_2d`` is True. Setting to 0\n        disables this check.\n\n    warn_on_dtype : boolean (default=False)\n        Raise DataConversionWarning if the dtype of the input data structure\n        does not match the requested dtype, causing a memory copy.\n\n    estimator : str or estimator instance (default=None)\n        If passed, include the name of the estimator in warning messages.\n\n    Returns\n    -------\n    X_converted : object\n        The converted and validated X.\n\n    \"\"\"\n    # accept_sparse 'None' deprecation check\n    if accept_sparse is None:\n        warnings.warn(\n            \"Passing 'None' to parameter 'accept_sparse' in methods \"\n            \"check_array and check_X_y is deprecated in version 0.19 \"\n            \"and will be removed in 0.21. Use 'accept_sparse=False' \"\n            \" instead.\", DeprecationWarning)\n        accept_sparse = False\n\n    # store whether originally we wanted numeric dtype\n    dtype_numeric = isinstance(dtype, six.string_types) and dtype == \"numeric\"\n\n    dtype_orig = getattr(array, \"dtype\", None)\n    if not hasattr(dtype_orig, 'kind'):\n        # not a data type (e.g. a column named dtype in a pandas DataFrame)\n        dtype_orig = None\n\n    if dtype_numeric:\n        if dtype_orig is not None and dtype_orig.kind == \"O\":\n            # if input is object, convert to float.\n            dtype = np.float64\n        else:\n            dtype = None\n\n    if isinstance(dtype, (list, tuple)):\n        if dtype_orig is not None and dtype_orig in dtype:\n            # no dtype conversion required\n            dtype = None\n        else:\n            # dtype conversion required. Let's select the first element of the\n            # list of accepted types.\n            dtype = dtype[0]\n\n    if estimator is not None:\n        if isinstance(estimator, six.string_types):\n            estimator_name = estimator\n        else:\n            estimator_name = estimator.__class__.__name__\n    else:\n        estimator_name = \"Estimator\"\n    context = \" by %s\" % estimator_name if estimator is not None else \"\"\n\n    if sp.issparse(array):\n        array = _ensure_sparse_format(array, accept_sparse, dtype,\n                                      force_all_finite, copy=True)\n    else:\n        array = np.array(array, dtype=dtype, order=order, copy=True)\n\n        if ensure_2d:\n            if array.ndim == 1:\n                raise ValueError(\n                    \"Expected 2D array, got 1D array instead:\\narray={}.\\n\"\n                    \"Reshape your data either using array.reshape(-1, 1) if \"\n                    \"your data has a single feature or array.reshape(1, -1) \"\n                    \"if it contains a single sample.\".format(array))\n            array = np.atleast_2d(array)\n            # To ensure that array flags are maintained\n            array = np.array(array, dtype=dtype, order=order, copy=True)\n\n        # make sure we actually converted to numeric:\n        if dtype_numeric and array.dtype.kind == \"O\":\n            array = array.astype(np.float64)\n        if not allow_nd and array.ndim >= 3:\n            raise ValueError(\"Found array with dim %d. %s expected <= 2.\"\n                             % (array.ndim, estimator_name))\n        if force_all_finite:\n            _assert_all_finite(array)\n\n    shape_repr = _shape_repr(array.shape)\n    if ensure_min_samples > 0:\n        n_samples = _num_samples(array)\n        if n_samples < ensure_min_samples:\n            raise ValueError(\"Found array with %d sample(s) (shape=%s) while a\"\n                             \" minimum of %d is required%s.\"\n                             % (n_samples, shape_repr, ensure_min_samples,\n                                context))\n\n    if ensure_min_features > 0 and array.ndim == 2:\n        n_features = array.shape[1]\n        if n_features < ensure_min_features:\n            raise ValueError(\"Found array with %d feature(s) (shape=%s) while\"\n                             \" a minimum of %d is required%s.\"\n                             % (n_features, shape_repr, ensure_min_features,\n                                context))\n\n    if warn_on_dtype and dtype_orig is not None and array.dtype != dtype_orig:\n        msg = (\"Data with input dtype %s was converted to %s%s.\"\n               % (dtype_orig, array.dtype, context))\n        warnings.warn(msg, DataConversionWarning)\n    return array\n\n\ndef check_random_state(seed):\n    \"\"\"Turn seed into a np.random.RandomState instance\n\n    Parameters\n    ----------\n    seed : None | int | instance of RandomState\n        If seed is None, return the RandomState singleton used by np.random.\n        If seed is an int, return a new RandomState instance seeded with seed.\n        If seed is already a RandomState instance, return it.\n        Otherwise raise ValueError.\n    \"\"\"\n    if seed is None or seed is np.random:\n        return np.random.mtrand._rand\n    if isinstance(seed, (numbers.Integral, np.integer)):\n        return np.random.RandomState(seed)\n    if isinstance(seed, np.random.RandomState):\n        return seed\n    raise ValueError('%r cannot be used to seed a numpy.random.RandomState'\n                     ' instance' % seed)\n\n\ndef as_float_array(X, copy=True, force_all_finite=True):\n    \"\"\"Converts an array-like to an array of floats.\n\n    The new dtype will be np.float32 or np.float64, depending on the original\n    type. The function can create a copy or modify the argument depending\n    on the argument copy.\n\n    Parameters\n    ----------\n    X : {array-like, sparse matrix}\n\n    copy : bool, optional\n        If True, a copy of X will be created. If False, a copy may still be\n        returned if X's dtype is not a floating point type.\n\n    force_all_finite : boolean (default=True)\n        Whether to raise an error on np.inf and np.nan in X.\n\n    Returns\n    -------\n    XT : {array, sparse matrix}\n        An array of type np.float\n    \"\"\"\n    if isinstance(X, np.matrix) or (not isinstance(X, np.ndarray)\n                                    and not sp.issparse(X)):\n        return check_array(X, ['csr', 'csc', 'coo'], dtype=np.float64,\n                           copy=copy, force_all_finite=force_all_finite,\n                           ensure_2d=False)\n    elif sp.issparse(X) and X.dtype in [np.float32, np.float64]:\n        return X.copy() if copy else X\n    elif X.dtype in [np.float32, np.float64]:  # is numpy array\n        return X.copy('F' if X.flags['F_CONTIGUOUS'] else 'C') if copy else X\n    else:\n        if X.dtype.kind in 'uib' and X.dtype.itemsize <= 4:\n            return_dtype = np.float32\n        else:\n            return_dtype = np.float64\n        return X.astype(return_dtype)\n\n\ndef _assert_all_finite(X):\n    \"\"\"Like assert_all_finite, but only for ndarray.\"\"\"\n    if _get_config()['assume_finite']:\n        return\n    X = np.asanyarray(X)\n    # First try an O(n) time, O(1) space solution for the common case that\n    # everything is finite; fall back to O(n) space np.isfinite to prevent\n    # false positives from overflow in sum method.\n    if (X.dtype.char in np.typecodes['AllFloat'] and not np.isfinite(X.sum())\n            and not np.isfinite(X).all()):\n        raise ValueError(\"Input contains NaN, infinity\"\n                         \" or a value too large for %r.\" % X.dtype)\n\n\ndef _num_samples(x):\n    \"\"\"Return number of samples in array-like x.\"\"\"\n    if hasattr(x, 'fit') and callable(x.fit):\n        # Don't get num_samples from an ensembles length!\n        raise TypeError('Expected sequence or array-like, got '\n                        'estimator %s' % x)\n    if not hasattr(x, '__len__') and not hasattr(x, 'shape'):\n        if hasattr(x, '__array__'):\n            x = np.asarray(x)\n        else:\n            raise TypeError(\"Expected sequence or array-like, got %s\" %\n                            type(x))\n    if hasattr(x, 'shape'):\n        if len(x.shape) == 0:\n            raise TypeError(\"Singleton array %r cannot be considered\"\n                            \" a valid collection.\" % x)\n        return x.shape[0]\n    else:\n        return len(x)\n\n\ndef _shape_repr(shape):\n    \"\"\"Return a platform independent representation of an array shape\n\n    Under Python 2, the `long` type introduces an 'L' suffix when using the\n    default %r format for tuples of integers (typically used to store the shape\n    of an array).\n\n    Under Windows 64 bit (and Python 2), the `long` type is used by default\n    in numpy shapes even when the integer dimensions are well below 32 bit.\n    The platform specific type causes string messages or doctests to change\n    from one platform to another which is not desirable.\n\n    Under Python 3, there is no more `long` type so the `L` suffix is never\n    introduced in string representation.\n\n    >>> _shape_repr((1, 2))\n    '(1, 2)'\n    >>> one = 2 ** 64 / 2 ** 64  # force an upcast to `long` under Python 2\n    >>> _shape_repr((one, 2 * one))\n    '(1, 2)'\n    >>> _shape_repr((1,))\n    '(1,)'\n    >>> _shape_repr(())\n    '()'\n    \"\"\"\n    if len(shape) == 0:\n        return \"()\"\n    joined = \", \".join(\"%d\" % e for e in shape)\n    if len(shape) == 1:\n        # special notation for singleton tuples\n        joined += ','\n    return \"(%s)\" % joined\n\n\ndef _ensure_sparse_format(spmatrix, accept_sparse, dtype, copy,\n                          force_all_finite):\n    \"\"\"Convert a sparse matrix to a given format.\n\n    Checks the sparse format of spmatrix and converts if necessary.\n\n    Parameters\n    ----------\n    spmatrix : scipy sparse matrix\n        Input to validate and convert.\n\n    accept_sparse : string, boolean or list/tuple of strings\n        String[s] representing allowed sparse matrix formats ('csc',\n        'csr', 'coo', 'dok', 'bsr', 'lil', 'dia'). If the input is sparse but\n        not in the allowed format, it will be converted to the first listed\n        format. True allows the input to be any format. False means\n        that a sparse matrix input will raise an error.\n\n    dtype : string, type or None\n        Data type of result. If None, the dtype of the input is preserved.\n\n    copy : boolean\n        Whether a forced copy will be triggered. If copy=False, a copy might\n        be triggered by a conversion.\n\n    force_all_finite : boolean\n        Whether to raise an error on np.inf and np.nan in X.\n\n    Returns\n    -------\n    spmatrix_converted : scipy sparse matrix.\n        Matrix that is ensured to have an allowed type.\n    \"\"\"\n    if dtype is None:\n        dtype = spmatrix.dtype\n\n    changed_format = False\n\n    if isinstance(accept_sparse, six.string_types):\n        accept_sparse = [accept_sparse]\n\n    if accept_sparse is False:\n        raise TypeError('A sparse matrix was passed, but dense '\n                        'data is required. Use X.toarray() to '\n                        'convert to a dense numpy array.')\n    elif isinstance(accept_sparse, (list, tuple)):\n        if len(accept_sparse) == 0:\n            raise ValueError(\"When providing 'accept_sparse' \"\n                             \"as a tuple or list, it must contain at \"\n                             \"least one string value.\")\n        # ensure correct sparse format\n        if spmatrix.format not in accept_sparse:\n            # create new with correct sparse\n            spmatrix = spmatrix.asformat(accept_sparse[0])\n            changed_format = True\n    elif accept_sparse is not True:\n        # any other type\n        raise ValueError(\"Parameter 'accept_sparse' should be a string, \"\n                         \"boolean or list of strings. You provided \"\n                         \"'accept_sparse={}'.\".format(accept_sparse))\n\n    if dtype != spmatrix.dtype:\n        # convert dtype\n        spmatrix = spmatrix.astype(dtype)\n    elif copy and not changed_format:\n        # force copy\n        spmatrix = spmatrix.copy()\n\n    if force_all_finite:\n        if not hasattr(spmatrix, \"data\"):\n            warnings.warn(\"Can't check %s sparse matrix for nan or inf.\"\n                          % spmatrix.format)\n        else:\n            _assert_all_finite(spmatrix.data)\n    return spmatrix\n\n\nFLOAT_DTYPES = (np.float64, np.float32, np.float16)\n\n\ndef check_is_fitted(estimator, attributes, msg=None, all_or_any=all):\n    \"\"\"Perform is_fitted validation for estimator.\n\n    Checks if the estimator is fitted by verifying the presence of\n    \"all_or_any\" of the passed attributes and raises a NotFittedError with the\n    given message.\n\n    Parameters\n    ----------\n    estimator : estimator instance.\n        estimator instance for which the check is performed.\n\n    attributes : attribute name(s) given as string or a list/tuple of strings\n        Eg.:\n            ``[\"coef_\", \"estimator_\", ...], \"coef_\"``\n\n    msg : string\n        The default error message is, \"This %(name)s instance is not fitted\n        yet. Call 'fit' with appropriate arguments before using this method.\"\n\n        For custom messages if \"%(name)s\" is present in the message string,\n        it is substituted for the estimator name.\n\n        Eg. : \"Estimator, %(name)s, must be fitted before sparsifying\".\n\n    all_or_any : callable, {all, any}, default all\n        Specify whether all or any of the given attributes must exist.\n\n    Returns\n    -------\n    None\n\n    Raises\n    ------\n    NotFittedError\n        If the attributes are not found.\n    \"\"\"\n    if msg is None:\n        msg = (\"This %(name)s instance is not fitted yet. Call 'fit' with \"\n               \"appropriate arguments before using this method.\")\n\n    if not hasattr(estimator, 'fit'):\n        raise TypeError(\"%s is not an estimator instance.\" % (estimator))\n\n    if not isinstance(attributes, (list, tuple)):\n        attributes = [attributes]\n\n    if not all_or_any([hasattr(estimator, attr) for attr in attributes]):\n        raise NotFittedError(msg % {'name': type(estimator).__name__})"
  },
  {
    "path": "pyproject.toml",
    "content": "[build-system]\nrequires = [\"setuptools\", \"wheel\", \"cython>=3.0.11\", \"numpy>=2.0,<3\"]\n"
  },
  {
    "path": "requirements-dev.txt",
    "content": "-r requirements.txt\npytest>=5.1\npandas>=2.2.3\ntwine\nsphinx\nsphinx-rtd-theme\nnumpydoc\nbump2version\nnose\nscikit-learn>=1.5.2\ncython>=3.0.11\n"
  },
  {
    "path": "requirements.txt",
    "content": "ortools >= 9.15.6755\nscipy >= 1.14.1\nnumpy >= 2.1.1\nsix\njoblib\n"
  },
  {
    "path": "setup.cfg",
    "content": "[metadata]\nname = k-means-constrained\nversion = 0.9.0\ndescription = K-Means clustering constrained with minimum and maximum cluster size\nlong_description = file: README.md\nlong_description_content_type = text/markdown\nlicense = BSD 3-Clause\nauthor = Josh Levy-Kramer\nurl = https://github.com/joshlk/k-means-constrained\ndownload_urls = https://pypi.org/project/k-means-constrained/\nproject_urls =\n\tDocumentation = https://joshlk.github.io/k-means-constrained/\n\tCode = https://github.com/joshlk/k-means-constrained\n\tIssue tracker = https://github.com/joshlk/k-means-constrained/issues\nclassifiers =\n    Development Status :: 5 - Production/Stable\n    Intended Audience :: Developers\n    Topic :: Scientific/Engineering\n    License :: OSI Approved :: BSD License\n    Programming Language :: Python :: 3\n[options]\nzip_safe = False\n; Currently includes the venv `k-means-env` directory. Can't work out how to exclude it\n; Dont try. Its a HUGE RABAT HOLE\npackages = find:\n\n"
  },
  {
    "path": "setup.py",
    "content": "#!/usr/bin/env python3\n\n\"\"\"\nBased on template: https://github.com/FedericoStra/cython-package-example\n\"\"\"\n\nfrom setuptools import dist, find_packages\n\nimport os\nfrom setuptools import setup, Extension\n\ntry:\n    from numpy import get_include\nexcept:\n    def get_include():\n        # Defer import to later\n        from numpy import get_include\n        return get_include()\n\ntry:\n    from Cython.Build import cythonize\nexcept ImportError:\n    print(\"! Could not import Cython !\")\n    cythonize = None\n\n\n# https://cython.readthedocs.io/en/latest/src/userguide/source_files_and_compilation.html#distributing-cython-modules\ndef no_cythonize(extensions, **_ignore):\n    for extension in extensions:\n        sources = []\n        for sfile in extension.sources:\n            path, ext = os.path.splitext(sfile)\n            if ext in (\".pyx\", \".py\"):\n                if extension.language == \"c++\":\n                    ext = \".cpp\"\n                else:\n                    ext = \".c\"\n                sfile = path + ext\n            sources.append(sfile)\n        extension.sources[:] = sources\n    return extensions\n\nextensions = [\n    Extension(\"k_means_constrained.sklearn_import.cluster._k_means\", [\"k_means_constrained/sklearn_import/cluster/_k_means.pyx\"],\n              include_dirs=[get_include()]),\n    Extension(\"k_means_constrained.sklearn_import.metrics.pairwise_fast\", [\"k_means_constrained/sklearn_import/metrics/pairwise_fast.pyx\"],\n                  include_dirs=[get_include()]),\n    Extension(\"k_means_constrained.sklearn_import.utils.sparsefuncs_fast\", [\"k_means_constrained/sklearn_import/utils/sparsefuncs_fast.pyx\"],\n                      include_dirs=[get_include()]),\n]\n\nCYTHONIZE = bool(int(os.getenv(\"CYTHONIZE\", 1))) and cythonize is not None\n\nif CYTHONIZE:\n    compiler_directives = {\"language_level\": 3, \"embedsignature\": True}\n    extensions = cythonize(extensions, compiler_directives=compiler_directives)\nelse:\n    extensions = no_cythonize(extensions)\n\nwith open(\"requirements.txt\") as fp:\n    install_requires = fp.read().strip().split(\"\\n\")\n\nsetup(\n    ext_modules=extensions,\n    install_requires=install_requires,\n)\n"
  },
  {
    "path": "tests/test_k_means_constrained_.py",
    "content": "#!/usr/bin/env python\n\nimport numpy as np\nimport pandas as pd\nimport pytest\nfrom scipy.sparse import csc_matrix, issparse\n\nfrom k_means_constrained.sklearn_import.metrics.pairwise import euclidean_distances\n\nfrom k_means_constrained.k_means_constrained_ import minimum_cost_flow_problem_graph, solve_min_cost_flow_graph, \\\n    KMeansConstrained, _labels_constrained\n\ndef sort_coordinates(array):\n    array = array[np.lexsort(np.fliplr(array).T)]\n    return array\n\n\ndef test_minimum_cost_flow_problem_graph():\n    # Setup graph\n    X = np.array([\n        [0, 0],\n        [1, 2],\n        [1, 4],\n        [1, 0],\n        [4, 2],\n        [4, 4],\n        [4, 0],\n        [4, 4]\n    ])\n    C = np.array([\n        [0, 0],\n        [4, 4]\n    ])\n    size_min, size_max = 3, 10\n\n    D = euclidean_distances(X, C, squared=True)\n\n    edges, costs, capacities, supplies, n_C, n_X = minimum_cost_flow_problem_graph(X, C, D, size_min, size_max)\n\n    assert edges.shape[0] == len(costs)\n    assert edges.shape[0] == len(capacities)\n    assert len(np.unique(edges)) == len(supplies)\n    assert costs.sum() > 0\n    assert supplies.sum() == 0\n\n\ndef test_solve_min_cost_flow_graph():\n    # Setup graph\n    X = np.array([\n        [0, 0],\n        [1, 2],\n        [1, 4],\n        [1, 0],\n        [4, 2],\n        [4, 4],\n        [4, 0],\n        [4, 4]\n    ])\n    C = np.array([\n        [0, 0],\n        [4, 4]\n    ])\n    size_min, size_max = 3, 10\n\n    D = euclidean_distances(X, C, squared=True)\n\n    edges, costs, capacities, supplies, n_C, n_X = minimum_cost_flow_problem_graph(X, C, D, size_min, size_max)\n    labels = solve_min_cost_flow_graph(edges, costs, capacities, supplies, n_C, n_X)\n\n    cluster_size = pd.Series(labels).value_counts()\n\n    assert (cluster_size > size_max).sum() == 0\n    assert (cluster_size < size_min).sum() == 0\n\n\ndef test__labels_constrained():\n    # Setup graph\n    X = np.array([\n        [0, 0],\n        [1, 2],\n        [1, 4],\n        [1, 0],\n        [4, 2],\n        [4, 4],\n        [4, 0],\n        [4, 4]\n    ])\n    centers = np.array([\n        [0, 0],\n        [4, 4]\n    ])\n    size_min, size_max = 3, 10\n\n    distances = np.zeros(shape=(X.shape[0],), dtype=X.dtype)\n\n    labels, inertia = _labels_constrained(X, centers, size_min, size_max, distances)\n\n    # Labels\n    cluster_size = pd.Series(labels).value_counts()\n    assert (cluster_size > size_max).sum() == 0\n    assert (cluster_size < size_min).sum() == 0\n\n    # Distances\n    assert distances.sum() > 0\n\n    # Inertia\n    assert inertia > 0\n\ndef test_KMeansConstrained():\n    X = np.array([\n        [0, 0],\n        [1, 2],\n        [1, 4],\n        [1, 0],\n        [4, 2],\n        [4, 4],\n        [4, 0],\n        [3, 0],\n        [4, 4]\n    ])\n\n    k = 3\n    size_min, size_max = 3, 7\n\n    clf = KMeansConstrained(\n        n_clusters=k,\n        size_min=size_min,\n        size_max=size_max\n    )\n\n    y = clf.fit_predict(X)\n\n    # Labels\n    cluster_size = pd.Series(y).value_counts()\n    assert (cluster_size > size_max).sum() == 0\n    assert (cluster_size < size_min).sum() == 0\n\n\ndef test_KMeansConstrained_predict_method():\n    X = np.array([\n        [0, 0],\n        [0, 0],\n        [0, 0],\n        [1, 1],\n    ])\n\n    k = 2\n    size_max = 2\n\n    clf = KMeansConstrained(\n        n_clusters=k,\n        size_max=size_max\n    )\n\n    clf.fit(X)\n\n    y_constrained = clf.predict(X)  # Expected np.array([0, 0, 1, 1])\n    y_normal = super(KMeansConstrained, clf).predict(X)  # Expected np.array([0, 0, 0, 1])\n\n    cluster_size_constrained = pd.Series(y_constrained).value_counts()\n    assert (cluster_size_constrained > size_max).any() == False\n    assert len(cluster_size_constrained) == k\n\n    cluster_size_normal = pd.Series(y_normal).value_counts()\n    assert (cluster_size_normal > size_max).any() == True\n    assert len(cluster_size_normal) == k\n\n\ndef test_spare_not_implemented():\n    X = np.array([\n        [0, 0],\n        [1, 2],\n        [1, 4],\n        [1, 0],\n        [4, 2],\n        [4, 4],\n        [4, 0],\n        [3, 0],\n        [4, 4]\n    ])\n\n    k = 3\n    size_min, size_max = 3, 7\n\n    clf = KMeansConstrained(\n        n_clusters=k,\n        size_min=size_min,\n        size_max=size_max\n    )\n\n    X = csc_matrix(X)\n\n    with pytest.raises(NotImplementedError):\n        clf.fit(X)\n\n    with pytest.raises(NotImplementedError):\n        clf.fit_predict(X)\n\n#######\n# Parity tests only works with sklearn v0.19.2 but does not run on Python 3.8+\n#######\n\n# from sklearn.cluster import KMeans\n# from sklearn.cluster.k_means_ import _labels_inertia\n# from numpy.testing import assert_array_equal, assert_almost_equal\n# from k_means_constrained.sklearn_import.utils.extmath import row_norms\n\n# Test passes on Python 3.7\n# def test__labels_constrained_kmeans_parity():\n#     X = np.array([\n#         [0, 0],\n#         [1, 2],\n#         [1, 4],\n#         [1, 0],\n#         [4, 2],\n#         [4, 4],\n#         [4, 0],\n#         [4, 4]\n#     ]).astype('float')\n#     centers = np.array([\n#         [0, 0],\n#         [4, 4]\n#     ]).astype('float')\n#     size_min, size_max = 0, len(X)  # No restrictions and so should be the same as K-means\n#\n#     x_squared_norms = row_norms(X, squared=True)\n#\n#     distances_constrained = np.zeros(shape=(X.shape[0],), dtype=X.dtype)\n#     labels_constrained, inertia_constrained = _labels_constrained(X, centers, size_min, size_max, distances_constrained)\n#\n#     distances_kmeans = np.zeros(shape=(X.shape[0],), dtype=X.dtype)\n#     labels_kmeans, inertia_kmeans = \\\n#         _labels_inertia(X=X, x_squared_norms=x_squared_norms, centers=centers, precompute_distances=False,\n#                         distances=distances_kmeans)\n#\n#     assert_array_equal(labels_constrained, labels_kmeans)\n#     assert_almost_equal(distances_constrained, distances_kmeans)\n#     assert inertia_constrained == inertia_kmeans\n\n# Test passes on Python 3.7\n# def test_KMeansConstrained_parity_digits():\n#     iris = datasets.load_iris()\n#     X = iris.data\n#\n#     k = 8\n#     random_state = 1\n#     size_min, size_max = None, None  # No restrictions and so should produce same result\n#\n#     clf_constrained = KMeansConstrained(\n#         size_min=size_min,\n#         size_max=size_max,\n#         n_clusters=k,\n#         random_state=random_state,\n#         init='k-means++',\n#         n_init=10,\n#         max_iter=300,\n#         tol=1e-4\n#     )\n#     y_constrained = clf_constrained.fit_predict(X)\n#\n#     # TODO: Testing scikit-learn has be set to v0.19. This is because there is a discrepancy scikit-learn v0.22 https://github.com/scikit-learn/scikit-learn/issues/16623\n#     clf_kmeans = KMeans(\n#         n_clusters=k,\n#         random_state=random_state,\n#         init='k-means++',\n#         n_init=10,\n#         max_iter=300,\n#         tol=1e-4\n#     )\n#     y_kmeans = clf_kmeans.fit_predict(X)\n#\n#     # Each cluster should have the same number of datapoints assigned to it\n#     constrained_ndp = pd.Series(y_constrained).value_counts().values\n#     kmeans_ndp = pd.Series(y_kmeans).value_counts().values\n#\n#     assert_almost_equal(constrained_ndp, kmeans_ndp)\n#\n#     # Sort the cluster coordinates (otherwise in a random order)\n#     constrained_cluster_centers = sort_coordinates(clf_constrained.cluster_centers_)\n#     kmean_cluster_centers = sort_coordinates(clf_kmeans.cluster_centers_)\n#\n#     assert_almost_equal(constrained_cluster_centers, kmean_cluster_centers)\n\n\n####\n# Further tests removed as removed sklearn dependency\n####\n\n# from sklearn import datasets\n#\n# def test_KMeansConstrained_n_jobs():\n#     X, _ = datasets.make_blobs(n_samples=100, n_features=5, centers=10, random_state=1)\n#\n#     n_jobs = -1\n#     k = 20\n#     size_min, size_max = 3, 40\n#\n#     clf = KMeansConstrained(\n#         n_clusters=k,\n#         size_min=size_min,\n#         size_max=size_max,\n#         n_jobs=n_jobs\n#     )\n#\n#     y = clf.fit_predict(X)\n#\n#     # Labels\n#     cluster_size = pd.Series(y).value_counts()\n#     assert (cluster_size > size_max).sum() == 0\n#     assert (cluster_size < size_min).sum() == 0"
  },
  {
    "path": "tests/test_kmeans_constrained_from_sklearn.py",
    "content": "# Tests copied and modified from: https://github.com/scikit-learn/scikit-learn/blob/0.19.X/sklearn/cluster/tests/test_k_means.py\n\nimport sys\nimport numpy as np\nfrom numpy.testing import assert_equal, assert_warns, assert_array_almost_equal, assert_array_equal, assert_raises,\\\n    assert_raises_regex\nfrom k_means_constrained.k_means_constrained_ import k_means_constrained, _labels_constrained\nfrom k_means_constrained import KMeansConstrained\nfrom sklearn.datasets import make_blobs\nfrom sklearn.metrics.cluster import v_measure_score\nfrom unittest import SkipTest\nimport pytest\n\n# non centered, sparse centers to check the\ncenters = np.array([\n    [0.0, 5.0, 0.0, 0.0, 0.0],\n    [1.0, 1.0, 4.0, 0.0, 0.0],\n    [1.0, 0.0, 0.0, 5.0, 1.0],\n])\nn_samples = 100\nn_clusters, n_features = centers.shape\nX, true_labels = make_blobs(n_samples=n_samples, centers=centers,\n                            cluster_std=1., random_state=42)\n\ndef test_labels_assignment_and_inertia():\n    # pure numpy implementation as easily auditable reference gold\n    # implementation\n    rng = np.random.RandomState(42)\n    noisy_centers = centers + rng.normal(size=centers.shape)\n    labels_gold = - np.ones(n_samples, dtype=int)\n    mindist = np.empty(n_samples)\n    mindist.fill(np.inf)\n    for center_id in range(n_clusters):\n        dist = np.sum((X - noisy_centers[center_id]) ** 2, axis=1)\n        labels_gold[dist < mindist] = center_id\n        mindist = np.minimum(dist, mindist)\n    inertia_gold = mindist.sum()\n    assert (mindist >= 0.0).all()\n    assert (labels_gold != -1).all()\n\n    # perform label assignment using the dense array input\n    distances = np.zeros(shape=(len(X),), dtype=X.dtype)\n    labels_array, inertia_array = _labels_constrained(\n        X, noisy_centers, size_min=0, size_max=len(X), distances=distances)\n    assert_array_almost_equal(inertia_array, inertia_gold)\n    assert_array_equal(labels_array, labels_gold)\n\ndef _check_fitted_model(km):\n    # check that the number of clusters centers and distinct labels match\n    # the expectation\n    centers = km.cluster_centers_\n    assert_equal(centers.shape, (n_clusters, n_features))\n\n    labels = km.labels_\n    assert_equal(np.unique(labels).shape[0], n_clusters)\n\n    # check that the labels assignment are perfect (up to a permutation)\n    assert_equal(v_measure_score(true_labels, labels), 1.0)\n    assert km.inertia_ > 0.0\n\n    # check error on dataset being too small\n    assert_raises(ValueError, km.fit, [[0., 1.]])\n\n\ndef test_k_means_plus_plus_init():\n    km = KMeansConstrained(init=\"k-means++\", n_clusters=n_clusters,\n                random_state=42).fit(X)\n    _check_fitted_model(km)\n\n\ndef test_k_means_new_centers():\n    # Explore the part of the code where a new center is reassigned\n    X = np.array([[0, 0, 1, 1],\n                  [0, 0, 0, 0],\n                  [0, 1, 0, 0],\n                  [0, 0, 0, 0],\n                  [0, 0, 0, 0],\n                  [0, 1, 0, 0]])\n    labels = [0, 1, 2, 1, 1, 2]\n    bad_centers = np.array([[+0, 1, 0, 0],\n                            [.2, 0, .2, .2],\n                            [+0, 0, 0, 0]])\n\n    km = KMeansConstrained(n_clusters=3, init=bad_centers, n_init=1, max_iter=10,\n                random_state=1)\n\n    for i in range(2):\n        km.fit(X)\n        this_labels = km.labels_\n        # Reorder the labels so that the first instance is in cluster 0,\n        # the second in cluster 1, ...\n        this_labels = np.unique(this_labels, return_index=True)[1][this_labels]\n        np.testing.assert_array_equal(this_labels, labels)\n\n\ndef test_k_means_plus_plus_init_2_jobs():\n    if sys.version_info[:2] < (3, 4):\n        raise SkipTest(\n            \"Possible multi-process bug with some BLAS under Python < 3.4\")\n\n    km = KMeansConstrained(init=\"k-means++\", n_clusters=n_clusters, n_jobs=2,\n                random_state=42).fit(X)\n    _check_fitted_model(km)\n\n\ndef test_k_means_random_init():\n    km = KMeansConstrained(init=\"random\", n_clusters=n_clusters, random_state=42)\n    km.fit(X)\n    _check_fitted_model(km)\n\n\ndef test_k_means_perfect_init():\n    km = KMeansConstrained(init=centers.copy(), n_clusters=n_clusters, random_state=42,\n                n_init=1)\n    km.fit(X)\n    _check_fitted_model(km)\n\n\ndef test_k_means_n_init():\n    rnd = np.random.RandomState(0)\n    X = rnd.normal(size=(40, 2))\n\n    # two regression tests on bad n_init argument\n    # previous bug: n_init <= 0 threw non-informative TypeError (#3858)\n    assert_raises_regex(ValueError, \"n_init\", KMeansConstrained(n_init=0).fit, X)\n    assert_raises_regex(ValueError, \"n_init\", KMeansConstrained(n_init=-1).fit, X)\n\n\ndef test_k_means_explicit_init_shape():\n    # test for sensible errors when giving explicit init\n    # with wrong number of features or clusters\n    rnd = np.random.RandomState(0)\n    X = rnd.normal(size=(40, 3))\n\n    # mismatch of number of features\n    km = KMeansConstrained(n_init=1, init=X[:, :2], n_clusters=len(X))\n    msg = \"does not match the number of features of the data\"\n    assert_raises_regex(ValueError, msg, km.fit, X)\n    # for callable init\n    km = KMeansConstrained(n_init=1,\n               init=lambda X_, k, random_state: X_[:, :2],\n               n_clusters=len(X))\n    assert_raises_regex(ValueError, msg, km.fit, X)\n    # mismatch of number of clusters\n    msg = \"does not match the number of clusters\"\n    km = KMeansConstrained(n_init=1, init=X[:2, :], n_clusters=3)\n    assert_raises_regex(ValueError, msg, km.fit, X)\n    # for callable init\n    km = KMeansConstrained(n_init=1,\n               init=lambda X_, k, random_state: X_[:2, :],\n               n_clusters=3)\n    assert_raises_regex(ValueError, msg, km.fit, X)\n\n\ndef test_k_means_fortran_aligned_data():\n    # Check the KMeans will work well, even if X is a fortran-aligned data.\n    X = np.asfortranarray([[0, 0], [0, 1], [0, 1]])\n    centers = np.array([[0, 0], [0, 1]])\n    labels = np.array([0, 1, 1])\n    km = KMeansConstrained(n_init=1, init=centers,\n                random_state=42, n_clusters=2)\n    km.fit(X)\n    assert_array_equal(km.cluster_centers_, centers)\n    assert_array_equal(km.labels_, labels)\n\n\ndef test_k_means_invalid_init():\n    km = KMeansConstrained(init=\"invalid\", n_init=1, n_clusters=n_clusters)\n    assert_raises(ValueError, km.fit, X)\n\n\ndef test_k_means_copyx():\n    # Check if copy_x=False returns nearly equal X after de-centering.\n    my_X = X.copy()\n    km = KMeansConstrained(copy_x=False, n_clusters=n_clusters, random_state=42)\n    km.fit(my_X)\n    _check_fitted_model(km)\n\n    # check if my_X is centered\n    assert_array_almost_equal(my_X, X)\n\n\ndef test_k_means_non_collapsed():\n    # Check k_means with a bad initialization does not yield a singleton\n    # Starting with bad centers that are quickly ignored should not\n    # result in a repositioning of the centers to the center of mass that\n    # would lead to collapsed centers which in turns make the clustering\n    # dependent of the numerical unstabilities.\n    my_X = np.array([[1.1, 1.1], [0.9, 1.1], [1.1, 0.9], [0.9, 1.1]])\n    array_init = np.array([[1.0, 1.0], [5.0, 5.0], [-5.0, -5.0]])\n    km = KMeansConstrained(init=array_init, n_clusters=3, random_state=42, n_init=1)\n    km.fit(my_X)\n\n    # centers must not been collapsed\n    assert_equal(len(np.unique(km.labels_)), 3)\n\n    centers = km.cluster_centers_\n    assert (np.linalg.norm(centers[0] - centers[1]) >= 0.1).all()\n    assert (np.linalg.norm(centers[0] - centers[2]) >= 0.1).all()\n    assert (np.linalg.norm(centers[1] - centers[2]) >= 0.1).all()\n\n\ndef test_predict():\n    km = KMeansConstrained(n_clusters=n_clusters, random_state=42)\n\n    km.fit(X)\n\n    # sanity check: predict centroid labels\n    pred = km.predict(km.cluster_centers_)\n    assert_array_equal(pred, np.arange(n_clusters))\n\n    # sanity check: re-predict labeling for training set samples\n    pred = km.predict(X)\n    assert_array_equal(pred, km.labels_)\n\n    # re-predict labels for training set using fit_predict\n    pred = km.fit_predict(X)\n    assert_array_equal(pred, km.labels_)\n\n\ndef test_score():\n\n    km1 = KMeansConstrained(n_clusters=n_clusters, max_iter=1, random_state=42, n_init=1)\n    s1 = km1.fit(X).score(X)\n    km2 = KMeansConstrained(n_clusters=n_clusters, max_iter=10, random_state=42, n_init=1)\n    s2 = km2.fit(X).score(X)\n    assert s2 > s1\n\n\ndef test_transform():\n    km = KMeansConstrained(n_clusters=n_clusters)\n    km.fit(X)\n    X_new = km.transform(km.cluster_centers_)\n\n    for c in range(n_clusters):\n        assert_array_almost_equal(X_new[c, c], 0)\n        for c2 in range(n_clusters):\n            if c != c2:\n                assert X_new[c, c2] > 0\n\n\ndef test_fit_transform():\n    X1 = KMeansConstrained(n_clusters=3, random_state=51).fit(X).transform(X)\n    X2 = KMeansConstrained(n_clusters=3, random_state=51).fit_transform(X)\n    assert_array_equal(X1, X2)\n\n\ndef test_n_init():\n    # Check that increasing the number of init increases the quality\n    n_runs = 5\n    n_init_range = [1, 5, 10]\n    inertia = np.zeros((len(n_init_range), n_runs))\n    for i, n_init in enumerate(n_init_range):\n        for j in range(n_runs):\n            km = KMeansConstrained(n_clusters=n_clusters, init=\"random\", n_init=n_init,\n                        random_state=j).fit(X)\n            inertia[i, j] = km.inertia_\n\n    inertia = inertia.mean(axis=1)\n    failure_msg = (\"Inertia %r should be decreasing\"\n                   \" when n_init is increasing.\") % list(inertia)\n    for i in range(len(n_init_range) - 1):\n        assert (inertia[i] >= inertia[i + 1]).all(), failure_msg\n\n\ndef test_k_means_function():\n    # test calling the k_means function directly\n    # catch output\n    old_stdout = sys.stdout\n    #sys.stdout = StringIO()\n    try:\n        cluster_centers, labels, inertia = k_means_constrained(X, n_clusters=n_clusters,\n                                                   verbose=True)\n    finally:\n        sys.stdout = old_stdout\n    centers = cluster_centers\n    assert_equal(centers.shape, (n_clusters, n_features))\n\n    labels = labels\n    assert_equal(np.unique(labels).shape[0], n_clusters)\n\n    # check that the labels assignment are perfect (up to a permutation)\n    assert_equal(v_measure_score(true_labels, labels), 1.0)\n    assert inertia > 0.0\n\n    # check warning when centers are passed\n    assert_warns(RuntimeWarning, k_means_constrained, X, n_clusters=n_clusters,\n                 init=centers)\n\n    # to many clusters desired\n    assert_raises(ValueError, k_means_constrained, X, n_clusters=X.shape[0] + 1)\n\n\n\ndef test_max_iter_error():\n\n    km = KMeansConstrained(max_iter=-1)\n    with pytest.raises(ValueError, match='Number of iterations should be'):\n        km.fit(X)\n\n\ndef test_float_precision():\n    km = KMeansConstrained(n_init=1, random_state=30)\n\n    inertia = {}\n    X_new = {}\n    centers = {}\n\n    for dtype in [np.float64, np.float32]:\n        X_test = X.astype(dtype)\n        km.fit(X_test)\n        # dtype of cluster centers has to be the dtype of the input\n        # data\n        assert_equal(km.cluster_centers_.dtype, dtype)\n        inertia[dtype] = km.inertia_\n        X_new[dtype] = km.transform(X_test)\n        centers[dtype] = km.cluster_centers_\n        # ensure the extracted row is a 2d array\n        assert_equal(km.predict(X_test[:1]),\n                     km.labels_[0])\n        if hasattr(km, 'partial_fit'):\n            km.partial_fit(X_test[0:3])\n            # dtype of cluster centers has to stay the same after\n            # partial_fit\n            assert_equal(km.cluster_centers_.dtype, dtype)\n\n    # compare arrays with low precision since the difference between\n    # 32 and 64 bit sometimes makes a difference up to the 4th decimal\n    # place\n    assert_array_almost_equal(inertia[np.float32], inertia[np.float64],\n                              decimal=4)\n    assert_array_almost_equal(X_new[np.float32], X_new[np.float64],\n                              decimal=4)\n    assert_array_almost_equal(centers[np.float32], centers[np.float64],\n                              decimal=4)\n\n\ndef test_k_means_init_centers():\n    # This test is used to check KMeans won't mutate the user provided input\n    # array silently even if input data and init centers have the same type\n    X_small = np.array([[1.1, 1.1], [-7.5, -7.5], [-1.1, -1.1], [7.5, 7.5]])\n    init_centers = np.array([[0.0, 0.0], [5.0, 5.0], [-5.0, -5.0]])\n    for dtype in [np.int32, np.int64, np.float32, np.float64]:\n        X_test = dtype(X_small)\n        init_centers_test = dtype(init_centers)\n        assert_array_equal(init_centers, init_centers_test)\n        km = KMeansConstrained(init=init_centers_test, n_clusters=3, n_init=1)\n        km.fit(X_test)\n        assert_equal(False, np.may_share_memory(km.cluster_centers_, init_centers))\n\n\ndef test_sparse_k_means_init_centers():\n    from sklearn.datasets import load_iris\n\n    iris = load_iris()\n    X = iris.data\n\n    # Get a local optimum\n    centers = KMeansConstrained(n_clusters=3, size_min=50).fit(X).cluster_centers_\n\n    # Fit starting from a local optimum shouldn't change the solution\n    np.testing.assert_allclose(\n        centers,\n        KMeansConstrained(n_clusters=3, size_min=50,\n               init=centers,\n               n_init=1).fit(X).cluster_centers_\n    )\n\n\ndef test_sparse_validate_centers():\n    from sklearn.datasets import load_iris\n\n    iris = load_iris()\n    X = iris.data\n\n    # Get a local optimum\n    centers = KMeansConstrained(n_clusters=4).fit(X).cluster_centers_\n\n    # Test that a ValueError is raised for validate_center_shape\n    classifier = KMeansConstrained(n_clusters=3, init=centers, n_init=1)\n\n    assert_raises(ValueError, classifier.fit, X)\n"
  },
  {
    "path": "tox.ini",
    "content": "# Needed for setup.py to work correctly (no idea why)\n[tox]\nenvlist = py{38,39}\n\n[testenv]\nbasepython =\n    py38: python3.8\n    py39: python3.9\ndeps =\n    check-manifest\n    readme_renderer\n    flake8\n    pytest\ncommands =\n    check-manifest --ignore tox.ini,tests*\n    python setup.py check -m -r -s\n    flake8 .\n    py.test tests\n[flake8]\nexclude = .tox,*.egg,build,data\nselect = E,W,F\n"
  }
]