pax_global_header00006660000000000000000000000064145046152220014513gustar00rootroot0000000000000052 comment=91d3f8387de69dc190ad244120226b86e55dd3f9 sphinxcontrib-django-2.5/000077500000000000000000000000001450461522200155135ustar00rootroot00000000000000sphinxcontrib-django-2.5/.github/000077500000000000000000000000001450461522200170535ustar00rootroot00000000000000sphinxcontrib-django-2.5/.github/CODEOWNERS000066400000000000000000000004061450461522200204460ustar00rootroot00000000000000# Each line is a file pattern followed by one or more owners. # These owners will be the default owners for everything in the repo. # Unless a later match takes precedence, they will be requested for review when someone opens a pull request. * @timobrembeck sphinxcontrib-django-2.5/.github/ISSUE_TEMPLATE/000077500000000000000000000000001450461522200212365ustar00rootroot00000000000000sphinxcontrib-django-2.5/.github/ISSUE_TEMPLATE/bug-report.md000066400000000000000000000016131450461522200236470ustar00rootroot00000000000000--- name: "Bug report \U0001F41B" about: "Create a report to help us improve" labels: "bug" --- ### Describe the Bug ### Minimal Example to Reproduce ### Expected Behavior ### Actual Behavior ### Additional Information
Traceback ``` ```
### System Information OS version: Python version: Sphinx version: sphinxcontrib_django version: sphinxcontrib-django-2.5/.github/ISSUE_TEMPLATE/feature-request.md000066400000000000000000000014131450461522200247000ustar00rootroot00000000000000--- name: "Feature request \U0001F4A1" about: "Suggest an idea for this project" labels: "feature request" --- ### Motivation ### Proposed Solution ### Alternatives ### Additional Context sphinxcontrib-django-2.5/.github/PULL_REQUEST_TEMPLATE.md000066400000000000000000000003711450461522200226550ustar00rootroot00000000000000### Short description ### Proposed changes - - ### Resolved issues Fixes: # sphinxcontrib-django-2.5/.github/workflows/000077500000000000000000000000001450461522200211105ustar00rootroot00000000000000sphinxcontrib-django-2.5/.github/workflows/deployment.yml000066400000000000000000000023421450461522200240140ustar00rootroot00000000000000name: Deployment on: [push, pull_request] jobs: has: name: Check Secrets runs-on: ubuntu-latest steps: - id: secrets env: test_pypi_token: ${{ secrets.TEST_PYPI_TOKEN }} pypi_token: ${{ secrets.PYPI_TOKEN }} if: ${{ env.test_pypi_token != '' && env.pypi_token != '' }} run: echo "::set-output name=secrets::1" outputs: secrets: ${{ steps.secrets.outputs.secrets }} build-and-publish: needs: has runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 - name: Install dependencies run: pip install build twine - name: Build a binary wheel and a source tarball run: python3 -m build - name: Publish distribution 📦 to Test PyPI if: ${{ needs.has.outputs.secrets }} uses: pypa/gh-action-pypi-publish@release/v1 with: password: ${{ secrets.TEST_PYPI_TOKEN }} repository_url: https://test.pypi.org/legacy/ skip_existing: true - name: Publish distribution 📦 to PyPI if: startsWith(github.ref, 'refs/tags') uses: pypa/gh-action-pypi-publish@release/v1 with: password: ${{ secrets.PYPI_TOKEN }} sphinxcontrib-django-2.5/.github/workflows/linting.yml000066400000000000000000000012311450461522200232740ustar00rootroot00000000000000name: Linting on: [push, pull_request] jobs: black: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 - uses: psf/black@stable isort: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 - uses: jamescurtin/isort-action@master with: configuration: --check-only flake8: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 - name: Install dependencies run: pip install flake8 flake8-pyproject - name: Run flake8 run: flake8 . sphinxcontrib-django-2.5/.github/workflows/tests.yml000066400000000000000000000022501450461522200227740ustar00rootroot00000000000000name: Tests on: [push, pull_request] jobs: unittests: runs-on: ubuntu-latest strategy: matrix: python-version: ["3.8", "3.9", "3.10", "3.11"] django-version: ["django~=3.2", "django~=4.1", "django~=4.2"] optional-dependencies: ["optional-deps", "no-optional-deps"] env: OS: ubuntu-latest PYTHON: ${{ matrix.python-version }} DJANGO: ${{ matrix.django-version }} steps: - uses: actions/checkout@master - name: Setup Python uses: actions/setup-python@master with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | pip install "${{ matrix.django-version }}" pip install -e .[test] - name: Install optional dependencies if: matrix.optional-dependencies == 'optional-deps' run: pip install -e .[optional] - name: Run tests and generate coverage report run: coverage run - name: Upload coverage to Codecov uses: codecov/codecov-action@v3 with: env_vars: OS,PYTHON,DJANGO name: codecov-umbrella fail_ci_if_error: true verbose: true sphinxcontrib-django-2.5/.gitignore000066400000000000000000000002741450461522200175060ustar00rootroot00000000000000*.pyc *.pyo *.mo *.db *.egg-info/ *.egg/ .coverage .project .idea/ .pydevproject .idea/workspace.xml .DS_Store .venv/ .vscode/ build/ coverage.xml dist/ docs/_build/ htmlcov/ __pycache__/ sphinxcontrib-django-2.5/.pre-commit-config.yaml000066400000000000000000000005061450461522200217750ustar00rootroot00000000000000repos: - repo: https://github.com/psf/black rev: 23.1.0 hooks: - id: black - repo: https://github.com/PyCQA/isort rev: 5.12.0 hooks: - id: isort - repo: https://github.com/pycqa/flake8 rev: 6.0.0 hooks: - id: flake8 additional_dependencies: - flake8-pyproject sphinxcontrib-django-2.5/.readthedocs.yaml000066400000000000000000000007011450461522200207400ustar00rootroot00000000000000# .readthedocs.yml # Read the Docs configuration file # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details # Required version: 2 # Build documentation in the docs/ directory with Sphinx sphinx: configuration: docs/conf.py fail_on_warning: true # Optionally set the version of Python and requirements required to build your docs python: install: - method: pip path: . extra_requirements: - doc sphinxcontrib-django-2.5/AUTHORS000066400000000000000000000001521450461522200165610ustar00rootroot00000000000000Original authors: * Diederik van der Boor (@vdboor) Maintainer since 2020: * Timo Ludwig (@timoludwig) sphinxcontrib-django-2.5/CHANGES.rst000066400000000000000000000121701450461522200173160ustar00rootroot00000000000000Changelog ========= Version 2.5 (2023-09-26) ------------------------ * Drop support for sphinx < 3.4.0 * [ `#45 `_ ] Fix rendering of inheritance diagrams * Drop support for Python 3.7 Version 2.4 (2023-07-02) ------------------------ * [ `#39 `_ ] Fix table names of abstract models (`@insspb `__) * [ `#41 `_ ] Fix rendering of iterable choices (`@insspb `__) Version 2.3 (2023-04-12) ------------------------ * Add support for Django 4.2 * Drop support for Django 4.0 Version 2.2 (2023-03-01) ------------------------ * [ `#35 `_ ] Fix interference with other ``autodoc-skip-member`` signal handlers Version 2.1 (2023-03-01) ------------------------ * [ `#32 `_ ] Fix rendering of nested directives in model parameter documentation Version 2.0 (2023-01-02) ------------------------ Merge fork `sphinxcontrib_django2 `_ back into `sphinxcontrib_django `_. *Versions 0.6 until 1.6 were releases of the fork. With version 2.0, the changes are included in the original package again.* Version 1.6 (2022-11-24) ------------------------ * Add inline docstrings of model fields to parameter documentation of models * Add support for Python 3.11 * Add support for Django 4.1 * Drop support for Django 2.2 Version 1.5 (2022-01-05) ------------------------ * Support string foreign keys of abstract models Version 1.4 (2022-01-05) ------------------------ * Do not reference related names of abstract models * Drop support for Python 3.6 * Drop support for Django 3.1 * Add support for Django 4.0 Version 1.3 (2021-11-20) ------------------------ * Fix ``AttributeError`` when ``django.contrib.contenttypes`` is not in ``INSTALLED_APPS`` * Emit sphinx event ``django-configured`` after ``django.setup()`` is finished to allow monkeypatching django during documentation build Version 1.2 (2021-11-08) ------------------------ * Add support for Python 3.10 * Add support for Django 3.2 * Drop support for Django 3.0 * Add option ``django_show_db_tables`` to list the database table names of Django models in their docstring Version 1.1.1 (2021-03-02) -------------------------- * Support django.db.models.JSONField * List choices of choice fields Version 1.1 (2021-03-02) ------------------------ * Add support for Python 3.9 * Add support for django-mptt with Django >=3.1 * Append initial docstrings to attributes * Fix mutable references of pre-commit hooks * Fix tests for sphinx 3.5.0 Version 1.0.2 (2021-02-02) -------------------------- * Add support for GenericForeignKey field of django.contrib.contenttypes Version 1.0.1 (2021-02-02) -------------------------- * Fix Intersphinx mappings to AppConfig and Manager classes Version 1.0 (2021-01-24) ------------------------ * Fix more Intersphinx mappings to Django classes * Refactor package structure * Refactor tests * Improve docstring output * Improve handling of related and reverse related fields * Add documentation for sphinxcontrib_django itself * Improve docstrings of iterable data * Add config value for Django settings * Load autodoc and intersphinx extensions in setup() * Provide default intersphinx_mapping * Return extension metadata in setup() * Move dev dependencies from Pipfile to setup.py * Add readthedocs.io integration Version 0.7 (2020-11-30) ------------------------ * Fix Intersphinx mappings to Django classes * 100% test coverage Version 0.6 (2020-11-16) ------------------------ * Fix deferred attribute for Django >=2.1, <3.0 * Django: Drop support for [1.11, 2.0], add support for [2.2, 3.0, 3.1] * Python: Drop support for [2.7, 3.5], add support for [3.6, 3.7, 3.8] * Replace force_text by force_str (deprecated in Django 4.0) * Improved test coverage * Support for Django ModelFields Version 0.5.1 (2020-01-26) -------------------------- * Fix deferred attribute for Django 3.0. Version 0.5 (2019-08-09) ------------------------ * Model fields always show verbose name if present. * Model fields are skipped when they are already documented. * Support "self" in foreign keys. * Allow ``:setting:`` registration to fail * Fixed ``runtests.py`` for Django 2.2 * Reformatted all source code with black, isort and flake8 Version 0.4 (2018-07-26) ------------------------ * Fixed Django 2.0 behavior when foreignkeys are strings. Version 0.3.1 (2018-03-11) -------------------------- * Fixed Python 2 issue with ``list.clear()``. Version 0.3 (2018-02-19) ------------------------ * Fixed Django 2.0 support * Fixed missing form fields * Fixed handling of ``ForeignKey('modelname')`` Version 0.2.1 (2018-01-02) ------------------------ * Fixed bad packaging of 0.2 Version 0.2 (2018-01-02) ------------------------ * Support more Python versions (removed f-strings) version 0.1 (2017-12-07) ------------------------ * Initial version sphinxcontrib-django-2.5/LICENSE000066400000000000000000000261351450461522200165270ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. sphinxcontrib-django-2.5/MANIFEST.in000066400000000000000000000002741450461522200172540ustar00rootroot00000000000000include AUTHORS include README.rst include LICENSE global-exclude .DS_Store global-exclude Thumbs.db global-exclude Desktop.ini global-exclude *.swp global-exclude *~ global-exclude *.bak sphinxcontrib-django-2.5/README.rst000066400000000000000000000110231450461522200171770ustar00rootroot00000000000000.. image:: https://github.com/edoburu/sphinxcontrib-django/workflows/Tests/badge.svg :alt: GitHub Workflow Status :target: https://github.com/edoburu/sphinxcontrib-django/actions?query=workflow%3ATests .. image:: https://img.shields.io/pypi/v/sphinxcontrib-django.svg :alt: PyPi :target: https://pypi.org/project/sphinxcontrib-django/ .. image:: https://codecov.io/gh/edoburu/sphinxcontrib-django/branch/main/graph/badge.svg :alt: Code coverage :target: https://codecov.io/gh/edoburu/sphinxcontrib-django .. image:: https://img.shields.io/badge/code%20style-black-000000.svg :alt: Black Code Style :target: https://github.com/psf/black .. image:: https://img.shields.io/github/license/edoburu/sphinxcontrib-django :alt: GitHub license :target: https://github.com/edoburu/sphinxcontrib-django/blob/main/LICENSE .. image:: https://readthedocs.org/projects/sphinxcontrib-django/badge/?version=latest :alt: Documentation Status :target: https://sphinxcontrib-django.readthedocs.io/en/latest/?badge=latest | .. image:: https://raw.githubusercontent.com/edoburu/sphinxcontrib-django/main/docs/images/django-sphinx-logo-blue.png :width: 500 :alt: logo :target: https://pypi.org/project/sphinxcontrib-django/ sphinxcontrib-django ===================== This is a sphinx extension which improves the documentation of Django apps. Features -------- Improvements for the output of Sphinx's autodoc for Django classes: * List all model and form fields as class parameters * Improve model field representations * Link related and reverse related fields to the referenced class * Hide irrelevant runtime information like ``declared_fieldsets``, ``fieldsets`` and ``Meta`` from classes * Add information about autogenerated methods * Fix intersphinx mappings to Django modules * Custom text roles to cross-reference the documentations of Django (``:setting:``, ``:templatetag:``, ``:templatefilter:``, ``:fieldlookup:``) and Sphinx (``:event:``, ``:confval:``) Installation ------------ Install the package via pip: .. code-block:: bash pip install sphinxcontrib-django Configuration ------------- Add the following to your Sphinx config file ``conf.py``: .. code-block:: python # Add source directory to sys.path sys.path.insert(0, os.path.abspath("../src")) # Add sphinxcontrib_django to installed extensions extensions = [ "sphinxcontrib_django", ] # Configure the path to the Django settings module django_settings = "myapp.settings" Optionally, you can include the table names of your models in their docstrings with: .. code-block:: python # Include the database table names of Django models django_show_db_tables = True # Boolean, default: False # Add abstract database tables names (only takes effect if django_show_db_tables is True) django_show_db_tables_abstract = True # Boolean, default: False Optionally, you can extend amount of displayed choices in model fields with them: .. code-block:: python # Integer amount of model field choices to show, default 10 django_choices_to_show = 10 Advanced Usage -------------- If you want to run custom code which depends on Django, e.g. to monkeypatch your application during documentation build, you might run into an `ImproperlyConfigured `_ exception: Requested setting INSTALLED_APPS, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings. Therefore, this Sphinx extension emits the event ``django-configured`` after ``django.setup()`` is finished, so you can run your code the following way in ``conf.py``: .. code-block:: python def patch_django(app): """ Your custom code here """ def setup(app): app.connect("django-configured", patch_django) Contributing ------------ Pull requests are always welcome! You can install all requirements of the development setup with the extras ``dev``, ``test``, ``doc`` and ``optional``: .. code-block:: bash python3 -m venv .venv source .venv/bin/activate pip install -e .[dev,test,doc,optional] pre-commit install Run the tests and generate the coverage report with: .. code-block:: bash coverage run coverage html Build the documentation with: .. code-block:: bash cd docs make html The documentation is automatically deployed to `Read the Docs `_. sphinxcontrib-django-2.5/docs/000077500000000000000000000000001450461522200164435ustar00rootroot00000000000000sphinxcontrib-django-2.5/docs/Makefile000066400000000000000000000011721450461522200201040ustar00rootroot00000000000000# Minimal makefile for Sphinx documentation # # You can set these variables from the command line, and also # from the environment for the first two. SPHINXOPTS ?= SPHINXBUILD ?= sphinx-build SOURCEDIR = . BUILDDIR = _build # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) sphinxcontrib-django-2.5/docs/conf.py000066400000000000000000000032411450461522200177420ustar00rootroot00000000000000# Configuration file for the Sphinx documentation builder. # # This file only contains a selection of the most common options. For a full # list see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html from sphinxcontrib_django import __version__ # -- Project information ----------------------------------------------------- project = "sphinxcontrib-django" copyright = "2021" author = "Timo Ludwig" # The full version, including alpha/beta/rc tags release = __version__ # -- General configuration --------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ "sphinx.ext.autodoc", "sphinx_rtd_theme", "sphinx_last_updated_by_git", "sphinxcontrib_django.roles", ] # Warn about all references where the target cannot be found nitpicky = True # Add any paths that contain templates here, relative to this directory. templates_path = ["templates"] # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. exclude_patterns = ["_build"] # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. html_theme = "sphinx_rtd_theme" # The logos shown in the menu bar html_logo = "images/django-sphinx-logo-white.png" # The favicon of the html doc files html_favicon = "images/favicon.svg" # Do not include links to the documentation source (.rst files) in build html_show_sourcelink = False sphinxcontrib-django-2.5/docs/docstrings.rst000066400000000000000000000020161450461522200213530ustar00rootroot00000000000000Docstrings ========== .. automodule:: sphinxcontrib_django.docstrings :members: :undoc-members: :show-inheritance: Field Utilities --------------- .. automodule:: sphinxcontrib_django.docstrings.field_utils :members: :undoc-members: :show-inheritance: Attributes ---------- .. automodule:: sphinxcontrib_django.docstrings.attributes :members: :undoc-members: :show-inheritance: Classes ------- .. automodule:: sphinxcontrib_django.docstrings.classes :members: :undoc-members: :show-inheritance: Data ---- .. automodule:: sphinxcontrib_django.docstrings.data :members: :undoc-members: :show-inheritance: Methods ------- .. automodule:: sphinxcontrib_django.docstrings.methods :members: :undoc-members: :show-inheritance: Patches ------- .. automodule:: sphinxcontrib_django.docstrings.patches :members: :undoc-members: :show-inheritance: Config ------ .. automodule:: sphinxcontrib_django.docstrings.config :members: :undoc-members: :show-inheritance: sphinxcontrib-django-2.5/docs/images/000077500000000000000000000000001450461522200177105ustar00rootroot00000000000000sphinxcontrib-django-2.5/docs/images/django-sphinx-logo-black.png000066400000000000000000002225041450461522200252040ustar00rootroot00000000000000PNG  IHDR^AzTXtRaw profile type exifxڥivdv3 á]3m"TM:m*2t/Nw߯7J-Ru3W/|~??_{-V5}~ /}4#Ma߁R!|eyu |^N?R,g_+ۅ7S'SL ΅!U~O3K' _]M5g_eߘ_K߾B}V^ܾſW(}nUlھY&УcjF5xwQՋm{"!FSHb Fz\I7VrS#ɋ'ލ%v{Z;pi zýjKK/VQfʜ~r `Q"? D'.,~%dZH%X5l$h0rd 79%#7-Rû4ێ32QgM]Fr.O͍%\J1^%V̬@qTZ^GK-ҬZoǞҭzcȃ1L3:s,gUk?{p(O9viq)ͷ\#kߴZ|҅n?CIQHXt9PQ9-9HW$r2F ;?U_ys5-o9׼.k[4Յ Ot׌㵏sz\6g;}m:y":,'z.;o;ϭ%]+)cB}uv|+]C %:i3l?a*]h> __k<k2Hg[a)cwz{S,Kq!$n\V6S@Ɋ.*&S^Tv2ן #uINX>s*e]M4FN8q^c\&=*j(u'D|v[3Tb:9VOXκ0a՚EلBWK;2vKK˒׿yj>W!vffOQ-:.)ᵞ|nHa54™*yZ+q֧rt!wCؾ[O~K4>3X@k (^'^'`}[1Cb12 >|+@SJޘ$KD%/pu<i5今Ƕ̣.?: ~ #yQ!LA9Lp~Bp°Ya%[ՈE>0 BKK{:Ai ~`gPf=q!hPTtrCC+ hHՀP6[}.=w R&@m0h9$JdV@`%CʬޑW0J = ):6S#cej*E8_V&Eo9F#܃PiSj}Q@Y"ʳz,=W s}0~Z7V#_&ASC aRHIԵ6kT%&|L IƓߦu!QzV/rcD;h<-n #́"MC@;jTVQq:#e%cщ0ɼQmӢ {l,f^b>76gr5zl3.FT:grW:"fXOnBDǔ8H*d174UBQDN$cyݥ@/fGU*W.6})'@YRv&Q6)8K/—.|d9p*G_z"jAV sgrCWpyy92X?jZ1aҾ(f|խQ܈y ߾jUpf$A%FJ ߷D}a% N^PrkA$OO}H 54"xMuTn0y$8ӒJVY2}H<Рp'(G?tWPS#)11RO8]DI #6V‰ne>|gsM`فUVFL,[1ӑT%1HG嵹vqW'G[܈+4sN#T8JoG4lk3u,׳^aԏ^ƃ.7H,/f%'Jv# Z\VcxhbZN/)_Pb\ڲt6"IL Ġ"`kBM%Ǫ}TDN\m3*Y(>^jBo&xpmSO`*Ԍ~\F{3[hm h H=܅?q!~̼~>oA&"aa\GE191$h߇2,n)jR hd'aldYN^+ ]Bz|Gat'_<%#PT@z'j_ Ȇa4JH ԮMFkuz|P~joĄX*^ ͮPrCaavmimHp'k?G>;wO㻣Aq Gv z2LQ?ĵ4+c R0D{b{e aHI$a`8 .)cO2: "[(vUq״91 0MCvn%RTw\ND P=W|tEՂyӎ2=D oJ҃1Zim ،r;>ٌ iɁW ~^Æq ph'e|(7}x"NQ,+h+ ԩDZ _wrj/9D(*Xo EE$0 $!}}G\&'KsҶVW}":A扄 k ӠjX|>YyQ4?MAbt_|4(F[HSB9feEQ_κ^O {2<֖ X5SK*TШ]d;zJ>j{ (` 񰆁G =U+6)'Cj,Ki7ȚQxmFޮB}6%Ђ JI 6,Cb,?T#n6@>] @5(^t 5Groiy19'#wcL"t< bo'Ik6E˧g.-‘Ԕ ᫃%F pZanDza A.T[<<>'pҴ1A(Fmv1u!j:-3:ZNWa?[C6D* 8鼠|sښ5Vx"QG󉮤8Uk݁EHxtᝐ50c8mK8{>ߢɣ22y"Ny@"@Nu6!"fC?xaF*&!j#-.g0&-t0 hQ&Ip Β6%9aXMHGƗR%;n4dƤiGZ G쒌\r|o&F.P }ܫqf$E!BQ $6^fJ,mLG(.23+T$tu4Fs 49^Rt-7SFvN0@{JcQN,u Ȣ}Xj0 8(k"'/:4>Q{72G( ˹qv6e:CP*oD( h,2]@N3mt&DīeD>O}|  L ZݯwIH6N4&RN*@@@W:ANvQu@eC{o? \0֨/ Gka&q v)cG(^#j:PMrm“UvNA)xuΦߣca})FOq tKAF&AH@c_%&`l:$CgՄҎWSAh]6p7Z>̨Cg "̐0| ۉR)h놮ɽ.Bjv} D'2 /<6$)q%awNVDҔ}Ϛv"@y8%Zx!@ؔF؁ТVYxo&J6yc$)ƣpZ,D[4tԧ[H,d;N'$1C d_mH J=AGgĮOhʛ82xC#,@# 2:sO2GSlȈng5 GZ1!G?L ̋vciK[+ :[j>}I7= -(Ё1"КzP\(đ#"҃>md±=ڰ@!+,@Ӄtz$v“_5K) }!Llk#% It+}OZ SVNeѕSw<l(M}fџr$XKxpO59N$˨(CMȔvXQhj=dG,n ``^?WNꬬ%)-9FS Z]Zʸ_7dRTQU똍HAU`t!.P'i ^TiCCPICC profilex}=H@_S;8dh,8jP! :\MGbYWWAqssRtZxp܏wwVb1hm&11YA`\f1'I x{zYjbO$eioOo}+*9I$~7y2SyocYԈêSnyV= Y}e4" A (FV Iڏy\D.\E0r, ZɉFR0t8G|;N?Wz_3W[Z.[\Olʮ)r}S5q pp){]{Jrw@] iTXtXML:com.adobe.xmp {bKGD pHYs  tIME '1g8 IDATxۏ\goUIDQF3##{4\70 2 ? @6f|{_d}@{2IF'clIr<-fkCWSUk~y$I$I$iK]~uLvkhM I$I$I߹%Wtje $I$I$mVP#tXY]wC on-!I$I$I?w>uKHک %I$I$IYXu+H %I$I$I;nI;$I$I$Ip$I$I$IR J$I$I$I g((I$I$I$5$I$I$Ip$I$I$IR J$I$I$I g((I$I$I$5$I$I$Ip$I$I$IR J$I$I$I g((I$I$I$5$I$I$Ip$I$I$IR J$I$I$I g((I$I$I$5$I$I$Ip$I$I$IR J$I$I$I g((I$I$I$5$I$I$Ip$I$I$IR J$I$I$I g((I$I$I$5$I$I$Ip$I$I$IR J$I$I$I g((I$I$I$5$I$I$Ip$I$I$IR J$I$I$I g((I$I$I$5$I$I$Ip$I$I$IR J$I$I$I g((I$I$I$5$I$I$Ip$I$I$IR J$I$I$I g((I$I$I$5$I$I$Ip$I$I$IR J$I$I$I g((I$I$I$5$I$I$Ip$I$I$IR J$I$I$I g((I$I$I$5$I$I$Ip$I$I$IR J$I$I$I g((I$I$I$5$I$I$Ip$I$I$IR J$I$I$I g((I$I$I$5$I$I$Ip$I$I$IR J$I$I$I g((I$I$I$5$I$I$Ip$I$I$IR J$I$I$I g((I$I$I$5$I$I$Ip$I$I$IR J$I$I$I g((I$I$I$5$I$I$Ip$I$I$IR J$I$I$I g((I$I$I$5$I$I$Ip$I$I$IR J$I$I$I g((I$I$I$5$I$I$Ip$I$I$IR J$I$I$I g((I$I$I$5$I$I$Ip$I$I$IR J$I$I$I g((I$I$I$5$I$I$Ip$I$I$IR J$I$I$I g((I$I$I$5$I$I$Ip$I$I$IR J$I$I$I 7&m$-bW^V_$I$I$ CAI{Oy00 +˱,$I$Ic((IϯMhuSUח6ͥ 0v |M%* w^> A~O<,C$I$I  JiQsZׁDMXx 濷kD-B뗁[MZD% > { J$I$I+a((ika$QscD5LT a< QX̀m ADȷJ:}pJD%ჼ]R[R$I$Iݠ6V ! Q6 ETa8#"õǭn6Qw a_ r<1)~t.GU­U$I$I %5Q;orLQ`_?w&_?J땂~'nw@ ׉*Ep0O߹\$Ƶ>CBI$I$IzNvzU_}Jj㹗rC7:%d}U"{DT> B/;D5QY0_BTk$n:$I$I]PPNWaok|vʏES+5K%5 o7Dua ,$I$I9 .i싆nh9S9ƉJT~ Tu)ܹ֞T-GT-S]!BE",r>w#JT.|ot5H$I$Ij2CAI;('*Gj1"j.-E5J;I=Gz(a`>s_#B& J$I$Ij4CAI/[iYBD$gpXn6oǨoR>:t 8Մw{&$I$I4 %m{-FP,&Qx2ﭽnͨ-z/vjǺמҊt |AT^~OT>&Z>$RQX%I$I$i3CիfDD\>7E~D`Y/ppͩm4ngsph5zH&-Մ2$I$I Jz^ psQUYDȲpN8dW>-^>ϱB1UE na}CI$I$Iz %=6M~oX 1MTNA0UEVͨc|awi#2ъ>)%I$I$J5j9""Dcy=(z kU#D%\>#*WD0x%*eN>~z$I$IDw8'DU`G+!Agڅ.k/.UQI$I$IPºs!#9横5{Ǩvg "gͱh!z16mjQ5H0!QQx %I$I$m!CAyJ_o< *'X( S :#"QZ>ֈ2J5a$I$IPPj1";@} q0cv;^ au#D(X%z>"$I$ITUqK RP/*k$.{xXoi6J;PkO:UPx |A_bBCAI$I$IOd((|DQxvEhi :+iPpODPxx ,Ճ7v|,I$I$i3vQ7CgsKpsՀRL8ZOs\"*?%Z>n:I$I$iw3vV~gy0th:OJv۾br;DTr&r[zD(I$I$i0^6s$px |l*ijC\,p0C}'9>&󏁕|z~A$I$I@*U}{;IT)`o7ﱯ}bѿ$*DEzwu{nBI$I$Y W&G1FGIׁ9=T ‘ʯ="=39Vu j>jBI$I$i J[E{jLjugIja %\#½6j Dp6Z J$I$IPPzqbr}o. Q /-AJ^muM!ZQQLGx*MTXjA.$I$IC J_YpOg?"n& b]v~ma)Y%ρOO3"$\#Ej$I$IvCAjyU[УA*p1^ځZ():D$ ^׀DuBI$I$IQhvOo D17rtXo*5QMx V+D:ssJ$I$IPPڨCG׈oQ!3EŤ-B%i7jNg=bD|N$I$I^JU(%&*_jzljжr180K *7s Q=x COܧ$aQI$I$0nVڄ'~JTZp* 4+A$}%-$I$I j7?瀃D8oM&I/\@sq`QI8ܓYb-y{$IT.)%I$Ia(&)|V(p x 1}X kfIV'XwOQ]"%Eˠ$I$I`(&#*Q戊 "ƾ|L~$mB~FMCT^.HP$I$In4OjI7cXMAr"BQ\Pv>}4,Q7o ¥=6]*BI$I$PP #D5[i" 1Vܬ$I$I ߟ{72a$ |@-`-ǗDGDDH$I$I J%40mAv"NJ@Iڽǎz5a=Oku6p F׉V$I$IR j ܽD1{ 3 Q"Iҳ/&" ||`E$I$IPP۩TB2{&Z$I/ǝy\99Q9xh1zDTՃ$I$IjCAm╵ ٱ|M )ubMibҶf$m{ז` (QExxTsJ$I$i@ j+o`'!nI$I$iG2Ӕ0Mlj6kG}T@K[=$i}N|iv|!"GD%",FT$ X=(I$IPPPmbm( '|Ivqr]` ||N?rhI%ړA$I$I^)]QQ X~6V$I:IT%BDKѯBREmF%I$I  bCT9!&2ځ5Oמc;PIZDUHC9D |pX&*wHZ$I$IPpwh80A=I@Tה5` (Io!kqOEz""A5`"OwV$I$ C5h9GT#9֞!$I/ӻ'ߟc uVnDѻDPQ9D9CAI$IpR*gIׁ3Yb0.Y(IW*m? ^%*||/c(C80~<_$I$IR qU418͓grFB*k-A,w6 Vʖ|Xm~bYǃ.ڞM_c@?p/EbU@x7?$"|裹v+%=uv_~hn}|YO܎N\-*I$IPpg)7ݟ?]%! gchW?ĤZ.1)e}]gXc!&n$sR7ALO`9~QU*sْXz1$4QV~K&_.9~f=EGNa9룮];YsԲo*,tX~o,A>p@)I$IPpg!&Dw"~ޟ}8or@Pz]z}KʯE5I;D0$p(URwqb2~<3Z3 {j7[F^TAD޾ǹxHUu|V<$^R]]Z|\oDW:t7<cTJ Ʃ:!]0[ G %I$IRC nMhe3${isUמOI.Q*{ϑosk9_;俱Fj~gݩ6-T`9N~wJrA:T!*|׈ Ab ^ac(0zyk<_pXsr2QB? kި;JH$.Um%I$I*A[DD'򦴺ԆF KD_`_"#&m^_{>mT*ȋs%V>JybVm?):TtX\o" /ᣧ|{|Z 1\~OrinE<s܆$I$Q _MusTWq8P>>NLSMIzkDU_K:>pHG~,RU B'm$e95D%繿+Hr8KEi JR],3֪s<3[7Yo-H=5us??OSN`X$T[J$I$5WzLҕvZ qFOIzqN=׉5e}Q"8A>-u",,k km}nRWZ&rNUᆂ$I$Q _LkmR;{JSrB[aDBT%½kD Nj%TuKE\MRun^!K\81JT SU .؛}?-d~LS-D%I$IR >]kRqjCD@XZi-$=>պv}"{D('|.W KDH*@z%x-S^7A\l1w:jGk#|ZGpm:xVThsolj GCD(9~M7x1$I$IjZ 2F M^bByj :-Wo%Be"+UD8vh<.׺iXڴ_omL0y}q!HYP5wąkFT$I$5n Tm?Lj}$PG=d1]ڈAa_WZ}U D{ƭT,ACDL |pZ0U *)cVK$IQ& IDAT7`6q`. S|U2=jyX1zvA` Wz{Tn"1_%,k0p<ׇ $Nk<Hf;9 .:$I$Ih;9lܮjy 8DL"&zg߽䮓֪]JD% '*HT.^V`e/Wr{JEaₑQ=GD5~VӥbU;VIj<<hPP$IzQ#NvoI;9!zND 'TkMJ:RNzU<&RU>x“;o*,^'©ڱ`PjiRn I$??:k]۽}gk1WZ?+Of;;:{3 oQvbk!½dk n5vUe|kDC"D)k-kBDد i'Ws7*5 Q>jO]ZS* % D'<Z.IJ_'<\pQ9_O_ZY[֙[:?V'z/iPGרip"_?V*7:x$_S!W+N%+%" \"* TjCf?ZT "ƒ Z5wun%IY~^Uee_V5??g7[\>40T Nk3$41a quiVZvI(OSU.X&*e"V{2TM\S-qTU_FJ9um6N&k8? :՟b((IA0:鬬u?UŜ1A>¯a >:ׁj?^-I% ?)3VoS$i 'Mm;!'.Qnk^&¿.6MzVݢGrt Fvo_'A7igkgQ-|"Id͡~hYUEy4[g WoIӠP7&**Ʃ*%sމ3nU"Nu}2tM(m| m/8H̞dzD8N3j{/I$?B]~ ?pvWTEGlM 5$o{DEߓ*-bmψ_U5U~'U46x:Tk>}_e)gUn~m8?c_v&*5&ZTkvjVKt~Ng(Imm@ 'BIڹ )JL,o"p)oAƚgNTAC֌U_Sy| ')?Ii=9W,Va~A? Ud-_{hZp=ѵd&OC8CT{D#,m"X$I?kETa(( y"U²"+>oUflleW_v#TLl6Wœiv%'žG{GT|E2p7cnϊ{f6֫kQ{{k<Grᾼ?KQ]hrL~-T %I%ڼOW3 yJn?w{'c~zrCCCAi@T o-@SU&B"Xv ڵ0pǁw'-?Ks1PGn_%H䀮}SǷ 﩯WY* /j܎WD@{>߇TDPx,4UQI[MRg%ICg¯A $mёwvu^흿ߢyZ W-.ڻ=j)=+NUٷD,WZ^$Bo5r逘-UxeM=DR9j%²R9Z>.kAw يmX}"`,!"Q9x*@,!aY&U|n ̩ͮID`8O\  Kk=l %VO?>`dI$=6_uf5$5vT=[)ܚ?wāC&} 'e:o1NTV:D,ц5":B}-i"p/a_'mH%r}>C]_i|#ǧTD0x8 DP^B~*$IS 9>_8੣A?w֙ |kM/x|rH;gJL'&_ix[܍{! "Cx2VT<땂,m@1TrP~?cb ަ8\"* `! i=`-c1"5b]C$gd[J/r?8#IёNke_VAmA%5GT}w PPzzlTS׀19QMwFf}#TkCMLL_ QݼF`SԫFjx>qo/$&cK(xhX,-?]Y6 jgTv@:UoPA~WXLʻ.]YΣ|X|z=GA8[M`]*FXth$Iv=߬ʟ$ CA)76c`&`&*Wb*he w&x8@nS16-UB?o=եj[2U@d:$^4h[ ,V0QY{8<M>on>wNPP$|gA%IPPaJRY8qAoRU .ҼT 9"l#f*T~}D`Q*\LO,oGs>&T|njKo?R q̝>"D` ?څ!R<7$IRs]~}ӧ7C 8?  ψψ* Tz5bVLAmhxxJpo8Vxח~ ||LT^cceowP?nجO E~mE\c((IVlY[CԸ㜛@ʚu&‚TUEw՚eM3c=Bܟ"¿DQsh8߳cT)ைpN~ί徠|>IJhx;g|FըC0cI$ "tY $5ӕJub|5''&`S,>v1ῐc_޾EI jHy\"*!W>QQw(#bkTUeƵBLsϟ8CT cDU1M g0.M8$I4P:~٥~n IR JOV |@L\&BDxo3֔Q15NL 9b=y &Kx8gMBJ²ϸTO W(RWln'K[iVMK$5Z# Sޯ %IT]տFT,QN_1w4M`t br1y(?-J]* BT>Eb.DxPn?j}B>+D(:U`6ƨ."Ѿ{$Iv1N$i72bb{ B\=ybb:_ P8ՀoICT-;T!b QIWZ?$..8"I\tp+_G+ebů.68vy"(l/р'|6$Ia %I UduιI\ĻNWKDT<{oO6I "ܘ#}z@! 徥T%"ڌ!´x>l 6}DpsnF 5>IT !?Ò$I!:tE_%$I2TkM]b.~C^ &WjV>ڵ1ITL?%;lj}r>D!'TUkD8 ]'?wj/מcWk9s{p8KT)ZQ{ eD<".i>$Ize'i_vK5%IJj.1JL>"¿[>QwjQY1T!&(Nv<uԢ 3Cv[;D%z^̟~D`?]e=}y}v J$Cm]wJ8&Ѐ*DLLqKDxLHנ(!M " fDp8ƶ^T 6AT ^= jG9[W}r}\i]|"'e ^".~CU=8(ڋ.sUDO=IDHFnal/WM? ^IH_$=v'&(?oo_|\!^6OL&ZsX(5EpGx$|;JUMV;9(SDE'mY|;iMaG$i[thuߺ%$Iz>։T^&)kbyQbB$&юu,1=ecx igusy3Qt^zH7?PcOG\?Iv͞+h{Zcy.uH$2_,[BD^u._>'&S*cD˺Ą~pm % e3)"$+"׉ 7$Z:}'Bu","9E\ |xco}O{s4O$IځՁ$m%CA}s-#buY"&w:B*1*$ʺAӵQLD0X(i)U-aƝWkDHxھo5mmuY_ܟ tfr_>cھT3Sc((I\;PPPWhH-JjbƪAl5 MDUtVJ\+_czz\&?_Ǘ*AڀWvv~4DkYp6ov2QOq"I<'R喐$0ԓ+I[DxE\^.ʑ{DkoC#&gQ"4%i s_7K\R-~?*nPMS{1K7MqG Lr|8JTbx _r8I$=Hի}VJZnI.1Y[Zj_mR8D'"Z-NJڍ&r|1q+>~| |N\8ǚl6a?ߖs|kƈLjJ3O!ZHfYN]6BTh_*i%I Z쮬[BPpw+Z ϯ 1{]&igaXGMvDU 1;E@P6K!oϺ5$I>Wڂ.XIDbbs=kTbMi"&m),5T %5:=S;\'H+wjǠARp?ʟ3$3GTwur{* Tb >-bs"R8K=MW aU$ D#Zn*;yI;gHfzy,_?Ւ{@T <릈¡ڱǾҎ\HBytvGz]P$itZg %IA O*P11!LL\P*miwէyWꡌbs=@ y{u$i:TTawX:U+E" KuM9Ė}m5>Bz2Bi"8,$STʐ _9R jۣKyU Jk~>=CI$(Cm]_Y[Bvvl q-<1Yu+v?_W=~IYb'3D5$UJ5$5_+BG?XZEuD{ΏkYynp=J`i=T?)r?~:oZU;Wwr*,?#BRKX$Mܩs(Icͻ= %Iډi7)WWr]rv~veK de"wX8caƈpv{-Q?Ef3q G$Iz$I=pv>QD"1iu4(-חIr7,a3JBYp $'f[>:bR9qY":__~BkS?:d?\=:l6$IM$9!_ &*,1IvX禄爰k{ip]buh41$-smQvVe^$*>ʌoI$= AIz]λk^!Dwjp1?umjfnn" DKh0$'u\ \DXx"fKI$ AIzg_*%V>wj]Rw[~jyc]0ĽcTmضAwkV!IR6BTCSZ^y"k|.r1J$iJԃ>@p+{$Ux:#?_ڈ6 Az p&ZNڀ[q8PԛGč0[/a⦡KTk %IuvJԃ.kwl17ϕ;ZyY?[Z}kTsswk D%U跉6l$ڭ5Ip(;< .b~M5-VWDHx瀛^\*z}%7R_9$D}<[\+!1.]bB;?FUW!giD;-DCnBU!\Mbl Ą|YPPcIAǣqb wѥv;$IU 8hH{3,is]NiʯUWi@܉?nc  7}U8*Tmm QanR8\'&/qJ&۵-%=k1AeZ^ߜ!ڌ~_1`P$Is{$I=k9CdQb"A .ԈT>; 43"#%"#Bڀ[sK8BJbw Y"_cL21)w!yR涣e>[:<#Bqb̰C˭R٦+aQw8 x2[sBt?gi 8O%W=W#¿?-b-DEKľϓFOX w7G\x&9-[nL#1Uݪ`UW~&7;ɷX|'<~߯MR\󔛝߯A]\YtKTmWu#G% ?#+Oso`*IC &͗ IvɩQb|m#UW&w'&$VN(CL. , &[IgJUb݇X?uXoXV/;̦ʱW75g:F$ITV_:$y!Xr5b"y/KD𷟘o+НD 3RJ;y Ѳ Q5OAT`,՝[ |)^Syk{u1:BJB1sy/vKkUhxǵ}kܧ5-o}?g便Gk<ђM %I(|Jv q!A{ {hO^4- %IMt$$I_Vn#ֵ &W)ۈ Z8[Zc>]:Ïy⯴< 5u@{e´ssf{jR)X&9= Q 8CTAǛDe"U?.v7lA"Z_MD$ l#!IRPkwp)6 > D+\V_ew<e*?)%5vCAI4l*I@Pƽ(ԕ ;Cﮣ &I )J5*Mc#o D%|Q4KLp6p=1ɻs$]^u1ynBnǀWT֥ݐr.[r^{+|$IZU $i,g(X_y~NvDX>XiJno 1Z~״:&2\$B"vav`Ҷ$ 7'dLK{'$1)q]n:pN)brDu i_Gy|I@+"XK,[<Ac$IN.L#!I2ບhy Eb28^Kʪ`sܗWxo׉{KzpvACh8[FD6(Z?'5{?H?XO?8L+=Xi8$I'cC/|Ӂ$i JE'Y"FT ] '/6*M9%nJ8L?'&]vҽy]|0G#I H$CAD@Yӫ;- fj`7o-"l {|19D0GT Zn"Z"Q$Q-g/y]$:/4Z Id((}XkNT-. oq^C_Mo7-"|:Iڌ j w3Ȓ$O4[|Q$I`(֠)-@\>fϵ0u>_TabZiq.j\FNmܶs;uDVQ@ yu^H$Zm8HH$0`[ *o빽FL :6+ѺWizP%EEn4D|pzs_EGrCWJ1`2KU\{Pob /u$IROMچ$B+Coc#~P½cDU'^klJ\G-"jc&Ix";ET v][á}|>7COA1ğn!*3pBQ3~}$I9MQ ,}nvpQ7wqGX;0t7v/4Eh'k}h=͡oQ;Ԧ}% oZDϫ9uN|e|aKyIc8KT>sDE,ωd?> #GŨO Hs?$IV jLרPo-`S?+G}i3S 7iU~c(^Վ6D` nb'a.u}d!il$x!3NTZ?O%&`]n} y\$IzV j^n}zԫmZ4"Ws/:L,_&Մzz6D;Qb-Y$ZI.ya Q )AYOjN/%*4_!ڋ>E,UNl+ :s$IRBUzj/tc B3* ~JBI=w I"ԻA0V@PP$uLT r$Tj=6ߵMڃ~F: q?o#GER^+8ZaĤ"HUu-" M.䟽K҃!Z&J%qSy0\y^Du0n6ET_mkJl,C!IUZ"C }qV;0#괏HR73rhwl @oft'D`:z\w= C{io7 =z9bP~ǁ5DF+ ՍqIԵF V Ә7iIӪ@ICZA l7`*QX*oS ě<2"&Ues-D( 9ʨA7^ " Ѿxa.;祽D~೹$IZַ=tR;8C!Id(GQ5Ĥ8цATp6ZĤ-"8<| .PZ._KӣD;8ugwN Bx4Rۉ5C]cPOZhxpa$I+a U{ߨr($I~pWT`pNU"Q1MTl&B-"Tt}=)w>Q]aJ:M'w!QQ`f9 Q^w􄯃{n $i5Z%XM IG1ԓ Q"p Z5BTa,,V^ji,һDf"X6Gp[B*ԉR6~<׬qL6kYcm%I}h:vav`%GB?l#!I8ZkXKThm$n"&gDkѫ{D{RhS~܀E:qW O ZۉUZ{QIh&$IZ.v玂~~b>HH>hՉ 5" LzXT m17uQy<,ܾFV Z^%/E:P+w = <|bqL$ m ( ;o85p5̌]%* 8=b{Du.ZPp? k 6ܿ0w'Zڂo;TիZ׈ u <l&sAdGyO @Pe `%nf0$IOTf (IzsC.W˭~ML}ybBn__#Y"j:P8DUjh]Y[U㇀h;E덹W+Aչ`61n\^gdp$IOC$SG^nh%E"MLʝ&ž TZY8q1HZ_ Z!#Twu"!W!Cy"ߓ"f~=Gt'kxXr>w9E$I[!jh %I-ʑQbyxț#" |8BC8KoUDA+Eoh`?uZe}DSD si&¾3Dw8:!nj, G$IOCWHH> CAϵQL6%'SĚ?; r 17W4D٫M(Oj WDO ܘ)",۳ߤ<j<"n @ 1'W=˹} L]hiDX:E=O%( $IҊu~:Ҧ{$iI' znr DĺV:"QEx$Xw"Zŝ~ՂKkD0:\u]CUF!bD>~eҤIT_s<ct%IR]Դ( sU#!IZdNA׉r;Iw[`}/󽢥+w_U[7A1Q"­c?7&!B;Dآj+*IU.LH :[;8uؑ$-ٹ!ڄJ<1xbQ5s g=gO> 6t'{Y9fj 4Q/{?zZDXǁK4ql!I'Q[o7Z-AIҒ2>O ܻQapX "J\+Iz ÀS:'PPzt5pQE "ILXg4U;8QKk](;W{A&#*-DTZN94כ|>o}0z!)2UEuV[$|ѠܤA JJ mm>7A'  [?!&Vv&U0_#ZǾ@k1lg5^onU'ڂNn#%JKǑYt'n|_@0 ö $=a*mFK=|X1yx#ORUpr͉Jӹ<D|Yѻuzz`=F?>Kݛx&-v!ϓq5fKDqa$Ivcl*IZr_8mv(@TT.UEe._!*U ",18mKUimb|ԉ DnTAkf9\ZyL}:$_I{X)y{1;^vZDw? Cu<;DŪ_-ۣ~*d\Ry*qN7X.Il߮\p$$Ii+SZDI^:IT%V[JD5~G*׉v6Q;OT >YvvlN~z%l#&چ67BLQUnn=V.S";OT\UMş.:xs7vOVǹ׭TYc)=sKna (Iݾ/%I+alwP~@L Z#* F"(\MʈjՈjtu?k!MbQU*nnR]̭BN>3DM֍ܞǷ}TMri\ o¿E]Q!X^wWX}r]纭^x:ω6ljKDaUTC$I@%I+cMb*1A:DL#&'ʈ}ZjI!kO~j Dx>Q1C@T50\ <]qa zwbxF׶ub.Y ljO8Đ:Z{ↂs\Ò$I7@ǓV JVH7me˼S4H{nCL'&LmZ{m$4-r&wTV!% ovzc^c,TEbWFwy?k. Ut+>v? q/|"S3Dw_G\0I$-W%.'%I+iĺV7IQU"&ͷUl݈IO}vqg5v EU!b)?gNSU=jXI`YWjy"ڑ!V:~JwuEF7_m7x,$IZBm_w3Y;8@HVp?n*wAR6ۉ ׭6TL};Hб/ WQH~cs7TG~8MP7 {l+'+pzkg$7ۈSD%JwUEZ Pp *}CûDߕ$I^wk^u$I+eObnSjᶆ(U[#UkCD1qD(@~h-@TΟ5vwBV>o՚zY9 U~v-Q~h,іRi1} 2SJ2VK$=YcC] aWXIJ8OT.YGՃzcQQ*8Va0(=0į"^ պgJ™ܮ9?odzCa+t_Kvyf=պEݪEqxX3(qs%1Z$ X\\}HaGB!\mHX%/"x/aBQR \oVIWqT[󜰃%n"H6kFW1"BuwqDM#xz\pSvBuOwlWp@Ilcoj߭tHIҊv>I DpңlCjp7DEj"X4XT5DR&AeDu5bTN,êBExWn|&Dȷ:ߋc[W % ுxYn($IV؅Qp^eK<}?gwԼ(FÎ$ >6Zh7oD𷙨< <[IҶn{ם2(ު œ?!s}稂Ir͎E~co-g~a qCUD50ث>VUW  ^vx$I ۇڟ&$u C&ȿJ \dQLU-c&^w %$D,Q1ؠ<#-J!1~vZ#y|Zo/ a`YT1xM~?_c $*~MTrx$IS!3/Cu$[@=60@U.Up*0\ELZ*'G׹߬AJ_i7 1q>|n/R"%lYt{+{յH|]k*vXұ;Jp:i qC Dxǟvt|?qSz ǭ3aD{Λ$Iԅڴ9 }vnPIR1\>-bҿ01iG5=IT1m'&&(m*W~ Dm!z_/\4s>Ckw3;CTf?8HweJ;Ƕ縷Hn=#$ܑUwʿ)4 IW?~EEuÃ$IA_M5|OIR71\ƫ:vٍ(y8Q1 F[ۈ DpQwhZ ?F wa";[ֈ @C fODj}Nu'D7Ƿͫ1"cC+#ʯO`u$IR/ph_۶$uCP|]R#dNf-DUagE2E IDATU'Z Iac,11L5ƅDƏ|(K 梟M -Y$w18 ?t $I]P{IT$'BRE9 bR~-:K˧?+ՉO8> m6imr<.}Z,-5CY ||ha@P$ /.L4~8R;0i+I 5Vw*B#D'm%M{­D*b~jgj"4J;qo׈&Ikվ}]ݏn$I0M-6vEVZMDX!~ՄDX]$^^%DT .:D$I> [a&(I2ML-",DX ؞o Z&BB[I=M@jWN9<a]kvK]tzQIR1_DE ";E>th'"E43?9|$u8 {1,pס$I+[P#6$u#C&Bnu]B=Eb;DuJ%aY*BI<% |xxhne$IR]Z)7\OPԝ  hC$cD )n"(\ET:6I;-X$IbC֟$ he׉KT n#ڋNvbm %IZm}bU"($IR?^=)O,}nSԍ U4;\h/< #MDF}5A$IA7$IR}~B^u$IPPMLP?%\OCx:mDZ" $IExD@(I>70pDv$u5CmBTf`QEh+ JC8Fkq5.A Q x$IsVIaM;KG\ipDPvs;Z9Q"e~= @P$I꽋zWne(Un_+UwY$nm SUn˟AIR[s -5u4Q5xX$iR?GF!IJZjv$"@!$*SG{Ρ$I\mڇ>1 ~e(e4"Mz8l&)hgMz"4$0+jP$IRv$IPP˭Q$u{D$IdC%I$$u3CAF4pxXE1 _ϯϬ$[y茁$I7Wi/%IPP+~KL69jϦgnvt{"4$$u<p [$I? JF^ՃۈpPPmng b$IwZIZ*0O%x8Bۈq`c>nu %I˧M0/ $I_p $I]PP=s]4+D`Xp30 )`WnۉVc~r3($=m"+&*I$}/N9$3TO_73b(6uD`h;ؑo%ź(IZRd)&#I}~B_pIAIRW3T/+ՃsyM[ m ܛo ǀڅVJ4\~ |xn$I$IVU;cD;3sD`$Q9m7V$I$I`(~V* ]"LTn%-ZTEk 5%Iew E$I$VKԝ 5nPƉ_ۈ6%$~׈u g$I$Iԅ 5JET'Zh+ Xp;P BIdQ}RlIk MD$IKz!^oOJu?|y$INk֢"Znv*RI6ֱKz U/Ƀl1ɇ7[y$InR`d{?^Ͽ9 ng` udnp%p7>abOv{5?G1s\ K$I$I=PPn%]]"vq`;p{al;*r;#?~WfPmV J$I$ J۹:Uہ]D5gʟٖ|"1_oC_u->XtwuoC_8k J$I$ JAT\j;Wd*ph/.FTj¡WNk rh@ }8:$$I>^뎁$ J'*$!¿q"DT" 7R ]C]ձ5 kP%<>?_ ׭u\/$I&IR3O g0*"x~U؛;XI(9 _ NaV`_>b(8OTY ?{w#}{}z7E}i6Z%iɛ',ν333 FS~ b'9XH%ZIQD-:-Wd/U_@&Eu}ԩ:y{H$I$( ɉh#:h%'‚Kyd:" ͐Pj~|{x!8B,@z.NѳE˲>Ljj6$I7ݕ EYnqO6ؿޕ$+CAI}/KT$ V7yJ*`p-.K_[D",[ szN_o!n^l^"*OD%I eT]op$IPP҅4+x>$ڐvՂs*yD%t# Q{zֿ/iE`-ϙ`SrC` ^a#I$i,Fj1@|r $Q3DN5zDpx pg:n$΢5ϰJݴ +3)`Q!4SvaQm$I]X4Րȕ$+CAIFT!BByDnp &%zΒ.&9-NbZ p0wI$I$]Ϧ#v f6VU`FWpQmh=:(J3*ڐZY(>%BB fS飴N$Iٓq:¢ +!IjWBsVav0 x9} pf2w+V,N`Ph{5Iϳ%DunԈPp  J]3h݉$@F>vf((i>ͦj3KT." &*ji͠9ð9ǐЪFVbgS`>x7tn-Z&nJ~ k$I$I(]*Hڙv7:0l=f+N飋#BhI{7WGY ?&S\- ?=1gq{ZaJ$Il٦Sehd(xat>;iNqw{vf7#D1ˮgZJet`f6֛~?z<`i}uB9\ΙTgSJTK?wP%4kie3L֦ϻ`Rؔ-T=KGp$I@|)R1t ۮ$-_\ M,S3$hߗ>ބ΁YgCKJlN{MaZa-}|6,`&).oLUhDX}FZ-JiDkeզBFc.'u[h2z~dHl&*FW#O2vt^mG>t7*\^(8%њ8^T'iU1_L] Yv5uo+@{:Va^jDHxxtKO)B$ISgC.#$]5l|7W-NhV0g NfR3UӜ71KQ'1&K#=DsxӴQ瘱[rfeDxW%“#;;4Bq;7&ڻ~t^\H~:Ic %IovW6BC_eWO6ԔWv Vv o.<+}m9bRE(^uIb1 DH!'w5Ũ?Uv71OZK"x&}o^$Iιy5CX JNWbSx~XLl~\MZHU^'}y]0k{D#|v$\/P:ǗehNnNT[:7oe.$Iqt[HQ'AOӉ9{(O xJk*izI6*.x$96+ .` "q1hK!I"ι6i`n&#Z]ֳsbQ:fsPpvY'o?6s-Cܲ^B$IS)k}_ 6 `/qD06Sj41ޖy>)"|%4Eۀ/-C+%[fNe`7JTWnQ-RH$i*պ{14BbneeWO6$ms(%DUD8K6'W"}ƊAISs\Hw*ZOKDO V_J$i {_T> Fg JFmf]}DЇGt H2&bC$pLAI'V_VFn^l;3fDi %I4eg!_:?KI:mvW6BtJ~?Ӂ?ETMCTMVH\𷈖Q >P0t s%I)zcZY*KW]IE w CZKDЛ<"c߯]"I0P DnY!G=T& ;Dl%I4\b5@ڕ$vZ|h0괩5s xCAI+sj2 mzgb;X!8D}Z`gZwfK$iR{]"W[vdK!IrSM#ۀ;ʐ뉪apHJFČ]D;SQ-TYүUzԁ[D0X0׻ Z&I$MS A60/J̎ZBY]vK" -nܓ^j~aTC3yɮ$IٓA䰲WB4զ"OT~  ZTVqs$*zn3t瓹|^Oy+OD5ئy Zޚޟ,tI$I4٪Tֹ Sod Ij ff7> \CwK BIy bශJ뱓 Gi J]M0+ǁ\I$MFU(;]Jd ,V'!^ZQg^b"~.Q2ND 8rǀO9vX!8z{hU :X$I&Y*SU$Mk$?2b3m!xq3;OxHrq[҅ Z;mt< Fa6U9%I74lS+!I*Q5hu?p;q}Vu,!\#BI:*nn[Df2'uon`& ~R[$I.s`1Uɾ2HDsYgW&?OIӟֹff-lA~Co7TK9Qih /D@Xjv|CeuV [I$MUPLu 2Q`> ;D.yAޛlb&9a\IUf"7J.y0Q!BZå'Z?rI$I4Ə]²ZP4e{_%ˈ H{u`"^č_$ůt|_t}F$Iid㎞l߅(T-#WB4ٺ&ߛM D0T3, 1oFʬ:f A .M_CX!Iz_ ڿBg(I_*Z_urAI; IDAT1;Nk9@K]D{EϺkI+ V+9sG7Kx4(:&/$I4YOU'~eW+!IL,"6d*92 %d!U6krx9DPΓmD\!~xX D!!XczmD!H$iB{*[N z{^4ic`FT]OS9TreJ!#*7 KTzc$IUʓB ~oJH&x7DĆ/`4h!,TLYzX|hy",#-C``nD >E$IzV;We2H&ڕNKӉ %D ,&&*24p |x GT!X!} x\|8 %OKg6U3sg#9xԥ$IhV*+Qybh؛P%I2ƿ ~4#1Gp!0xh/Dg:^jh o$IU+ %44+߼B4^wWZ3qSK500:S?p3~Pslj@9[a"=dtQY;ID 82I$R*R_6/ %IbTv"\>2mLJq*y{3. $'D4 եP+99p2GQ$Id _:tdk!_ZHԥ7WmC$6gt:׻S"OIh)0|S@!1Cg;D hx+y9b{G'jL$I:/o`(XJ+ר.5\N[,:Dk٪K! p>p1/"(y$ xxX @PW \ WDkcX*I46z.XBV*9?w-$IJݳRCոQ,IEМwO&" <9X :XzM#nZH}J}x%IɁö-j㉌ uPZN"%IjOU" 杕px| M+kT>aD[Ѿ O]2I$7Ue`֗!Iӈٻ\2]D<7?28h]9 d2+`J4o=LO`PP$I6oߚ %Ag JbVߵ\|4:qog?1kN5?G }+{t< fJ$og);Uj* Jb[Mրbsx, GA՞F׍W/@}74l~s~.l;!EWz^n&B1j((I$]$n4G=>IH$U+50.;yo ;@tP9KpUǚlj뀧e{#X]r#Z JB:sׁ/4:(ρҹ@xҥՈ^xz&IqZC#nwѲZ,3WD*{~^np51W}"|!̻*!-Q&U%qk.4if>GT *M'X9-B7cm]:ǐ$I.IԿJbR5UHR9`6qѢ"T m D%z5Pp7Q!x9\4b#׀z'ﻀ7爹n1嫧;p]zo E" ܛNcM$Ie_ :3Ua!IsJ>`9Qyq'y=CTvB /Z]C2 *M^W!Z>/8mDDXA}DuD|,$I4iéWCc`^Yk 'c JRyq\!Z̤A*Z i 6mUiy^ mȁD3D qÂέB 4g 5Qؔ^67ěa$I4E*Rk`(˹^ppPJWYD(lFkD( uK!Mׁ?%.oO/.YX~cNTogbf)G$IS`wqT˞5 2TZhI*2`>pQɆQ/?#J]iNCe"O+id|.DҐ0w4 ̡8zt\@ qy$I.*ds4@+k `c]=$Cʺx0kټ+ة'};,W^CDu~hYCazb'(42:*fQ6B37'%/c^Aρ'}$I l#WA%ufK2Ua"IH ,LZ kZ3|h-I$uՂz߶gSPݳ)6n7' J#K-@Atz֨hgAkCoa6>W*#*gS*Z:6O$IzQG:5u`>m2` Uzjʉ]NTDQ$]>~වo` xD|o 8>D29^_2I$IPmWA$mt(8h]7vro*Bm{&Bx{thDuu}DՖB=IT \'X-{M/$IR1v1C5BC燂ӯz0Q*0X r6jD5bu1#άغO6FD< N"Q-x0DQ-1vhC@$I`$IJ*&6OuS h׉*׈PC2Ҙ4g~=[D4DT}_3'\ C=X-fWNꄫ6Ҟm2O8r2% p-1gϳz] "šD&|Z)\#(IWNCWCf7KBRо$G _?,2->$** #f^n xz:G>5;:pMEU#.I^?$GO0شK3qn"$*#9D:Vuf;hV6mOI_jG:Jz.O'Z1~Q5%:H:oUѲk&Q^P.t+vz$IJco$GNYᏥ9t[wlHBl|5q*hQ7Q s!vFD37{wW׀3LyDй~ B+Q%ITjoC$k\ IXt yG~&K=KT>ݶ'|ұ,}"Zn!*T%I$`*֩Ր$\]Yog9u"lv`9Q0 I_;Np- @Ab5Et,A/]l x\3 ѯ 6SJTH>um3qC)$IRK2N+] IʣUb#DKK3vaD8dP0'B;O!6KHd>Q;WYyn{ive*ŭj=^_ߢU/I$ijj v$[!jD+Μh٠U%8BV6>:i>W6&fy'DjpT"oN_qy>cyiBtks tA$IYj vgdՐ$*A pAY'ީ~ywzĆ"bS%B<^lUz?&fD{uvt~]G_!څF\Ϝr"XKT $n>Q{^c5t J$I罈 X{%IRua-Xly;D"i.NHl Q'w}@;F}f'0.Nچ߹ *t" vp1۳9SgkD5DE;D6"f \Q)8$I4=K$IU͝ZCc) IDAT'Jh:.6"81 O-D)(I$]Z$x:>f- %]H\ <N<@N듻4cQ#^l*I$] JTCÿϺM{0lJET ?I"bUJZՁ =D6Q!+o ;|`q#MQf׀>T$I'j; JTbcNl'?ӰGҹDr uF;/hzVgO^X'SD0q*I$ $C"AT ~JZHpwՁˉ 0†DuS&" "s-HCM$I8wU-WCJаP9vΨl5LRUӹ`Q5N $uLU'ہW灵vzNt#fj(c=Ղ$IIU߭S!IR 9D%b#[RyՁwp$I41r#r5$IٳxtpRp?X*ČAM7 T0 ykUh !L=O8?vI$i"![k0(I呍 vF{ {Ji(RE  X]W?svEa`+X>vՁ ׀<+=|DTJ$Iȋ-; ,N/$\խ(MLN1h6+#Zˀr"*s.|ݖ>&ڃF }ؕy Ոֺ36 XD'D8(I$i"/w< AI:4.nQ4 :K =D~`N|EGTz,FZ-u4`v$I&B}$E/qװoPp8Al ?ky\Ӂ"J?fPzi0< IT wDs^`"Q'IT^Oڭ&*]1$I&$Csd;T֍sG'DѣO7Qp=1Sl#Rn~xVu ƅvQ#Z*B'\š KbW#t^I$ J9Folj`!1OV"ȔTk `p(-<_Ulz19QAW'Db_gKjkK<9E܏$I45)$:xH65:'i[D\ HK Q!]1k5ு>&nPq_ץu%x]<|uI$ISu1o0(I?ٛ9qZ:hC:C1#"ĸ#* /M)_'Ne^Dmg MV J$ISyQb+QI**\7>_(AGMq7C}Dkҋs/M3 9J& ".]B3'iU<$Ig0(IRulbUCwP(Iv0xh11cjA}Uy'f\,"fv*ODUO*|>ep5pp;1Ki>J]|͗$ID+\rE$swܓ qPpLM8HT^zp( &t̯^"yxeiys#:Jj8ߕ޳X +I$l=*ٛ ׻1:':K!R[z>e/J$IꔋbBVṺ@7~Z`IUI_"*~|4*D x5NE8^\c7BаJFTNUG}uϕڗ=$INR_ԿZH4ugɝ/"HM ۄ^:}Lp~}j{%*GUD`چ$j$Z$I X: Au"-z.Dt]ϏKe8gLjy\'SҥlBi J+|%k/ Tx 1KZu8Fݓ~m ]I$@?7ؚ .KW"4;bRYW?q楆أfj4%Dqeb D̶c;p^% C%څޞ>Uu2S* b6:2[KLjZn|!s%I< ,ΨEN WD&G,kiD(x92/X1K 9ߋB[ BTxhhn~NH&zz|$IR)4ޞB %\} 񵋅5bbhy֢;Jk0x9JRQUoQx5pQt3D4+Ux9A[Mty~_&Z9V9}+$I_ ׁ{};>g ݨ;%R,$i+t&Rg򤝩u2/p2>w&?HQnuǖRl]-ԅ"Hx{N|G@^ޯpߞ ~s -a"I+řZ`+Vf!A6Ĭ{ 򇉋MR[9Q …;ЮUc ^ Z u;-D?KﰟtNyH$ICYV#٢$Iy?W_!BoD7/k{YFgzEZ{iuDv`ju]cUiN ?6 ϛ'±D $#+~;p1wmW?!mhEXUĮ#Z63?/Om+9i %I$]$uGYdۼ 3x D1[DQc#K n'*}> .Jzب۪2bD߇zhj+z${WgAIK?aI`$It} x]g ]F[J & 2 bkrQj;KS tܮ'*-hW} TGL_{*ucV$I 9[ϖqOt e\kր/`h*Qmg`*dCA,oU? ^Zhq!־_K/7mBG:pt/,MGHOJ:vH$IZ\s7o|])@K 0u"Nύ\6"ph/:| \yZyY:_D{Їh]I`OkDE#]_\zx%I$uAsICwE.UNL5݈>V#Ӣ/,Q-p iATf!Qx Q1ViesLoۈ܀π/O*%uPP$IRd[6 MlgAC[JR^{B]N(8KTƌ`(uQ5xQ1x+Qp!*/e{Q-EN7ߍ6%CDk Py&'G Lz|8F$I;Ud[R]4j7L  "!.OTՆdY[ 8DպEZ"h@h  BuZt>G -p?% IꪣDKsL$IҊj/ˉogAid{vqd[w#9/w/t5m9`&$hgxzy0%6gQ9 ?!ډ~D;<˳H1T#ۀ;^"ې޾+KǝAHT$Vp9M$IҪ6o#Fl+'wԷ|O[~H\4g sؓpI>!5G~V:giN2֥#fE%j'j0ď6iA׈ہ;%hoݗ#B*_|Pi5"#qQ$Iz.iy9kgA7tFmsW7B`xxѭ{"0rp/^z}vQ<;Yiݒ."Q!x8ݿG: t¶$IBg@؞AX<dWA1yҪvυEhbΣu+%fQ!p߁iD-f)DiEp&.m]SU`#ݦ35oID(x13pQ8u{;ιCDڭ =ߤ1G[>Hc U`h܅?^Rۭ*y3c(x-7w6{iMmFǀ[jHTA^VaJ֊||<*wWl: sxKD$IR?&C_F wHCp<}~>ϪS{0TE#7e6/j7 튳"ʲ" Yp}V!Ɖ7̸G*sD}GzvFAxgkP}DK)"h?б!<&{(I$itT> hV!4d/uT-SlFl\J> OiK"]ci*);^}\Am|yHw{ vQ5+b~"1+McJkI< Rp-$I4fZ('w6N}?/aNvddB)Ǯlnv爀D%#CDܛ⺌j-G7Jr ^$/$}>$1NҮ&l?b ~ ow|Uwp3ݜkZޏ3Eo:M)*'HJ$I$ihJB|z_=gCYdj?ǹwI|?\eQ{KۡE^"i˽DfU6u"V6i<J?N_f~iXw%=F_l Ko"Ehz󠞾N{խS}-bEǒVW|f0$I+6ol; hVZ6¡:"Ry߁Hc#c~"7J?<[Dghń ]=OTnK4Q1B(e"T|U~UU;D[iS&Q= %I$iyfZM~:ª0{,/цӦ!{ #) U#*R_;`Q30DŽ+}hg&BPv2Y8\GܼRhةť3WgR%_ _Io?%73ʤ^4#|H$IRTQ /Rݳ|hP>@2\Qn)a;ص[b>h ]/v_ kQ[PI̯m'ˁp|TIDATmW}SjgP Q +7Rx)VJ$IJATŽO)'wd|e/5!>VQ|tG[ӛlr9~] _P$ZO%IV]\5o"I˼o) sD׀C%91]l*I$I=3j]ZiU0U!^R+}IAJbgEJN +/{u߮}R{0"jdsĜyp_3$i1U#څ O,>H=I`"'I$I0 kmL{͞Z,zRp`z-+;}FT^"Z~H+5RR8EtGT^tk$I$IֆG{v[vWZ$I$i"Ю$Z@#y~!Z N'LO@J">^Ӟג$I$Ikܑmٴ՝׺+3>fg J+1EG=40[lj ! %I$IzB}˗]L_[~ޒ#vvKM) DK7鼯fH:=qI$IѲu@aOSﱟ ^}p;Р]E([2h? &1CH:% #5[X,I$I3ʉFy(r!}WP{8^#ڈ0QǁDu~, x[D`I$I$|?sK9/{g/g;1 zmS1Jh2t[$I$IzCSy5;8GT%揽|x ȼy Z~L:J3iY( Y&X$I$:te{S|Z3ąƓ)㷈wzKE\!Nn4T -Bu.µK$I$i5:td0[gW?#Z ]1V,1s_&.$*gӹ*ix̧t` (I$Icl:rس ąψEu"8ׁ *?|uhh #+3H$I$0x " |8L3p30 ԈpPTa`.Q"D0EQ' w[$I$IzSAi4Ƙ&^$BmV@c~Oi?XGЦp+ |c5ك|:G:Ώ #D[k$ 2$3n$I$IRo￸ lAwdx8@T4l6wh+* 2UG?%By@I^^$چκ%$I$IE#wa0eyy`C9 ^H/lj :x*pp+D%)b>q"$j'B‹xq_ҕ] 83"I$I9ۛ݉4`mٴcaHd=su6^Ic@~R}-IϜ"BI$I$Fٹ'܈S-%0 EZD 2bbu'^ՃZYsDtt,)"lh/e!Oo_ǖZY%Q:MTx 8%tV$uq,G 2$I$I*0;NWV,M"tHTl>"ڨ}l%*on Bیj)ZDXUSϰ*PRZ+[D$I$IR?Jpe0 vS51_p5`sZmEkiЮ().[-.%B)0Q6Ѳx:nPuhK<0NT J$I$_X%8$[> سԁbפ*[vww_!*o!B{hWޒhMFmNUe3&Qw~N׫ҪBz [IZp 3t%I$I>R,N rٹn[TZDb[ho7a׉_'[Ҿm)OL [WJZM-bnO!$I$ILEwaH-`wUANU)v᲏gD`#vJ»0p=Qeؠݎt$}DҪhm_U[vܾuAtJT#s~z~E }5CēlW,I$Igjd;[݉a=PpuDYǁߥD э ۉp+f7\ոݪ-bYQQqS}] t}ē$I$I3T#ۼwb8~C5M%.Wkq~>>OF{INo ű$I$IP=g{(p'lƥ+n]iV5nvwCZ7vܶwaj&zpCXF@QPHWs&q=WlZ%'3~DT θ5$I$IY0<26o[ Ea׺{ V&h v[|1ұs; u[9"]Wh}c_~|< 8@$I$IC%zwbϳޡ DX5=f !5h*\(іt]VlZm^}A|,8I~ p[t{$I$IW`0|ǧ&3O ue iIzoC -$I$IͶz/  J4ZD;qb1bn$I$IXxi!y$I`(J"ڇN$I$IR*'wϸéw=_o$IE{ κ5$I$I/rl:ǯ %I O׀=i}D$I$IRȟ*)u'–PPph `m$I$I1G;1ju~g J."9C$I$IZ{ZY1ܚa((IR*&2}j@I$I$rbܔ;1-޼obPI px8I$Imzwbȏ]0$D8 ̻=$I$I"jyw.3$ĬDs]"l=$I$I!#x@x7$IE~-C 3%I$I4 jd;[?t'2$5jaGDՠ$I$ID=g{(q'TeWZ$Ilh: NХI$I$iE >wBv$( p>v$I$I֡`((IRiogI$I3ڨ5g l $ļW)bB%I$IH9>#۲g0֡`((IR9F mDg0$I$I8 )\nrK.OI$I$I$gjfn~m$I$I$IZ ƺ$I$I$IҪ0b~.H$I$I$Ntʉg$I$I$IRȟ°˵$I$I$I3v9WX$I$I$I vCEYo$I$I$ISONj)jd.H$I$I$t-qS I$I$IW$[e>>)(I$I$Itݲ]P>>hYFufZ+O8SP$I$I$i0eϯt V J$I$I$-K=g{E`866 c$I$I$IeO5 a :[@P$I$I$IKPOl7P\׻9Wص}$I$I$I"d9`uqJlz̻I$I$I4jԞl;V,8S?7$I$I$Ig ͂}-Z 7;!I$I$Iў1ۅ*]3Gpg$I$I$IRvb9;zq$I$I$I Knǎo6 ϗ{I$I$I^WNL52S55jˁ$I$I$IRKBO`{JW~8l*I$I$Izh2P+c>T$I$I$U(sMA JAI$I$IC˂gzH@ %I$I$IR/mԘG $I$I$ieO1;4T.'}𺷝$I$I$IZ ͂K [Lm8VH$I$I$]C9>]@r:mr$I$I$IZ55-g !x9g J$I$IUӜ8,?F"%I$I$IL91ըQ{2؞s+Y*I$I$IE F %I$I$I[U=pʵ6.DI$I$IURnkQj)#^$I$I$iv{K$I$I$ rb?AUOydK$I$I$ "̞PW=gG$I$I$InQllNm'I$I$I$-V1ls~$I$I$I[=g{0|s~$I$I$I` lȔ$I$I$IRFrb(I$I$Ie86FӣO$I$I$Ippڅ2ڨyI$I$I$i|lw]_a$I$I$I`=$I$I$Iԛ seH$I$I$I}ZF}Kh?#I$I$ISNL5 NlFI$I$I$^].I$I$I$ v9{DH$I$I$i` w8.'wxH$I$I$ihv'@0$I$I$Ipp@I$I$I$s@I$I$I$i8:P$I$I$IZF ]O x"yN$I$I$IZrb?E$I$I$Itjd;{h+*%I$I$I$uU=gZ@ $I$I$IVT91ըQ{8* t%I$I$I5Pِ= UJ$I$I$I=;a6$I$I$IR0*,*d9>_[ I$I$I4ʉȖwEX irWq`LeӛTٳUrB;IENDB`sphinxcontrib-django-2.5/docs/images/django-sphinx-logo-blue.png000066400000000000000000002177471450461522200250740ustar00rootroot00000000000000PNG  IHDR^AzTXtRaw profile type exifxڭVi& )rkqRyRT#ZICZsR+kZaӡ;ʭOg=x*k%%5ɐ{8Q/$< mކ ZG^pK/KI0_ 0O!9гď4LzlBnߞpz{*geCt=z񀓬"8Rh/ec(f`$# 5jj&f[%ksQ[Xɥ/4W7^ܽz\Ejz5`awÂN>ҙrY>]K^{IjRPGuƛ|ĊHpo$ZriCCPICC profilex}=H@_S;(d.Zq*BZu0 4$).kŪ "%/-=B4mtLĢb**^хz1!YƜ$9]gyst>xMA 'bKGD pHYs  tIME 6jt IDATxˏWodL23y'E=Rb4pL3s  Ph7EƬfӳƫaYUQ.1{UJw~%sN/HɌ7 "_F<$I$I$Io̼O=//ٿH=$I$I$}w^[D0|OwPP$I$ImGA42l4/ k$I$I$IMo=HHڭ %I$I$IW= v3CAI$I$I^GAnf((I$I$I$՜$I$I$ITs$I$I$IR J$I$I$I5g((I$I$I$՜$I$I$ITs$I$I$IR J$I$I$I5g((I$I$I$՜$I$I$ITs$I$I$IR J$I$I$I5g((I$I$I$՜$I$I$ITs$I$I$IR J$I$I$I5g((I$I$I$՜$I$I$ITs$I$I$IR J$I$I$I5g((I$I$I$՜$I$I$ITs$I$I$IR J$I$I$I5g((I$I$I$՜$I$I$ITs$I$I$IR J$I$I$I5g((I$I$I$՜$I$I$ITs$I$I$IR J$I$I$I5g((I$I$I$՜$I$I$ITs$I$I$IR J$I$I$I5g((I$I$I$՜$I$I$ITs$I$I$IR J$I$I$I5g((I$I$I$՜$I$I$ITs$I$I$IR J$I$I$I5g((I$I$I$՜$I$I$ITs$I$I$IR J$I$I$I5g((I$I$I$՜$I$I$ITs$I$I$IR J$I$I$I5g((I$I$I$՜$I$I$ITs$I$I$IR J$I$I$I5g((I$I$I$՜$I$I$ITs$I$I$IR J$I$I$I5g((I$I$I$՜$I$I$ITs$I$I$IR J$I$I$I5g((I$I$I$՜$I$I$ITs$I$I$IR J$I$I$I5g((I$I$I$՜$I$I$ITs$I$I$IR J$I$I$I5g((I$I$I$՜$I$I$ITs$I$I$IR J$I$I$I5g((I$I$I$՜$I$I$ITs$I$I$IR J$I$I$I5g((I$I$I$՜$I$I$ITs$I$I$IR J$I$I$I5g((I$I$I$՜$I$I$ITs$I$I$IR J$I$I$I5g((I$I$I$՜$I$I$ITs$I$I$IR z$i紊vh>qS7u #Q"^&\%%" L"OJI$I$IߩT^& "1Ph]nS8L|D+)" b((}K$RVM1ITJ㇉cDv@y@K~De}zh_O+s욇V$I$Iڽ o/0fU7 ab]vFN0ìaGC"( EٞT$I$I] *D5Q)ʶLjCĂznjhm'D1ʸ*W{!$I$I J 0\9%banoԣ'iMU3SK"$*y\1pJ$I$I;PPzPO{kODQ13Fh8qHO%|B_I$I$I;PP{V*p?OQ =KcDph[PI0L1L v} i>* @$jT$I$Iz2 6*WjC{Qh9(GDwh)zh5[t^PP$I$Iz gvh9 #q<!y$['P c~p*͹b/Jh_n s=$I$I= U("tިN/'[^X[~NiyEV+owU7sz@2z$I$IdD&*lj#&J1@=?!ډ&Z.׈2ъtUu$I$I WR5֖tiL' 54 (IAGҘ'*Wo|| |BT[EnzJ]%I$I 4!`| xhzljI,2R.871,#{8q9/7/+m0(I$I$U jj"Hc:&,QYr JBIRjPA8L:]9bDpu]J$I$i/3n}'{'8DDp8UW4*a4>!/7ZE{AI$I$ez># I ph z<.X(I{jjw0}~\o-ph59Wv=$I$I;CAQ]=@~ ? M!$=J?+&FWO93 *ګDK$I$I#CAJE$`{2̋G `e!$[hϝ#s8C:ph1:\n뭢ݱzP$I$Iuc(m*M"{=  6 Z^#:H,6=mРܟv?p="|x" +J$I$_ j۴M G=O1Q}#%&(Ig$:2Q1xLT~.oH%I$Ic(oUG*b;"ZM'J&qr^t3u.0$#LTjNz|W "$I$Inf(oc&=_^Qc ¿Fl.InN OTwAT. |A4$I$I]PP*9 ¿3DDE!vM$юJ/[.K#ϷIb/@T^>okDћDaAI$I${1D̗#) {DUQpא$iȟD0x< G-GWZE{hI!ړbP(I$I@gKDjJ<`5HM$i *{'BDK(C\EmF%I$I $/D~b!sh#}CTQU?>C{igDo/+VѾ  slùc߉\1ё$I$Iuf(0ph"')pzN3)&$}Y9>w'/Aᯈ* `(s׃tm%I$IjPfRE`^:@&Gi?L5/IFys4pxD*wD;DPP#}ϝD86w1$I$I5g(X#)b9 'v @I\h&H3x p0ݿD#7>$*]N'Lߗ=I$ITg}$-r'p?.V8te3s h(<<@ `lY&.*D+W}}oyl8aIM$Kq(`Q18OTޠ ^szͿ R@Im:nyi⤧f<~f$CrIYdhs/QI$ITGH xp?-׏ǁg֟Ů v`ho}=b~r_X}h_C;1k j8ҜR5N,#1JYu<@YSϖ5n8RzE~2]o4lh=RS)vinSU9ʜ5R|BOm9~nX .P y*ZZ9m(#4S  6*&ɭJ yMA2Xqb ^!N6ȡ 㫭R<^ps擔yx}ޣ 0|eȝƿm JI$I'PpUڃ6}g#Qy[]Uۈ6+Åsi*K,*~3=Ѿ. nz >[=O ]T^~j&} ms$I$IRm ~Go(r;+8'+#/W$}{N喟+֞D9Q 8O_\1~s)Dczsg_l+RO~ x =[m}_z4^^& %I$IR ~ p #3{NR%r-}7="[#5"Z&**Q s|˕y\>Q=; *ĉ#DQ*ĉ\{(ͧyNvN]CVѾ$I$N U\=F([ٍqrD@[i[jIz<=}zDxB('|W.<.Χokt=b.'NOsDabX=H"QYA+i$I$I{ZQ3Ii"O,9$%=ҶUw"!&-@fE2>DKPہ5"7IQA8I=} IDATV=H=dG^ ZK>?$I$IޞR׬abAy$yqXP>H'}QNӖu㫶!*u"[M]%ڀn럤_:@תH:Te^ N8Gi$c*s0q"H޳P5eFhoFT$I$^dl9J,"o2;IT'/)7%¾IY={JoϞ#*ҭ4$I$I}C_0E,jؾt{W~f;HYQbKT& &]b.A`u5z[?#3O,} 9 K׏$N y Ğѯqҁ$I$IR_۵`ZhT#m?OljEsKB{XuQW^CYɷJ}Du

-@@fCY Jj)=EzFykʽ '爠pYc0(AR I$ip{vf?6tiT'ZyZE!4w@l'_@ןh;%wΨTe(C8D ؚDK7Ścr?ee6#*7e"D{.VƗi\$BгIjϗ#D xhSÔskʊBI61?vI$O{: /[M~ ݛ{}ַ{k/~ܡ/\_Au9< G,,J$I}7wՅ˽ne߃_/ތgGtӟWos'JnAboqX0-rk&:Ҏ|3CRVΧDT]#‘D8x%`sj#ڛ8a>1exh5:ATNSk;>(${ )b0$IR?ng)9`/ ޛ=x? xGc 1{?{mؖNGVin]"iMC7O xzhvV4~mҊ@slU{f zFvǀD^ϤG|vFzO^'/{X$IYxa,+:ۦ3Лn2@4(/v}0Q!1wD%]%Dx7]NO\B<6ZE{m/8F̞N qf8K^$Iz*zsx.Lm)3z "?y ({"i7HF.DE:-boUu+^h?9W=OrԇiP#WZ̯?ev|LV{:"*'=^!^G (mV^G:ާ=t|$IҎHm@Sl( %i2'~D5"O D=ʊ{>dl_щ*h(Ú1k"]Ϗ lEn=yHG[ bz}@"U&k4WZE;K lf~LD?NT&!$ kDΙ&m^$IVm6$mCAO'R,{-^ny.oqہvO! q"(GyV J}bTGqFnzaHYu*r^m?yp*s,W>n ;Nn og!1D1y˛)JG\1[ʜJ!տ{ _%ãIPQ]zσok/[E `dI$=?ku֥󓙷/眤ۉWmom .J}0!M"˃mV*$*6I"m^&4?9k϶q$ɇ|U_itp7D\mz/P]`Kzh ڎ~@YA8Egs Y/}w:N-%IYx;d:Jwo̼޿ޛ_ܝzӷBUR>r+D0ց=zU)+Ɖo?MǪpe+j` ܆rn:ÔkJ=LQxQQ8ODb [Us tπw} Q#CjT6ߛ/CH$jd9ퟗAmA%Gsnoz$t)+GD5r3R}Ô{IMLYwhoL?w,rarH5FUCU"OwVXl[˹ڷF-.W޷Cx|ITN!"ٗ.=8 o[Eb5$IR}.W=3$ՄR 'XV9Uz%4Q] Qm4<DY%xpVm?:ϡ"~GT^R*ڝ4Я&u8iC繵a" c{8[_ĉ?$I5 3o_GCT773",JYUt ՚D7A,$B\O(W9h7JQEaqBz_Ks|h!7jvLrhx\."=FUg5~8f<$IR-B7̸W$\-Wn}" 89 b/T =s;sX?ơt'!", ̤막 UR :[ݟtJ CA)r% ȝۀ^'O*b*5hX9.ljCĢtD=N,["ݹ M.DUj'*< ^nGQʓ~t??H$N9 y띿hH"CA)M* qD{ω:.7JJQbq,Q*oX?NRI"6P>~:E- _U7nVѦUe"⧔'Os+DїDP8\>5F 1Q1l((IJ չ:&qF}b:^!/ s~Q7JT B 8,=6ETHϑժy~==8 GT Ò$I%^+?y띿HHd(U.[.;~_w@pe%hO:kP qQx9C {tOUD8>]'BesYr߮.Lm7{ k\q|8 U'h`|fvf}*sl"ItVz١㞁$%N,>"¿[}e-2n­=ǣDE_O, GTNcaPI I'*nyj!]in[ *6>w|=OTo/'j2Op~A,"M")}`P$8.{a$I[ _ʿu"["X {D%L$o8@#:<ֻ ~pH >ȽFnyX|o~ v ՖEee4VJuQ""$* _IaRKTkh 0q|~JSI9 !-/'q">'H$׊_xwHHx m_ \> *cD%* }xhG0C,z`x i}Os߫̉Ӽy\EW/-aM]t87׉'<) "nv_*u%Iwb@[J  j7ȕ!+De˽ty9+i\K/ wvm-{ aqbĢtA=Qu[۶0Dq"([$kpUQ[.ore/ΖtrKQM}4]Cx2P~xܽa$I>Uf#$Iߜv`%p7ʖek}eiѺP^~@T ڇ!Dĉw}~MT[_K/K͹bJ[VўKĊSD`+ͯT4}H@zO9CAIm2?IBx4$Iv\N *9n _g$¿DU\?" b9ph1v$]"<@?%m\(<4_OgD˭}ݹb*ڛĉ&+ JDPx8g[8=?pH$}7o̼޿u{oz4$In D_\Icn)WED[sؤG|Vv 'YE/jGD)eh'f9|1]tr\ =/Q"|؇t>4k>MhRy+IۼV3o_x#!IpKO&Q x/W|FO,FR}&*D˺D%34g4ODH4n'p\'Nh| *}k \K5D$K 牓7R7t ~I$IcJ{Ձ$m'CA}dr3`-EoiJ]+f7/L~]yߠL&D08(iU#i-W0c!D5"$*\E>6n?S8e17)W0()ʪ4t|b(^CAIށ$=9DEb`%Q x!.Ȝ/j= @T>A`zN/\#_~'z\&?n__VZE{bvUg{G`_% t }4@t q"If_n' I CA=L"pXE7j[Y=bAu JǕ"*Cqh57\$*m%=di"NXJ~>'.vATƿh /sIhwj›wh.qGL QAwE"ؗK$髌 7[?=%Iz -"h̭Aski|\Z6{"{9bV`E`|%Ei{gjxh7z/}}d;ۛ0y:D D[?7FJ:L\h;u*MmuWD|9W^I$}׊_C-$IOޖ .QTA$4=JTLmA %bq"SY׉O&|7|/~AyUPuj.I$Y#!I35b!2WU7wE;ęݹbv$UmӔ*bv5$i{+lQm9M*wWn:G]k9ffffhW q ^D@UZ}>2 mNrZv\ =_^ }n{4j\ uRp>_RNl]ՁWAER \5=K['I4!&O`:eꯇ|]^TEz`<݋|8-h2o73ڌmGP0x x+yfqLkbt>h3 wt}ӹ<(m MNu Z\hfbajOȫnyp ;P3rMF˗~UKnB`Źog|(C`oR;t#ĵUj[IΠv)$Lk z}@33368;ZCSCQi*Uͣ 4qBԶ*}SFM^E@6&?P0Ф ^̬W$,Z:y+qMr&[hcl:791F`Af<܂~B8D~ =CĵFJ_tn o:j!^;>x:̬}|ZG̬8\= tMTpMV݌M; NzPis+^dZ+qm®;mU jPu>ΛDΙk擦 rsqm54uWfff͡Ki.=.NkͷJg2U2GsD V33G|H s пNVYy6-&E97pv{#߇Or3BE}k34緰Y{r hff ~扶%4iuUds t{~װIAB1+j>`AmͶ>&4Aiff8/w.\||PBdFlw ;sq^$Rt}t귩Y{r hff (KḳI{i4Ivs¿(,\'?N1+Q}PxqMnmjMMgQui$jYy*} T;wt-oA33P07o;2Z&oU΢~.\&ڐmB!p[843BC((Tӵ8³543333ÁYP0W%o9zSemo"]`T'>7Jo+ bvkbpClfpH{}1nfI7 q SFoWYp3d|m̖uoWҷ*Y]wNG̬E(&1=_R_-&EOw揣ǁKnu_ {=(¿Tؼ>K:7rfMWPSkR[QJhx w{f ^(0م(`׽e-l ޫ;]%pNoFU=~zpcRu! V@uլt"HFj;~;c WlwAWZJ-@qUxMb&кQQe~RppMDkvɻظMoVIc@l{O10Uʷy=k^sYMR=]3uц8u1+U߻Q033}URJ-}fl|2 90phaJg/sMuTwYlG-% N֡5׮7+Y(8L^= Q@q/jjzoe qV?@|UYx:wW\e9MZҭmwOxyZj9\NT-rKBBVF+;O?~ObVClFk}" 5Go{Qg2{@\ )f広A33338k4^Hu.ʑ^$lBwGmFض*!41,~,p6>cCN-фi#]P5vg?qڦxڄPh~XӶUCm"_aNvO9j̺wҠrx#affٺ2,fަ:4 M$w*!Z^ϓ7&;Z)4z UF LTLRpS;OoCPJVǾo:<ֆ-j!) 9Zfաnǡu< fff[!Teҋ½ⱀZ=߳U6'{U$gZ2j:Q| l+fە4a133n㶡fffݥS*{$k?y-shrv]ttIVURw8A`4mgo'o]}s-8~<{H̬[4N]}ۆuլ܌&@OdLK{/$ [s`'.L!'QQU%<+3lqm=Qľ[mUTҧ57gIT=8___-MRuV덗<fffg5'7@wEaF NLNZg{A`fŬ\GaDx3*'P0'6 ,jmfffֱu~Q033N oCo])݌jZCUw; Ofs84 n%TŴOvw@c3^CQ>wGM9̬c~5# 33zf+'!v 9ZתXo쓹/'p(MZ'Z$W(؈q~'š٣*S)u/NzUYr(h ը<LP?ہ9T* v>W} p{YK/QTCF[c/*fct%+-zX̬z/< fff͡٣iO‰ۨjpSVl_WuJVj2q_~c;<lA-H ݭ'G/3333Pܹ+/كr(hvUT!j|BU'ci PuRZt: v-8,6nNף`q "|݊ZCwWuBo%̬}|Zo0333fB[h 1T-0p'P%40'[5k}$i( | ?d|ی:nbߙK̬s|ۣ`fffPк[&߻ZDL< :RcZ=$wc(f@?Z j{ ;b6QTGԺ ?5Y[}: 333QE ތ :ik8 lMTU~F vy9`\EQ '(<MvtW?P'wYy|333kW:z}?@7Gp(hݢNNjz5I,}~ M.kvYdF [G^B%F bV^}%U؞BmEw{1UnkZ[ZQ@ ffffmH?pHb-p=?g 8v̞e'zF—gFE`xM3^QT0¿wP1TEvdY[ǙG-ߪbs( UR1ğVFx< l@8 4Z̬hk1(m/BO'Ǿzd_3{Ku5MrՁjG)6hB%df Z뎝.n 4 aHQ,zα\BU}W Fk$P8pUy _̬mJX?屯7,̵W|rb\Uhfơ\BU)DU>Y",U 7uBaCαn"*Yi1y{aTi, JRkŭRaWZ IDATrPdځm^+4WL4#WkG&4vPVa|&bYB$ф0Bg=0CN'WA%+ՋYy2׀_מ"܋ۊZg |xXs̬}|ZU 4ű=*Uܵk@kQQ<$+ ͬ8V@n(ԻyMWBUpU.6o[QPa}l@/kJUkVbVtڋ>ͨp{(HZY'Pq1333ki:(r+ :AG'$*>}#uT-6QZL%+͡0Vz{ziT18?a`jJBkEہ"{}]bfff-kpFkLWu q4mwP0x UYTm7$P|5B]uF/ga!rUe/4y fd|K\,yX̬450{wffֹ r)MS4 U'l-5.[!K[Z@7܈mCZމbV֣J^G @?㑴5>ޗOv:ZEՁW䑰U['/03mYAQO':7Q5$jڇ-: o8lW3TQ PZs= p = 43.QTQTuKT%8]JUJbV ȴfە:dߌmg1`7 7umuP0 ]W+Y133VѠ =?Wy@3PS '1ԞzZ-Ws5p:Ls@1+C Ϡ{?ҋWQہbVyc333kG_)HqP33s(h$3ju U yZ$ {v7֧};3oPf؏SHh͛ &l|ۣ`#|Caf ø&gov -K\5Z,`=&rP].JRJ5T=x/ƹx<cq%-^ >\Do23338ЍsfU'O 33phAc3Ŭ\ښdF1+&q05Tlݹ2 AGQ%W?myaɫX4333[OG͚.`{O{$,q(hc;MϢ pMNuvR;14a6LT|>-V[n٪P2 iTeԃCV@׀G틧=,ݽǹgQʅ <<JZ 4333[_(}ڑZ({Caff H4)60VuFt MNNT NJݨby(|8ܮdrv{bE-ZŶx_> TZ-lEN{́=C`-UqP۸P&SŬ\w0h`PǁCux Puh>/CMh?l@3fffԾQn!kqzy6q8&Yy@s)`Xd*YQUyC`mC>*fѤVwYy)WU`΃"i}KoIV=(GP <>>.QXgPw8h܍1333[1nz)|_q hff̡uT92Bi47AyPѓ]+As=3bЕI+g 8*lv싮PŬ lBku PMs6¾(k)s覆8nMpdfffb:{։H'P:H% (<ً'nt:VJQ)zo5=8\ 4.ZWty"G-@žu8a{ jRLЍ!WQxP~+YiCgfffkv֡]ݓٗ_8'PкE?>y U#T 03zjP,PPP+߉YI5s}UnC-{1lK(LN6WPH83(_ٚrT'G̖CA=mm(\vкVgP5V$X`;Ŭ|`#\-y!b U5GzPVI"pMTxgQH8T}733ֻQ:coP<ff< Z7KFvFkM7b;MIw !0xr0w/cPwW7*Y]{z`O#(3@7_\^G@7\GUu%ҋ綡ff 5 h;yEUTQuJVеTT`Y{( im4fDU`? v%hj9Uwmqݘjc333*G_) ۆjp(hzPMy* Tau+f1+OTAWjY(ȝfфx;b-ރ3h=?X%+yыPʩ jUGh?~6tΫlXq?!׀IG̬/_ vУ`ffK$VYLi xM4!\So5:|U[ u(u@>((- {ZQ{' imͱmƖ8v*+q qU^O;{\8jXPѴyѬ U HU-p0jvmD%"lpURdQh{ UaFuDMZ54Md% ]CQ#,>ǐh !`GVor-Yt#Ż2~!ffff_Jy=wkY!8XPN[>J/D#*,фZ)Ubs8²FU_DGh֌3ZG߱x0VO3@DUxn/Ztnmk%]FOs 0>g5z@Ϸ }{$lf(8 M# к0zQlFmJg-Nrmp.pWsŬt;B=.T%V;ZGPy+_WgIT*j6閦6zx+ vqb$w[V֚rU^F7\NY+YiCefff἞`{GOW jZI154MZm0ߊ&9wc/y0&BaYق~SYޜE/^FU+x?Aϣd4gYǻ#P q,܂nH5VwLʜF(0&5{g~W^E_{LlO{Cf+mjtnx )bfff`j:V= 33[M]RG'UTtUnDUvTI8Y_'<vPX0tPxU`gQx8'n?JVjr- 96!v#R%x톸Bt P;8f'Q?ߪ Y9ǁbKU]uVZYcy=zӹ%mS84333{_^t.W ZXP0&hzw)f?mFϠgPnAAzG)$tXhݨkSܫBI4i{UJd1+K-IG=6ZoRi]q|;Hܾx>RNS5C&nXDp=^-jBpXG[AQ Ƀnsݎx/<ħPu=նlj 8:KV5C`43b4q=&o ^4 Mʈh-ChҴŚ_OO(<.r(zU~WbV:\8]q谁|O M<|`5kh>㵭J 4?c+=ho> pc'z}5VkA7\ҍn1lfff UUffVZ*l&\mQUڤ wQ;xn#PFi~4jҺd}lkp:T4BڄQE8TMXJyigu)=/ۋnCx=ojcS븻 >pG ͖[=S; I`N/y#ϣi ֌YTA8LCO|GzyuV.j6_UU#FQUWɻZ-Tvzc2jBgzkUffV?kӤ[Yy3(B]huG|U^̠i_Hk#~uGbV&k=Q@ԹR;8mi}v6*> !!@[k g>.:h:^^1D^8ZR˵>PʛP>aTy 2#UeF?ޗ^NK=ff:>d%D̠vi"M x sK OxO@l~֣UT9xr|}.qףxIj[N4U 4S[Ё8y`? S5 65k%iE`U$U{?.x IDAT%VtHM#[xrF8{i 4333[˶<3{=ff<wdZT.@yGzvT58ZKiTQX (tIэ@jӨ6>ߓ* gYaY?MہX>E!x/rw_8 Z2_qL7f+YɽՁWy :L_O_z̬%IZcM%4LwR븟IVnxrdݽ?ZBBP`||Rp[x ! pU^ߘ#ogjˣ?km#!!Se`o7qsZ?FS333T0C33kV@%+ Y0PʩZeNUP@8BC֛fy n4q>xnPwXB1SP=lj%bT}ܱ*Rp>lbyT}=Mi]n^Cǁ_c@̬5hz:[Y+q(zhҿ8ތ&OjAULdyle6cQQUoRI-(8l^4U sϟI8Lqdmgj|-ıinc8]+$uMw7RXjn j:E~Ã%x :j33k%WITvbV@k]Πp'j)w(-:y8 !üZx`ffá` ik22:^C5(HUbAQplk:&/?l6hPU _jfL|}ӷ7=¸@̬T8YxfϢGZâVJ5JpO,f^ pہji@\c+<К(4Z3f7PY^ _j%x=A33k9SE딥z^Q8S(L؉ QX5ChjpCdfffzF,:AoOz̬8lCl)}O1+CU=TA8­|3j5ngff:j&먍h+Y鼇lJ [&3TJkq5kUA!ygg'(@𙙙E G)01333(;<6fff-ǡ`jjSŬ\@!a4 GkJ´V^Z?]4&pseYG^Rcx=A33kMLF1+@pklQPU6333[~5tίR̬Eң`ffȡ%U` (@kUjx܅&\hu[((4333N\~a;'<W ^8Yq(hTR :|nt#j/z8<DVTA>x_aTQ 7ctCcfff >f@tYGZCAH(fy pxZgpCxx2p# Ձi@uj ^OZCAXTE 3bVE6`?"<ڊvuQ@!ףu ]IhffݮMTxZ%+yj̬ 4/^z^(Yr(hjŬ\` 8留0 wp1xn7y^uzG+(e|<:43333kËI*H*Y)ݾYyڝC!؆QHpg|m ޏ43Nʳ M~̬K)R3O< ff֪ ڲd%49uF`/i@Ez6ffI,jw WJ=4ffffݫAcԣ!},Fhݤ_mn;BA33kwu`x+WiT5hfffffoC`ff̡JV-f~T!==kn6 B33v̡SRSKn33333kkY+s(hkڨ]noPHxx6>zp1WA3333KWp8b2 p+}g΂<3Ϧ}_^X  *JPDO0Ws64U@ 11S(TUƖW-,HJ&Kj:G'3ϑ,YYr~"2΢73y,/"ZTK֢ s8q!$ [Tsy$IQu$ fdR#Ճ~zp JmBC$IRV JVY^$f n%Z6$i _7Dѣln3pvr"P,1|^&*ٟ Z`wy$It*/ߐݽօhCUA ղFUI=_rlW2YDa0]h$\ՉT*yiK#I$If`(TK,/*MD7Eh((I:t{ x`E$I$Ij j[* 1"$;o/A|bFڋ.A3%Is|j%/wY$INR5$5;CAuJ^:7PfC(qf Jt}'AI$I$ #*7m\#* _#Z c."Iskoo(lq$IPPtvody1,fa|`J=j}qWĶԊ$I( n$ Jnmv fyˈ*{ %4*4$I$IR3Q%/Ձ:0n.FgD玺5טSI$>oTJRs9~GT 7$I$IR+0@ 0jK]\\LTz"\,c&C !E$I$IPPXUq`;#%DыD N$ \`zI_x8J\"I$I$ CAiURx/^OmG 8pQ9Ax1Մ}c/#F%i,^'.\`(X%n^*$I$Ij5$z!*N; fTQeD5E{0tjDCDD`" :.$Ix TB Ijv$KĆ|TEH ERQI8[ߨqIgc(pQɎsa6%n}xƸua'ؔ$I$IZRaeyHTv9bb|pq3vT҈#<8 p } 15*M$I$IԺ Ոm-}Dbbp%Qӛ~m~Ebp v5mk<ӮQSUus?oT%I$I 3LT`)D,pQi8$ ҭJm0Xno4l'څ> l$$I>\&@ 6YDk`%a!DDulFZN#ZNuk4KՄR+N燭@n݉ZZׁJ^!#I$,,t $IPP`#Q-xF$IBtB}YvC![ޕ$5+CAITK,/"K{ϥF6B5DX4}oъ)ߟITm z vc"*URF$I㭐-[e/*HJaAuR!DXftQ}4">_&z/%>b "J70_6$ M#BVLj>5$Iӽ)w$IPPR6žA]iyDSOu!eDX Z'ľfa<"oyNq|tD gD x,bNB8HY|;Ӑ%I$M-uۇ..$ ^fQt D8{kxhgxq^8XKG\yuB絓=Ru le*p#3 K_6Xo991*!L:j<  )Q_Hi0yqpuZzؕ>u$I&LSoSp%$IP4-ujF0} ].'fƋDupQb,/!6~p+y潧NsRq7FXH%UDXs5XH9u tID#d9s3œͱRu;?Su;՟:>1o7qD!}oWR((SPp8<<vCDpz܇$ItaokkCAIRS2<NcdEGN~ Y& A"GT4Jl#ڝfyyA%/ճ\jwz.qN !ړrҟ.!ZC:\N\l{/=]cLC\p Tq;UkүODe ?Z=BzV ^~>]ߥ$Id)em _~JHQdž Tb#}jQCT ]H(x%(FZy?BlL?Kl 6ey=bꦰtvceHyΫ ү]F~CT!.BD(9ycQUu*3nFB֓7_|?`%/=i:^;mI_nY;ѣ.$I&ؕݽօh \IRP0V3ʿDErE0 ;&bRRb.db1oubQ#8ITq":zcq lHsmZ'.fXJT)uN"<ϩý3TAUsTn&_b75t&0$IZK}BV,r)$Iͦ#B,/w@lb3yFrb3y.o>bdsy7Ge'~L?W#ؼ fy-b 0$ijSkL3 Dpy,Hsdܛݫ!.@HVΡU$IRs(dgyمh8/7$tw9>M滘4}H ·*%CAɝoZl{> HNS%B?^K}H$I׺ؕ$5S%`cLF 9SKeDE " BUZ,bf׈p71AIM~/mVsLjy]~Nk$I2 C}`((IjB- fyCKaG.&k'B.:\o2b^>" |xxh5?G %5\qVi-CDַ I#x .$I1~vk IjF- 9D@pQ7#85}K'+zQe$#:,/W %5KyDyzNo t{}ϓ$IT]UZ)&V}|=% JJK)#Z."f##zR1]Q5 FuQE Ct$9%EDxvEIYsE\`4ͥ$Ir Ms%IM؂F۟|\DT]| JzZ _%"H DЍρ=]ąE] I$MB>jTr$Iͦ+S42R:jbNeD+N)5VWs'|D&C4+ۀO-C wMTHSj^B$Iiw^Bϛ{ + fѴ`V"]D:.%D{׳|&?MT~\kZSt$MDeetfex "fx x7]x[A1$I&iq^V}U ٲB'UN#څ.!}$pRHa,/[K\"Ic0P^I\j" w׈0q`k%/hC6eyy_%/Y-(IIP}h~L\|/IҤkDEڝ?'6{M)2b_m]%i,D5\O\Щ-_~lz.mj`105֒$I҄ïUh7/nu$I`*<WDeD*U:y`(o5 J>"@f>tb s|!3'LC\"Y[J$iB7Fͬw/6UY^.dyv5g&*n B>P eD ", y.J瓏_\Cg `#, HiZP$It/ lC5u$I`26^ۀ&fG- DO. X qAȌ^Ab3@ 5f%9ص@$Ipk^п{\ Id n.p)b֛nQs0CTuy$,/S^N^rIT><䥚GˤFh#2"IEq]WTk+!ILZ)p]9Quo%j` M藀o!NmQC>JPx2pK"IV+V N$MqHA`7^ DLl-3 Y^>jEx.%s@ D`P%ۆN"qRSY^ AG$Iax${ цVݻ~JH&Dk+ b ĕl=EbS׀w\w[Ln-0_:Bp03PTҰIӘGTů'A~$ICTw1$Mh:hu# n]1S 6K?ˈP> ]Y^^| Q%8X+:{ͥN%`y: .$I&FakЖ I,R6 DDOAlfyՂNz%JT vb`vB~ Y!ؔmD/ob+I RhͮDRSWB4ƫZh)[DЩ.y6LX`pkωJn:BpxQ!D3Y\k.$I&BW3WmY-(I4cZ)b; _Ȁtv4h [,RgKMO+y9!o*F+˯V~F$Ii7V߷ɅhSV J&XW vdW2z`xL'/:kIlP$.wD%tn X VG\r t$I4n ٲB[ZP4)lS+m#p)0 q)pt_wQ*u0sDxrM:GL3D]3X[,"}u4$I_]U{] IDoY ` 7Pchۋ3NU_V}&7Z`Ж-@-?$IҸ肟Wa+Ѷ^{ǥ$M1 C̏Z |V)ļO\sdy>A lvVL}龜EV|.`pqzfgy C.$I.=Y^v!:B}Mʷnk!I/ggmC? )rv .'6$R{HkJN^~YsyDإ3kUXB;|>V$Ip?׸&ƃʶe] Ix8P0]ĦJkDƦZU*Qa2Cbm QOe9l *bz&B>l}>ftg/' 6$IꂟWLu6'b~$Ic|^l%%x}BxbSPPjY^.fyh |p3 ~>:b:pxX TlNn U0S⢩KiY^v$It>eWvܟ{$i<φ `5 .$I Ӊ"7?C=1CvZ?k:Pp#ˁO_H.I$h%˕uj^VWB4gIM#6> \K@?zu*#ZThG 2b|h4]h%I$bgB^^v+!I+ vUnjdS cpePUt'ώ=<䥺GN@TJn BUY^I$l Sp:6'A4V*r{V| }Ai<>֒UDЯE:7  !DhPrb.e8tU+yɪSI$Aaov:Y#[\ I҅:Juv1GS"KgZ5Wm9^+4p[ur,/p^$I:B}WSE0:H.DXu\ˁOW_mCuzSֲ].R1'BТGGVsu-y/^!`oZ*Imscnt!:VےBt>GD+qXZ^Ζ__J@ {n` ѕa$I\d(Zs߬־۟{$|}h`{ʯFlLgPcd^&."Ȁ[ļN="7;:B;=[ut`j&QE0/o+yK&IB'Up``[ۿjHՙ6U@K3 n C1hUa₆ wH{ 5AI;I-r&p7ѽ.$I(j~ `1p 0Ҧ? qvF*+T` ?H!M,/#Z^ |XF?O^'.1Kp;PN1SÏ<ΪEk|x|3}0|$I:- SYEVSzHF;](8. 3$p%f *P Q#6:&*$MT>'.wF<6 2cmHf+qѫDxh:Hu9$It/ ?S˕),v} L3 | x L\sT:+ua/jUJ%J3`.=U5ljo1q|,$.Ո+^B]D[v8^Kv$Iy*p CA}][~xjI I:e`c5frwubt>:|z$Z J$!_E 2 `^f:aiZ0&I0pOiGwI{ҟݽv@'[ۿHR*'~ʤ\LlF >C̐AlO 0R%q]iL# |(Q187&I@ͱhZIQx^cH$IgWȕЙԩߕ5])$uSU$0Z>oA`(wo 3Hw!G\]! tl_G H$i"V,j spYu$u7D +G(. J44oMfEM$i|ey8p u:B\ $f%/^h*o{dw."ђԮN D+D[V6H{ 516W%ڇ$ZuFTK6*2a%,/Jˀ;OANC=ݞ~O֙uhYcy\!gұp%IP*{] ]"|k/E$uQ\B,/wAXE*`qMDh7o$6T;q{i_%A+'1"dǀOٯ3]!HD[LJ 6o՘4QuђK#IfU:Kuw ׸+˻ UԺFS@p6[VwǀÕ4"VD01wG̎WԚv:|: vUO$*N$*a$IZ@aŒ,~q54F@.׾\ȖZy?} _Mn\8RPpp-1؊yR/`͒Ev /F]tR"=觀BB@TNu#Dq owӉҺzD</$Ij%~/š61:$,돴z%a?۴^+JjA7s2Dlmޮ䥉 vUڿʢNlo& !N҅Io!* Dv"oN9Mgux'w<,$IԒPZP,BBj]Px4~pǖ8V[vC7[X]ޭZZXWcdCoaJT\ UBpx1(!fAI${JyjAItF(El ^LkV <čWz~5[~D?mC*{ F<܇U |#.*v['Sn# %IԎ|sFWB4&NթԘԨ좵6`MbI#=Jl~oMD?+yܤ0Q*ݮ2`.Fu!Qߧs瞱=j.[uFˀ$Iv) d7fI$z`5Lzx 82YJ^fyy 8vscrW%ey``Ѿ⁥fШ:D^Ω{+yi%S:`#t$Bu|ʗ*y騇$IU_3{+!IRB뇂G{ɞo7DT-| => l IDAT6T:'"k~h׼VMF`j:&v7XL<T&I$*$I@{4{4 F:b+0D%D(mCsƹ`%q-DN< ;D(Xޮ.ϸ!Tg[WcLj*yi$I:Ղ$c&&'m"Zᵢ!J"|͇tF g׈jAh~ 4㪗{Y<;c%Iy5T-P !IMnB6[͸D-{>LjpSP^&B-Euw+y3f`֝:/۱$I:on+!IRgk STNX \EҞmAK`=p,\ά )pp)1gϳ6"QXsi&\ַH4CqI$iV,Z?*{] I:W70/J-EkqbVP3OmSRbp/>@X{|4 ˳c|%QbvD%x:׼䥪K3av5L~T.IN)Y^Ր$s%ӈMVR%5&r%/11"XElubxh{00\KVHbz,O%Z1~HJ^ĚNTs(xh20$I]] I:GB-4fk ɧbE&z ڄ>EToᦦgUą_'ov/*spsg G" U$Im@?p?׸so.|z(x Ci߁T1x1!„LNk `3$q4N#=k/TZxG]DyVNە݅xن?fg[:^%gI$ r?o$k[!j}P)v1[''xx|hg (tbۿ ,!> Ox@\6*Q{EoJ:v[;VV}D UI$I@![~ewTjHYYogy.DR6n Qwhչ Xc|#O/;nK"3eDJsD `~vԭSKq<]D5І?V!.9.I$ؔ|W] I:G7m%Ď=ĆQ%/mv3_30~`4"[JYD:J\tKbJ^:LBz}Z׍[J$IU] I[!:)X8FS#Uisubr+p 2i.6#fy&f+U-ՎnJ"˽Dwq"*}Aₓǁ }|7NMz:2A$II)I]$I7BAZ+\a֑o Rt0U v O]DuGB[}hUA2|N/H ] ̤=.^ƅ%WG*tis6jo7  J$I%Y^^J6ת󯆈{|-Y^|G*KD8q1{*1U"6wԚ@P:sK0 "Hi9lFT'o~ '+D ą&p5: l#Z /I$}"m#*IRhO%~x x4M@vtJϯ$IN6Q nabC QpfuF*uMQ%څ9QU5;=us q1D8&.8)jо%wcV$I3$L>GC&Z{۱Ӧ-T:wY^JWn'f{6zԈ7MDV:ًK8siߪDχ$I٫%km/IR) tS#Y^.S_"څ$ȃDupZ:^2 L"$lG$I9v*$ܱ񹡠n{Dx]] ,%.{ Q!Ձͫ ؆k%T1>c$i loq?΍$  J8Y^nnVn801m KJ^41_q/C$It|kn|gGIvQR8oJDXb #&pei D2` }Q B6$Iy(X2]d+!I:Q}kZ5"*Y^v旤3}瀯_n.fc x:CA`2p<-a0޳2-D)(I${J;+!IR{iPnӰ 3H3/nwDйw@2_%X%/9?uڻS~`'$I.ȦCa+!IRzV7PjĦ~bðC.b ZnI:I {7Vb6 Q!䥺RK i-C`PI$iLToN/(IR[hUbm7Gnlt)X#$pq-?!Bӫ`[bJ^:򴤹̓?nFӳ@6662X%U"(D~KهIW!K$%QRTU('on›Rz 7p9 :2` l6痽DذD8NvπOIq`*I$i >ѿoݖJ Hձ8? ;8+i5E*<"^ p)$ۉJ}cb<ĸПG sNO;66IGpP$I,J-jC_[G J6^C!:@RLxx E" / π1B $ .,u=C "Qo~I$i%奛[U`jHRѕ|H>_<=Sp8I\?껸n/7]g(^&_PC~[xU,xx|VXB覽Uztq$I4Gv JRixj(xG=\ Y@t?MۆT47O&_*&ہ=㾊i!,?^Jv 82;^%Ie0(IR 'O5mr$~oVBo vScSUJ> {Gji)S"ݴwRѺ]ג$I|0$=˦V&SLm[KN+(N_#^Bׁ  ~=pW~EC.|Q$I41(IE}'3CLkľ崺VƼyPN=Dw=Dqp/EG3 :?p Ҋ֊{%).{xPI$i~1(Icz>7mS~Pp/6^7?J"!:$2BioHˀ8&p-grt1Օ7$FCt D~N +I$t3p9$wY^(NJ5\oljt]#UN I-$yvG͏.tQq{+/?؇]SdJi/:H$IZP-]pB=+!I;WGI$[*c'Q_dD2<DŽvR+8'݁A /ׁ!;:"0+]WwSFH$Ik0]őSVCK78s1Qȹ⏄}Dx8A{u Bt!>M'[]{崚`7p%1 Ę%^z8k;;ΈKJ"d퀫 w_#I$+kK^JdU(s N6h~%X<V_y)ijp p71ҷ | 1d.Z?Fl^&qw5džEt.أ9C%I12Ն>ӷ~JGAE{`-i$1kqqA]OhCzƓ˻CJFSA3g[kEk xRK+X=$BeDw T#)1$IRHK7 /CVcuolI`+p'}pq¿\Kt%Ac`Fl(D8.{z:cl'F#n"K#L]īj@^/\#1p»$IԞj骇W/eVCِl:= O;'|v''-ܒ._9vADbD见/*PD(&}V\۹-^:c$o_>`0.I$mى[p$ ֠m8 #7w{{=;S D>PP|=ĸNqx ~; u݃DWW\8w_I$Ie`Me_}u߇Q+"I-m9CdX9%^-pu^OZZ旦VKc""\3pL襫nbO4 QKNzث!1!I$@ld묈$lpOߺ-@/%mm|=pu'i@'?#ˆ?!v^LKׁ@Ю@`y+.+qbώЕ$I dkꙬ6oB^^hS]S .k#P?ILMi OKoJw-9 RL^~A^iH-!}T9. ƀ^dx8-/pFqbw+V-<*n"|K:$GAAI$5cb\[PAzVwzbQTN 1&vb:7o=L5w/$IAT6/hIdqY3PpJ>5+3gT͐:"`ZNۀwOk^uĈ6b'K18ێOy\5[=ev/J:i9$I$]5`yjD#*q2; ZZ/DOJb/"`9J-3Aͪ|Dh7P_dz/#B؜oZZ^6/8@.D;e((I$i$奛dO9ZTȕw˫m1r^J(8JtԈ={DaW~^Et E5mZ"¿+)눑&{.. BF}ǁDKҌ:?%vJ$IҌwpqMFUV~u6RB| 눓t]REk IDATDgV8Q~^D`ڼ&:"xۉw5Dp؍J#?!vAGnefb$>A1I$Ij`Mel|iNl:N PɥsC-w I3={s'Ԓ@{g!9 .rZ"NlkP]Dwp4Jߔ_n?ga~3;ge'8q-͸:Kp'SbOcy%I$͙dْ1bU6`ڿS8_#Gj%ؔ|}|Do?2cCcrZ}-3B-/Į7?jwv<L^"$1Gs_t~<_K+G,4&ѷMq(I$Ib񢥿h<.Gs `lpw8Wa*{S |D}D5tяCtxOt v"})ZZqhN6#rs~;[bo#%ͮV]"tW$I]1 Z$tQ(ٖ]yG xaYm[-D;䭙v;eDܕ^e!p7 `8YN'SĨ1&lKSƂv@}]D(x557?$BW. 9sw!I$J##? |ɲ%"D+:fk&B :ؓ"v/> #D;in0>iDصy/ \_ 3t jf'&:wo!͍p(±$IԀpraQ:E]4F~ϟ=_ןfGHG>ZZius;D\u"/W HabD!h9!:^K+ :iؓߦ;5o[P6bgR+pm7;D~$x7Ǜ4gƈ&:XI$Iflp[_d.Bihݮu4}FˏDоme'?PcoNҊI$IT(SknH66+S: \}od|P0}7^NCDxL)¨.s>qxO4OH l!:ƈM198;1wM JS|ۼ !B DWoWbGllL׼ZY~2Jd Nq~FtR=KO,yS\^CbbbZ%:D1 $Ak={&?P9Dl-BrZ>F/arg3Ի m7]Sjߛw{hM=e%Fct8?&w$I$I#$|_⬑D(߯?o!d`} mWD>1WZZDRKhDQ%I$b #: ppO/|eP!+Ki8ʸ~{3TK+Y>F8q CY}drꋁeLڍ25 Pdp":O~ }u]_{n݂W`sDhov3Svxx xyz`cIs|M4$IH-:vޞo>ߗ5内uum#ٛ=0T>nݬ?rZ}#""pY;fY鄱S; u2qxɱ7B@l/pM v5@W3O o?'Ҋ{ʤ{x{I$I4c5`)aa?\j$b )7{⿥@ @B2 ɶjc KepN]Dt3 >uckiv8w(yp:SvzNf0Z:UlDpCbo;FqGԊctw~$$I4sJsO3<X]r}VpnMuQty&˖8Sb^NE7ۡD@TX}:SBsg/>k`'1n^I$IKy#CC =z\$Ib[SC8GEcz/ied3ҡ8#mjTڛNͤ=j p+>sCJVN>[O;$i:N]!ƅ K,>byw$=?XI$I*skSƘJj%,>sʱrZADUssHj;x|B }  Zx΀$I$I,liw @\M%<ޱoA"P0Z_cC@:bǠ]D]`7GkierIm 916tVE$I$i>O(~ϟGw8Cb^`p3&#?}(q@,$I$I_[]< 1!\~?i3b< rn :JF}C"|8YK+cJj[o݁ΏQ}I$IUo.2:S3VNo}`%"X\,֓L'Mb`V|VW#?k$I$Ij Gv|y^%?!J* 1JOtƉ Hj_}&`Z$I$ie3E~Kt,I$I"=}0A0:Cˁ>NSkDgDW{S.{СRgˈDbϨ$I$IZP}VFǦҫò|hWN#D`Q#v > Ɖ@t.!, b~7k=݁%^8r81TK+F$I$5Q6K+E8RT:ױ3 v18vJ4 IcGݲH$I$lpOߺ--mKR&̻ˑrZx8B#uS.=Ļ:x~NC>qbM+Q|~RK+rZ͈ncĨѡƿ"Bn*`!p%~;)"H?Ъ#:ko;HycfXߎc (inՉ?~$BBI$I$B邆3hJ;=崚]= b\&" \Dt09t1jFbLish &rOA?Jt%~ZqN }-t%I$IFV- yRPpA0#$C|=%뉰 `E9]W½-cywxCt%:n_ 2@I-? 8c$I$IRɶ۲Jt.J. ɔ;ZND0y  !Ĉћ7CǚGo !dϫN}C"#N!:%:D|ߤ$~Lḁ$I$IR{[7}9RK:CRK+ d{iu1J3z/vb_!D$R}`Ifa4ҥs|;?c>%N&GؓfqkZZ4$I$Im=j%:ǖVJ\ :h5g2"\9嶽F"';@~?h#7ȿ| {o"TQL':1ȿK=;pҎIu7xO29YkΚ:*9Rt5>%:Ӓ$I$IjSk'ٓVt^ ܔ=V/-=>t)جAN|ao;#2ay$I$ID-VlylK':ihcݐxī3ZZ9jY$I$IڛcC;CAINS;%J$I$~)slh}`((IRd" !V-<$I$I- =ط~:+љJ7$8ľ7F$I$]j`Me|$Ip8 ؔ_>3F$I$/h$px_6G$I$@PW3} %Ij0I$I$I*ŵGT1$Չ}bdO׀Z-<$I$Iű"xSVB f{ J&n ԀAI$I$DjD#[g%Ua$Ik8F}h-dH$I$"dTk*3 %Ij-F#." |xV["I$Ib1ԹP0$ԁDG/[I$I2ԹP0$՜  v  $I$I*6`?: $nbq %I$I muq.:[B{3=%I$I$I4g! .d`MeL~ϒe$I$I$Ig:CAI$I$I9a ($I$I$IU+ j:XO} %I$I$IfQ_::+ KK-mq%I$I$IfG_3OZ MGw)/+I$I$I4醗!{JhFjiv J$I$I$͠6`?ltul~;%I$I$IfHjD.+{gk @K$I$I$]K9` H of $I$IzSm IDAT$I.K9T$I$I$ 5x A͐;%I$I$Iίa 5K)(I$I$ItN+җNi+UKso J$I$I$MՆ[uY ͼ乁5j%I$I$IŠtuuVBGk$I$I$Ix݁݁5 #[$I$I$2dْ$I$I$I@ͥ.'+;%I$I$IR;Ps)|>;%I$I$IR[:Y\* %I$I$IRGXuOgBs(!U$I$I$I*3;Psmd.&;%I$I$IR!eۇ{ۉF|HJ< )(I$I$I omKYu"T$I$I$Š[i+]be+`((I$I$I\[yPkK$I$I$ eۇ{ |GZCz%2oI$I$InVj!#jR^8LJJ$I$Iѿ`cjtRR^:в?7$I$I$Ijuv=i5j5_h$I$I$BY ҷӯiS$I$I$t~~K UJ6UO%I$I$IZIsThB'CAI$I$IBV5XB+CAI$I$I z{ʫ_CCA0$I$I$I/}qmF)+602ۓeK$I$I$ImƌBF[v NAI$I$I4DzЃ}뷭Q6`yv$I$I$iάH7<^'[g%>sJސ$I$I$i K1=$I$I$Id8 MOJ-Q5K I$I$Itq G[UXg((I$I$It H;,atn).$I$I$Ie_[]w %I$I$IZHA@$I$I$5SGi5i&J|kjviF{ ԿJF`|k<] :?]O<1C|P#cSOrd߲Rӏn>x`z(5{!i}}}P~_{{gu#WBZ<*z)~ =DrC;py+,㉍kZq%Vov2Hoc.ݷۭ`x>ÿݫAŊǨ"dʜ ?k"X3,᫶+f%:B_"]LHdאJ[` )I B)q3˘S$Ǣ5-?/Y$ r6eFI%RjiJ/k*-J5k KM̜u=8^{{F\=34,6m9*̭Ǝ;mpbݶ R:SO;vR[nwZpZZ|ۏqikCIQX́7eʙstJr{+JdEA#Xne_yߙsJݿ#sNK?dmmOeHmDc#x[S/QᾧLf>Y sr8u̓.}=x+V8%-)s*>>ݰ;Yc+J,j  㜧l*t箶fb#!d{͊lwuO=ωڞ毫Vh 1 xJw{~P'LgGlI570(5-")E)+OGZrܺ3\$N&J~03G2\sZp+|}NkV¤>Xvs+Y3"HPN݅sY.# ff5](vLӧ9X 2^3OoPa4J[yMk9"\'z3}ݫQ21}Jq6{@Ddp2/Z*'}Z/"'Qy,JYk;hid4j&I|L{ ]ju0^}߱G*g&SCFۼDt)ݵ\?MXNTkFf͝- ۞Jf֬uA-fkHU+8ԺKlMtS5 ĬݜtUNXb%=t{gphi},ƱL׍9LkV8q^z3R++M hsBA^@TN䔊n-IutX Li6SJnx;Uq4=0`h]XV 7ԋ+*PXt#h1<0=W1C"z[M[!𣫆FjY]#$X-VG]!fM 2{& p1!kqR-`{(93l[ щm~z* `Wt xH='%'Ԅ Ϫ* ށNM EB%Bl5"A(JVH"yI9ws$S\=E&Z7~)\/=zz~#8w9j,El)6P9BZa .d]d"\ZV.%RZ @L j7^֊KSIڻh'4+2G22)}q-vi@ :JS%%@ZXUG bR4`;ӦC7SaR1DnVXHFg|{5LGe tL3Ձ <GChê:S=ĠB˓nإo]9@\A/*xvd\99i'9g!RVve #pdw EDk ],./">`HM/"yn Oqj.^,]R#Hj3]=P[cTxKj(r(t{Dr;5fjv;4oD\S^v_8gg :"cPST+w@"ޅDS+$%r2+Ojӡ,RMc C/lllb kp}EJ6f7~ږ$,[&lN܄xISA 8q{ 3h؁㑊^1+ 88`(a/n-6R,ʈ F"`DGʴR:iåxL*{ަx"JT$pvH. :J;ߦ?E#i.'၀P.(.#4oE=I+Zb#i*<ĉ7YREV'b@ Ts"HӦ˦EMrA8IFCs B &B1^qO~*)"Ҁ)9"%*@IyH~޺]uH4ҮBP­J(AfA7uA-b=h(LTlĂuûT߆Us' ۥ`3GBq%`*oh@hKC\I'϶o¬^.ԲgNr?~EN=(w c~<%>+Seb @(OG c*Ȅj9[.2l s_y#;xն+0oXJi,2UR٘Wų0f T[W^ѼR`Zn\Ki8><Ցi%&N&x {[!@4{9$d% (纃,(XpL2{]{m,BSS +Qe6^-g抻@ 7YeҶ%n8L+͍HK8B :[[*940a(ءB!Ha#XmQvuep ѳ}ЂiN"<5Lz*PQ'So|O1Q}٧27; xa AL^1A@q)<[gZF.5C'y^@zkFǽ;悂hM)&-HhE@ 5boѦ : Eu::m8F=F&pgd t>ay&ytUھ3;Og3 2/enJvSmWJT-2֟79E1_AufRٛBDhJ.kSv爃7zidežY]>rsR>(L;OO4 orDS`6GUͻ 1yg=(L<5u#DĀ2uR:hEAVAvD.dj؊6%iZmuRjuC*cѫyC6U }: J˴R{1-¢)oD5?PRjaq+˴s?E{FAJGUS.CjOj .'I@=-eD;,+!rex4nw`hX$nБF+v\$U.XIY" 1jHLs*Cٓ,B bA&I\CXqe ɡ~34gpq4EC> psRa)IuiG:HM4QeE,`Mxmrv> (Hv]1#,a29]!w{94@}HI@{Zh'j){*iS=a[3@"JII"Rh B'}种Fl΂ ,u&Dw۪3_ V:ԛ\8gж8 p4yp$m0y]!A.FrL?;AI;p5xFtqJCIiap@PunOyX G@ S4Ajc-Y9ܢVrZwX_ٰ 9?SE-T!}|b sۨ {#җD$P0oF A$^su[άgqgҜTBh']GDSAN e}m~!(V"D8"_ *Gv/ R0~,n; +* &ynP`;'%1EKD} aAKF`P@gY].*رK@GM yjU5WJXLS IQNiF,8˜R _ҪCJY6^ZjUN$kڟY`}E`H-dX~Nd֖Gl.kWP'XN)ξ7bN;,-kDZNtء@l>#0 `$%i&p3`aXINpdÖavY `ރ\[] l1n}%0 #-gYV\@R=hƝ BSȫTu,.8>{Avsilg9 QDKCTm=X$!KBebT0Rp1.:v]uΉ޽xҹ66^K[{W0y?ߑԖQle5D}ƯqyќStT AJ$f#HxI &*Den•5gD1%zz,5f6MWB~lADX0hv J`d (:扠HScAB +K#<ad.qV8g@Ф}= l!Fמ|PՎɨ6cy; =:V?(0F M5JocaZ*ʸ:#ű[: ?:8z0cxMV4lڥh кpt[JP$TP@=?Nw*`; 30#K@EB|9?!L$(5(Ɉi.,&@Aeb$]H$*Zf+؄yXAexP` ~X4DT( L0-njL//DLA({fq,!ę!`R+Q9f$h C^kutBc`ր3]{Yma.} ӖAcFH/&e4iC% *xɮ\}ǢrEIrwCAt“M}%2*=,bT3⑎̧O} ?aQ(ġVs /Eߜt߾VT7h Vk(H;$P hdE*Zwm*hhɅ#U{(D :,yQpE_2Ghmomԯ0AjgƮnBړ<曀 T3{PqQ[㮐(ձ"ڕ) |hjXd͕A,d }$'[Y"WM!p:vuoeo]-' i!~Rj >Cvgط}v!vdRQ qī-$~ zO1 k ,#_ T.3c~tH%}\j8KiCCPICC profilex}=HPOSEE2T' RE EjVL^MGbYWWAqssRtK -bxsy<@fuLnD\dWŮWЏA2$) n(g9xMAF]QscigJo+u`ZK}uKS`ɐMٕ|x?o@Ϛ[@JXf={BriTXtXML:com.adobe.xmp j|;bKGD pHYs  tIME98r IDATxIlfyr}S!I$I$I6ŋ[P?xUMP $I$I$I^|P+}_Kn J$I$I){FP+}_KGP_UB$I$IW^N'uCHڶ %I$I$IAҶf((I$I$IGtU7CAI$I$I$ %I$I$I3$I$I$IZPP$I$I$Ij9CAI$I$I$ %I$I$I3$I$I$IZPP$I$I$Ij9CAI$I$I$ %I$I$I3$I$I$IZPP$I$I$Ij9CAI$I$I$ %I$I$I3$I$I$IZPP$I$I$Ij9CAI$I$I$ %I$I$I3$I$I$IZPP$I$I$Ij9CAI$I$I$ %I$I$I3$I$I$IZPP$I$I$Ij9CAI$I$I$ %I$I$I3$I$I$IZPP$I$I$Ij9CAI$I$I$ %I$I$I3$I$I$IZPP$I$I$Ij9CAI$I$I$ %I$I$I3$I$I$IZPP$I$I$Ij9CAI$I$I$ %I$I$I3$I$I$IZPP$I$I$Ij9CAI$I$I$ %I$I$I3$I$I$IZPP$I$I$Ij9CAI$I$I$ %I$I$I3$I$I$IZPP$I$I$Ij9CAI$I$I$ %I$I$I3$I$I$IZPP$I$I$Ij9CAI$I$I$ %I$I$I3$I$I$IZPP$I$I$Ij9CAI$I$I$ %I$I$I3$I$I$IZPP$I$I$Ij9CAI$I$I$ %I$I$I3$I$I$IZPP$I$I$Ij9CAI$I$I$ %I$I$I3$I$I$IZPP$I$I$Ij9CAI$I$I$ %I$I$I3$I$I$IZPP$I$I$Ij9CAI$I$I$ %I$I$I3$I$I$IZPP$I$I$Ij9CAI$I$I$ %I$I$I3$I$I$IZPP$I$I$Ij9CAI$I$I$ %I$I$I3$I$I$IZPP$I$I$Ij9CAI$I$I$ %I$I$I3$I$I$IZPP$I$I$Ij9CAI$I$I$ %I$I$I3$I$I$IZM I[' t?劸X1We`HZUU+J$I$IR1-Ro70'l8T 0,mx}=$I$Iy %!iϗv_uRD  Btx7FT^O)Mw _ϔTUUr/$I$IPPB+? x> 7?W~p߷+D i5~[mRY"\̿o-n0(I$I$I-WuzC>`"?7@]D_,!|3,O=oʹNDQ%L:DpJD%0RZ LRrUU$I$I %^c=YCD( Q7Aylj;zn."(ݗGәJxbN?^'ڏՅwRJJ1mP$I$I>ETNs);qiMz=?.&$I$INf((iӤ6VU)"T~N=px&(\$ZΧV+ nP(I$I$S JHrXv 0Ue1J^P8!/UwD E5p=4`8(I$I$i3PU=Dx7u~"i$%em8i;|]y_}w'¿by,a9"8\L)%b5p,I$I$i;0Po{2#ĺcyCDPK]fTgHa<" ^.y2ъt ݔ$I$ICAIjT^ a"G=OP^OPd]DlQI8_'*i"";NCyj6F0PL:"c<\u ٔjUU$I$IҖ8nCA#ழ)#Ba8#'% I[%y7Z5/ՃW D8xN)bUU%I$I^? I:ar{^Qmx(u5@cv&BUp x &+$I$IPPRJDQvaEhi :D :KEh:DGg R=x#tK݂tnRI$I$I6<>AD*@ٕA5`%DT\H)WUt$I$If((m9!*&aAeuh( XnOs` AR\0 ,WU&$I$IvCA1H)u={|,N-wc;PI*F׉uvp7,$I$IR; J[(WVDW;ET̷H=yt%=`7тĚ#*DE;ĺS)݄$I$IR J,p̷Cy !Qb `hzm*hVsNw7o7RJK: [P$I$I<櫈`oQ xXpXp/a@Pң՟C H7 D p1ZwI$I$I ҇R&&G+&#DKA C@I[+Fn A>.m6QY8 \O)]ϗ UU-i%I$IPP) |vC6`/uh (IV]DP8|fV?ȏoE %I$IGPP;FJh9 q<' $C)Ptnp~ MT^nJ)jUUnNI$I$ThN b"sD;1"D)U{8 KDxxx x x̥kVJ$I$ ecĄL]-B{z;˟+\.-F_.ҚՃ$I$IjCAmR7╵z ف G'5FIn$iT7^!'DU`XH)-yˆ$I$IT4)."#&Xkcx$ n\#P5vϪ1S\DU2QAvE#$I$I:>R?QOT^U~#ED~no~n(,$q&.N$ڋ &z[))`:>E kJ$I$i;3ԇ1D{cĚNQyʃ %I.߉u +D#{``~~ .?$|h9RZ$ZI1($I$I`@p8D5D%`{?n$i"*k~ o-Eߡ K $I$Ic`(Cna719Ll㹉^l*IRSETД"CT\fRJwi.VzUUn-NНTU֑$I$Imf({0ph4&pw~OY3n %Iz?r Ο_&DP} n`(;M$I$IRk L,\#D ow甦!bB}Ϗ.ʜs$]q!|x8_.lJi.gVh9?^^vMs4u5t7YT.X&Bcg !*&;$I$ >bW'p?OL|S_9o (m5Z_$ 19'"B=)?E@%T|2~-e]9m($&y磧se-1₅ݍr>.p(>|:".&E׈ +WϭQ_UvA\hН{**uǃ*}AN%D.LɿPP$I$WCLl"&msI1Ith6n׈ n!?G~|;?6QC+DPxׁUUuIic E JD(X5[ο*-4*kR!*|W  qA po(8__L)<{7.8,9EJeq'Pp<z{l;J|X%H</[)׀$I$Iz P=hE;ILD> ԕ81"8Mzotz>" /}~_E)=m0J\p<2@=?ӬpΨ6)n"ELMP__ơظmp\O\%¿sD%$z}UUY?"mzβX?Vn 5VkU ǥel(gpCAI$I*Bcp޾|;BFUeM.G<$po&½kD 5OT]'Ef|+eR}֨p\.牪".'*SW$.=|ZɞS%}R$I$M  EjOʮ?d$Jkn%!Iu-PJDI*>%"$ݜ_UU%x-CC1z/Z_~}0?!R(I$i/`p!$I$I:}䖠kQ5scD%K i։i"AIsD+DYi:O vgzK v #ڌ"Pfy)!I$IvDhC#&KJm IDAT7#Ą(& C/N[Iత[#BDxW@o1vhY.րu:#xjfyhc4ost9q#.)kJڹeFJi6$I$ vJ%[ubx1u"+*u*p N]n9BeMu'nw:\~cDvχ+pWI3VK$Iѡ`^`o'&K5p~mW~?OTRWX9"}Ó։*DWZA$CL!E",r~}6߷ZCC8Q}g/5_K8ϯ"H@5?E$I$Imۆy2bj?w5S<$&qO1뤮ɇ,uF]ɷHg`p)Q8 ҦʁRwT".>|x&KjTB?Sv'>I\b((I$}H_>\{[R>\)G"&_{JDOn uz-(,U,~ԕ䶟cx“)*, g>DO$INs'x3pN> #a~O?m~kk>w|$e[ 6*Ю/__~";JL@o7, b@M]Y䬴ɇ0QBT]!JYo򸘿% SQ/(nϭ*#}sD5x~n/u{ҚPRgNRJD k+%I:寧,E|>{~Kv7^ ?xUr%.\_J1R4Ak8߻7V*7$POz6*Np͏*E`0PR"W>6ciKDxp_;Ա} `XV$I8/r:q(ϟ>nv6Ϟ~6LK %VLc0(-JknbR+P\.QwG.UUTU`V^\2@Tž J&* '׵ΟkkJھz{Xu %Iͯ~8|=nV='?/_ojKRIk+C}/_>O|[mxGP$FTDMxֈq=\wZO)w a_?Np|Xh~~7i>|f$Iv+3|w\V9q('Xa*?|5BIcۇCnz)KDqAu"_''fZqJZH)-qoe"\8$cu݌'K$Iŋ>gy#"iLk 6Qm/I$mR /!$0:SZ^lJD|{3tn_QQ0D`q-4Dn\BDsr?VrCTD`tB~n-gz~TJi-KQ"`\wBXUU\u";c?ljp ՅVJƮ|^~x: %I)~;>//|%i{|3N>r񪡠ԡu{D ׀PW&B%"XmܮQT(]EDE 1bbsljf\on?Q0Gۄ6ooWjW4.4~^e4\*gJiǶ㫪j=CBwsy?쥮 "cy<'G[J\]D|.?g%IW^N_~=-o~}  #_x}smZPP >gjMn%V+k&Brϣq",+'㲶D{DZ uD8K%D$NQ%$,[DU vKUU2QEuD`D(.m쓻7`!|? |6ɒ$Iz(_O/j@לlEF]~8NJ_"BDwq:o4*G7Q7Na.H>2uKdI$_O_/TRkV9w8' 8KL!Bf  Nee`G^L)PW n"ܟʯ5Cpu+f` >}Cz}ԡH=8OQxp($y BoK)u2oIGĺ>= ,nq|z3CA88`]*gI-oI$=ſvcH:ID7sDěDq\"@U%ELϏʋ}6J|;CK`9/|{$Skmy˸KNc"1J8ݥl8uKճ%*k@>v57i'w~1o %IZ?׿a{PIR3>RT"2nu5MI`*R8A D58uRyoް;"(Jw)!UM.,u(Fds\Jivñ\}X~:7o DeD>Ȯ| cxcS;|CT"p=:G$=^|ê@IR J^iYBT^Ϸg )`@KSJK 4Qm4<Ɛ$5CWpXli 8Aa"4(0F󏶣޼PO/a]|_ɔ4QҲmRBD|<#f=yjTm֕0D$I:-B%I;҃JUb|9ߟ%?$&`+1Yځ}ĄcD0,p&?FTSڔڠOSJ5%IZ~{[ FG38GL \&BDx 댵h""*D7A'v*#&a hD; O%*qq I)-O?ǰ$I_(}W醐$ CAOjܮo]#&׀SINpo^Eֳ`i*Qs1<'Hy0ORWDXvV p=48sYj< s|R*JD|>p>BYQw}؝Rꪪj"Ix/}Wᚁ$5MֈebʏgU+6_DNSJ]8 *JnbRN.ooẀVCQ9h>}4SS|)ozޞ".|~K{󹫬g'mNJ$Ik@IPPT-]b)j! d|UUkGE`&&6cD[C#DpϽm %=͊ޞ|VZ * fvt!E"p۶UTon4qu!vGE6H3znY3j>> %IЗ]N>Ɛ$ iJۼ5" %Z'$&ʗc5"H쨉dyd^Ba7u R=XRUㄹUD5L]zes"q-",M\0vUU*.|*k%ڍ"BDHd^^TGf?a$I:|n/Y7$IPP] fIN_O/4Ήy =Qtή^'›d>O~qD9OJ[}SJUTJ$u_~V$}@JeQ2o/q%k9bBNNt@Zb=DwX/01x ?7J.VNtK;Ƌz9x`N)]i \^j[VnE|zzK~ޟ ^B7^&*woY$I6B%Ih ʄ:1JT^%\怵N>OZwћG1q?<| 4Qxh.#!5CŠ#Dszq~ciW}3$I$?ی1$IV[!*9n+oMb.4*.b1QQ 8FۗkAǧR*yv>;D)xޭ*V MvD~"(<Xs9$I>_y9~=Ɛ$#2tУT.qn)WIDXZurM]FVvOppSWHң87&BGM"xRZ".X|[sߤ^_|>?@SW}Osy_ۮH Xz ?1$Izh(Iңc(jh7GW&/WK45I) 띦X'.L_RJ+pj)?~~CkYcDUxݛ6G]D/㒛E$׿/| !I#b(iVN&QMq꽴!&T;vy!8Dȯ76}yx|Idao>׍ER->?'.J B|y[^ГQMx3}V?".(Q^>^ ;;ĺ?^#BtI$/kϾVJZlI5-.ɭsy\;% &wOkM=C;BL;+i'>Sgׁ7v3#l %DKcDs'gjBq6؏WׁBPUu7$I{^B-`( Yb|;EBT!*@6Fk@8L-@U1c0u[PAIsb?Q17B\H1IT]nzM)w`eJ|\͟MT !Bӓ 8QY9n։I |&HTƖ $IzGzϺ!$I"W*Ws̜&&3Հ7P|+m `Q1D}J)U#y͟!K32qE"H^>wRJw NUUk5KD@DJp8?cPETZ=C%"ܛn~z yK+>]$i+Ͼ8|ԍ!I2ltĺHLoSJgVb-jZU,{i S{3];ck|\'kVA^3e ^>E\x2Yռo$|wz;TګK$= LuCH 1Y*'*D;$4q%{i{u6n\1DTfLPWoid8ukPI(WآBshyXrfJ*\XTΥPT"Yyϟe-W7|%J'13wo~J&*?|9}/VPpCL.R?ί-J$}4/"} _rCHtD< & kUYqdsԕ J)u}y;&O ڵ :Nwg1vom"Y ])J(%A[ccQF8΅<cb\ؘ4Hr5txIډ8%[%Q,.EkokI`׭Q{ Tb`|NNu++cq hfffv}޿ ػ߃affPj5uw\6u66/c7RMSG|v:KYw)^8jC¼4333[`=H/A33Pp̣< Є8ʡ`n[*5UTItTm}hs @ 涠kq]a23k4)Æ8;O rAC)|M\Ѹ6Rumlkbn݇B|P픕ĵFgVR)|Aij,;Pxgc?㵱x'3YcI_—<fff5ơҙQ%q4Yu17?\yNI5hnp'XE&viЁY+⼟++h*rKWcUۙ|Ji:-)+s[qFQ=1~}휎"e8 @1wIVʟR2333jCVFw牭|\߿8]Ӎ>Y@P TU>CkDvʵzdg^s̚[&cRՖ+vB7Χ.q=)b&lî7U 0AʶE<ߎvаݬs3Quܼ眩,|R`D|+jA33P9433Ki$U$;ֹЀo'2ZNEa664hffK=ը55q@WQU0RρFh] G;@̬~8,M;?P7*'P8~&\&ڐF!-[ԅ!n]Yr\Ga[\@̬4Z(l9J<U?wr]\w-?Ht3 a_+WVvV+(۰mDA56k{՚Q;膟r0k{P(8Rl >Z7xCjffffYiP03Dk͢8ex2^#^_ۈS* u*(ף-[q56t#:ЍCMC)"RNgQ@8皭mE3k=fffuj9Bg̣yAy-KfvZ\o8 <OΠ.)ffffVo{#vx0R"mA_N;P_SUWn9ui4fA t3 =DSU!4!ܰ;omifށnU\7P`JiՓ~KRShe4?G ΢y 4kEMTU@;Ѻ+Pȷ -[z-l g2?UA9U=V+sN298W s$esrXhffff/{{ ROI>:Okdߧ- p+2Vl։Zl%(;s(x)~,Z?p|׿aw#:Pe5&3jZ߆Q@8͕ᷙٲo}ÁYXPp˚G?(݀RVPVV=&VTUEہZ-sh tMʿ~Tm3?3R[+mM:QLp:89ՃYieVt3$0q4333>x333d`Q)xɘӊ&sw T:P+7D1y@33heWm(E%MnGmr;< ό֋B&T}' X6fQV8gPT??sb{P|hfff=#_̬A,ew(ŒhcP1MZ7exU ЖuWC.Cx =΢*JZ뀝q0rON/h-.ys{($8uĶ;Αє8ת\kYUr=fV8wĵwSJEQ {4333{{? 56Ҋ4[m\fr2V.` }ha-\L|9 Σ꿳IxLffj)(8Dksk PVnG`:϶V]Mm\v/s'7Kq<ITvL)UWTW]ʊ+" x.soSqUUjڋB6T ?~} Uq~8 (Z nUI `~&f7Pp"΅;CyJ)My86(ע56}NZ_\u*8׎T'\<xxQ%E1@yNWW-f ]UZ^t]eUcQCVOdJi[]{{ CERʭ:vZ/^ʰ/OXoF֫$-\Q2&H6a4} UoAL,$uZĺ| 5uk5Z?u Zo ڵBu4|NnCmD796JB mǶM?qn:'O5&g{ W.&uZ(+t :}#Ք~SZzEњUccffff>̬9\`qg|wU,uo7jj˓DfزΔՀP˺׫JkX/gbVuK-+V6h:6 97ڎB=~<$4rW9Uy_R_Ekviw W =r [r矖ߧ߷?>Ԓ ̮~ _@5()Bvʉ> s9܉&Z8װZ's 8!(GWb-AS-˔RkQPoqiz=T>ߛϫ繭f$pU s[ZɟK)7qUl(J盅xK9(۸ x/p:tk / yA33PhBx% C-b /O"[E->˨ZjKۅj' Լng ])x)7X\>qBPJi8L5 ۮs3[AZ?n?ZRJffff?rz=fff ̡Ur QQ 6ƶU!uMUfcƵe-ˮM~L$p,cDNфi>{lߐ׮=γ7ݢjO)6q:oڶjՔW:,zpn|G\Ƶ̬iGç=fff )CRkտ u']&vQQR7VFwsdg^o8&Bϡʨ(ߞ+Wq`{",NnB6읨Zvts:u ;(o1҃:܉nġ59#hff5FU&(ܻ= n{L GBmC;kOZGy}3= DUPS8ڈ[㨊_]tI/4E5NxH̬Y}O033k  FUǕ([^rvkly=6\idkU7V0 yn :ځ{uЍKjG.reꦸvz {c됃BՁ M)].bbfffmC̚KT Iv [Q[(PlgKY)؃&@OdLK{+$ 4):J\NY]COZ= 49ُ(+q`"6ګ f"W^F|//u.ۇ]A*ݷY }M6fff / y̚RN2vIλJ{ ~-!Y#n :B)`U ETp8By033kbn^Bm>P` RdQ'tL\)`18yU dJ߳PTCFl.c6n w@mG7PКI; ?:N)MofffUVϞxwǃff6 ZP;Zm_Cƚ]VGHLo(P738VrVt3%sU:5NbN333?rrHbC g?w{?^?GI=طnklY3s(hx&QwUDUd'Ѣ(&CTb,Ή?M)AATAxg<V vZc@-DQpfffVw~<Ç8%?o9{;nzٹu;n{ff ϡ5 jy 8C $Z˓tPՓ54u8QEZIF.T=؎[Z)^q`fffV7\%haxt8xВ7~2|ׯx?ρ}w{wU5VEU9AYX?Z 9m }EaC1n(qH)}z Jrk5ra+^I)(*333r!gz-WУ⦅s ͬ9z[ h-FgfQ+4@9Љ:pHz8(Rs9^t;Z{v55{g}133>*A[TKx[}/~EEa ?JB3;%46BaLo: < BՀ"pw7QT-x1AAᝯ IDATa>+H=8L.WO^cI#(=333O}ڃ` DiA[!c'L~fV Z-꼊61 )6\ hEQΣ(p(X}/URJ( \lFn`/j7/6\Ah9y5 ߇* YMcI;n@؂Ώ~|/_|{__oozP̬f96 I (]cDe8v*W̮elAJV*覀CJiB/p=3mj= AhV6^PYs-?>M_xN YMs(hK!Ums4 Qkq4<Ch7j*=}*A)ã#Keff ʡ- p0 /\8MBN CZlvp- jIeyo|VYq(ffá-y4Q6¾x> Q*GadQ`6֠;Z4n"۴>TR;Ѕ*yjE+v#i˨+[c{=ffffb߇}=v7=0̬I8P/u/j1l h*(*P^xu.{:kP[;m{PӍՊ} Yܧ>=Q3Ok5v#PqTu0+=dBi>tx+鑩KM rl6RVz[l;fumwY ގBgRJgИY?AwdxtO~WW5!v=r iǀ=9TxdՐKm?{2 DH8*z:Q+=}^R5aǶTZQj{ۑRfffV >gRowޖ[CAPKRpMvV[FPt4@..g!OR\gC~`"܂!bnA7kC633eO}ڃ`oՁff9q M^ [fQ ZRV#&Pq4"=wW 6(Qɔҩl`܃ڊc=ZQ(xpjAefffGI;n@؛Ώ~oC /(0 O)mYERJI'Q`#SñC֜p%/hDUкۀQ%W;mwExu.I333e[/ z֠I INn':&&єh|=E[d"T8<܁ZphPl?3j__XPX|>MhP1hYh5 5̖'L@9 ^”i4 UE88L)  ce2ׁPuQ&MZrCbo\dR fvW]cDU-%[Ab{>]|゙- 7=@ޔCA[ @Ԫp0FALJi6[(fRJ#jE`- 6p( 4RJ-膔^~/5+=JDz}h-.tْۢz7~>{03PЖZ+ Uh[hA`&|?g${peQ-B79&]ݨJkUmuxl @7C71{Xl|c9Q쓟,_943PЖZ H*hM_FyTuO 8I|&`p+j yoO-9c{( sƓ[A33^6J}kMʝDaO~~N)M5*%W6N`,Z_U|"i8/?~ <'MO }(\?g 8N0%ZBv!>-mn_q hff7š5a8;h"oFy'QCͻ(/8{QŠ?l/YuTa󟁗Xt`J)Zy]Bp;jSu>7[j(;Bah|v<0nj GffffƭC&}p&3<:{CAkf6N=h!T1llGⵑ233Zػd>_o|23PLԠ6~Tnʪ\JM"&pK2FDEkU/v}rׁGmC=_oڃܢypPw[lQdu|>nCuCAGP<_QM ;z+QK-_Eʛ-3˕DmDUfffV>B9x)33[p^ ((<^\QwYv}>cׁO֡<4ucN&nSV?瘁gb pƁի~C&փ`ff“fo:bA U$ P5nT9xJ)M6yYܪ>SJrB  %$ԾoMȿGTa{-wk T5`KVPVF[{P(.Ώmj s4d\p0k5}ğiW-fׯ נ*=F!DQXx}$ N>L{w=h4# Ti9L8 _E>n_w\mqMuOCCqݝDq+o333k B8x}*33[4n\Ƕ*^ۀ /m(4‹s#(LqaE1FwMDލBU8jSh gb;Z:M)tZOu#[ۺxmsrhcGP 灸N^Rp38ifff Ahnjff͡mFsW}CxMl <lj ”Rœ%ޏ)Ty2,mT- ؇ <[+{@7Z#ޅq>3[* |q9j=,<60Y39w m-fKC:`+p7eEYTQu:tUEE1顫9RR~`?jizN/ bZ{T؎2p'j ۃCkfsaiusq}C7f̚o}a ?ff$ -Tu+onEJBV'Pr8SJCh2tUP̢ $ɔP;L 7r{z^?G>@QS_J):^ZBU;P.hߎv6-.|\&Ѝry݃̚Ah_ ْp(h{'_CA WQhxM^D3e5*Zx^~xnshgQ ]S o[Z;P{ ymV*Ɩ8w>*_F7XszgoU?̖RjάTni~3(܃Z6灁e`MNPV&W.W1#^\F9T ԫΡф(.tEE`>,;]h n#gKo r.1t#+2~:Ωffff`l -e(yk[iEՃ+T}6*,фk8Z)WqgKgxeU f@}fGժZ0ѶZq+Z'p# 3^ۊ3[Zmɟ. 5|YffffU`{o|ffd2F?)+Vce2}QfVT(LzPۿm\1rT QVNZW.&SJ((ق8nB[q젶9>2Kǿ%j6ioy`-j=-9?4jw:hͯLE1wzEXTmqogolw[(Cf_+mv8w%t/Ma'Q༯/ffffn79 {$l)-ueJU̡*pzBP%-+?߉'<ͮVvkQX0tQ`U`Px8Lv7 Z%SaE)0ZŬlawAJ̖S[=eO)]F/- *h|#xdk/N+e>P4ŝBkFv UC)YL7}Dz$euV.)L@ՒDՀyȻ(\;(]nbH<j;=nlRqA03eVoX&O3RGA8 )VGP;^T1 MQEj`UB^bjDR?<9ń֩s[?vʙ+pDmm܍*Q8+WQmweg ::_r(ؘxIw=33[6m("W )ըRpZp̸JT2nǬQ5ZQϡP~M ?Z͠*{XJi2dZsv\ߏZގЬT>n8ST%~󵙙"yGYAշ΃`ff˪ x&~{P{\Us N y 6Tۉ^ 広QE`lH)lzR>GmAwŵ䖸tS_[VU '5_F7wGs>G-.W 643e`Q(G Dn CANTs 5rxOSGlq֣srj;w!tJi*~>;³z$-h+:-hG\ :p' [n 0E*8_D7l w=mW kktQ)TD p]Ea^j#C~w#>P((xaL8J__.חPx8pD>vy?W㚰UvHz)ۆЁժn%tƫh=@lܺ݃Ѐ7< ffښ\sMPy2x5e۷5h_ WInTarVffWљjs($J< (XP 􇀹Xp$~t<25뷣Us`>S]n|Ț8wU^|8(| Enٲy= g~203!RQQE8sykEP-h-{PEI  sQ>VV%OF7@0e먺2>?+ SJ^)oXn`7|]/ʊ8 [2<|cF(lyWrP33 *0ȏߏ5 gQ0ɭ@y͔UPʕfvNT[nj?:Bx>?(<ts-88Dqnnl.vѽ IDATtƚgP q@7wXa5t#y`9333ڰs!BsffV ހ8kbRz%j7Uuh9ku! l^)./ű{AhΧ(oH(퇹[ (ΩW[QR}jsjg7vP5` wϭX>W]BmAx( 333nhx̬f8\`EQ4Π\d Hف&w[PU 'f w8^ %$(U QNPV u /6QE٫Iv0Av_+ w00 +[2^p hkzKBpcfffVvnAh0o? YpD(` UV\E(N4i+XPA333svBqP33%NMWW&{D.I-i,ϛ-ܦ+KPUgx>5Is~MsQ5006٪߻fT퐯5E1ַ{[nNꜘ|#5nH)4j:JyÃը{{rko87S;.ƨ`(yLW;֝poE߶]oD+Pgf|ny,%x~Ձffffǃ@:jCP 0RLL𭨺f p/TUX]cf˫&]?fA<庆ch\Z  tzT6Jk>_C7ja3333e=?5}33%kH]H)GUFǁc?>B*µm@Ppl ^N|86 Q`oU[$MWQ A333*r4aE5(yJp/J)Rݨ]zvoUGUKhMܷRsY 5CQ hf) BϢV&333t`l$^OjCT&:ey-W PXoGaFTM؇BeffVP2 s~yT58!2333_̬9Cl6kLJUWQ6=h ̬ṿΣ6?GT K)}x#a SJa9EQyܽוoUw23PqMalځډnq̬fG)Y𚂍Di$ * ^H)($lA^T]1\I"t |xxpeY9J̬V9l2v46RJ+P &{v*âj3337ny(<Ƶjԏ~ʃ`ff5ɡes(jQ6.z!܈ڋnMhm®F^C /}7~5Gy̬&94&c8o]ڋvP@UvU+ ̮j=p(c333S̬&9TEJ)MeUhn.6 U( 433WP['B5^ Y-s(ho(9T0\L)Jv`-UDmE7:+P@2к$43fW"?sEQT\W5W Yms(h5+*(*\Ji%x `;<z5XC33[:5 h +43ZPBGՃ)Z` 56V+boZcsPhff -瀧𘙙{#"af?{wwY}uwuw6, %tFptgFq3ZN?ѩ:R5%<0: #&(k BHl;!,UuWw:k_w\WjY اq1 mGO-?BM.$i_zJ[.$IdB{P't%IUPP5k@Xs"*+iqa1%D5ܣ2Յ Jh`(LT3zh%ξEe}Ղ;l$I4Զl"ԉ\zݔ$IUPPry;1u"{7Nf3pza R5x{] T4s6J)>/I$ "eWM$ J:X  mF &Uʏ[c LD\k]yiS&36^6$Is%IPPa")Ws+Q5I}g

t{d(xJD%3DakD;D¶NW^b~~Álo,ϕ1WFacmM+?nw4sgo@D4VP)_DxǶ[׻7ܼk׮rǏ3fJsss[" |} }s:vFyw}F$I6׭u-D%IP rΕMT֩$DlSގG' b,QS>=缑=SJ}~h ;vqfJX SyF&`.-J+Dk3Qp?x9pisn{z<{zL aT>XḰ}}}㺻?ikklP < ,FبR!I$h_~$";QDT,C韗8XUU;b~'}D貁u;W+~vvme'f_ۍC?d5˥$IHڶEsgq$IU!CVZ'*f3Ǧ_JlC08j1*J+v*_"fI-؉aR9%]=*MSo߮pۇf"NT)Oq=tqp`9>PPշ߯9ПqNw(Bcã\k_ %IڲPntw0 ;W.\b7IRiP0LDffDd"sy7e|ssίۀng&ICDjƫ.wo#{9!*+σikN ]sn-w's4Z KFu$I;*UΚe%ɕ$U<'!Dkm QMSʩU2g&*_! jBaVZl{6 Zm4DHG)m>{$I$id-8w>p !I:u JvӈـS0p4W]ZLf#s~ 7;(h<#'67rj8ؼFI$I5bYp.Dȯ$Jt(sn!C&?'A،Zh/Z3y]0 \Wy*6> |eh&Z!*(- 7:Tچ.n =zK] I$+Wuʋ/.$T}(XD!3Ӊ9y'0m`c<'`pK$i泀-Cm)c$p0ZJ+eP&[] I$m[]:2s f_~aʅK\ IRP m&B%Z~Gm4P]3pu0hORyF?8!;4rRJ˽JU3epι)d$IFĢnNgԑ+/tʅK,d$U rDEy!QX8Z؜hF0;heD`#wmC/AAӞL*U$I҈Z\yG]IRUMRC ]\Tc2p(59;-9׀V J׀r \|CTq5A>`#4{`eJiWʠLfU󻁽.$IFU+Xp.Dk)lJ]hBωʵX8\ZCT4j5 ZDcV{ف=^"C\o9ƒ$I҈xb 7C[0# Sy\lcG*3f h%6G痯ĜxG9J8~tƬx/:nH$IA]۶u+~E$UjlLT%1?YDK/L$ L!| "pB~p7$k&ږcJKsI$iX-~a̝5сA IDAT_JHmG眏.>C$6& m&;g望(4HmDЋˉvѓiܖہLjkRJ{&sg.$Iuk& O\U$UaJ'ig!T_pxb\`<JѼ46ŗdb^F`97x XXS@`$I4V.\*ԟk I #BlbvԌqUJ+ .4x71?ШDX'c$Iax-D3_x7D5ׅDe,:6]ի| *zN9)>trέ9r?Oq+wՁRJ})%8gO&$$InOZ"ԡk?a$i k(Xp|:;OגPp.pQA(Ic&rb컈JFmӸ O.`3Q%B| 8%$Ip{yZ]y̾NWB4<,3G圧$O^DLm4Z6hz`J)IZКs >\@4f xx-8c_ Lf'眝u,IaJ~a II$"|8'ڻ^FWas381O}DҨ 6O~ N)VIDUlbXD$IeM7R>.$iD f y\Yu= %-r9ωJIaF9>zZ(` ^(ײ3$IV ֧{T4b$+-CrciDD4vcv'6KOFQ*m@gO|3R| hKtVY!X_>BToV$I#P~}s_p$I#fZV[%ZMMl% ~hED H'AO-4桐=Dc}^1Um"p*|O3%$Ip.BZP45,ՁD|D xq^a4-.N"ˁD'YiX ,%BK`uCt<8xWιe$IPRY-(I)])BT'*CLvx#Z]i Q{@q`௉JKi AWG"BX!XKڈPCDSrE$IҐZz1%I#e6fp'08Q>`&rN=kFԘk@;qd.4f xhO^gJ!DF$ICi]:}ٗ_h'IҰg Yv.pQI"fҘ%dFkxX:k XF2ci.$I˜+X:;/_ŕ$ A sΣs9h DTDj9T^%ZF_Lh sOǁn+r]LrK$In#V ֻkˮG%IC2$Gݙ`#]C̰0F#*/ *!4cD(x\J W9h} Йsnv$Iۢn{ݯE$ A3sƖ]$7FWGj^`5p ؍f4.#_׾%$IU+\:7w_"$ $NƸ i22p КsvsTS%fUӀ]F`p7॔^+NK^g6!BvzكQ$IT/h#/_/t%$ICm0ZZ.kC$ZN!6K]@ |h:Y1Gp!2uwwEP?e$I`ZRtwp㷾ŕ$ #scrS3@֑R9q p,R9wA_ Zje '* ,R`ι)<|-;h܊ %fh \ | |By#Ip 7 smD%ICh*mC?Q%ƖPp1sIR(S\T^vYmK=)lLL".QA֜ L97;cW$Ia-DwM_s$iv(X63:tӊT-&iܪ! ci%DpI =5|n!۰j!K ̜(AI$B!s$A^+9|p9py膗)j((ՁRrxA"|qd`13QRJ;RJ=5{w ?[\&I$Eh sg'jAIҐ8 \"<#'U#fR)վQD> ٱ K_ہ^/_q98 ]$I:lKo#umB4kAw Sy58 T1R9䜧srD 06QҞ!{l"P# ~ |jpP$I{l47MIҠj:_;huQ)h (I\ -pYnuYEte2I$i+.Zj jAIQyۓ9QD b%;^*sn&B3UJ'c6`3Qx潵\3SW119gW).$Inwlp^u5w/W]rNiD+6Le((UJீS? 7 B?ۺrUZ|7x%j$IRw"+/#NY te^ⴿail puR=ABx@JT5zxX,"m> Z?b_Bj!?期 fZnr$I[H׭3p1YsxbSy3?$鐽SDLbS(=nbs"y<\~NkT-O̜Sι8:x?p p.q裵[{ w cF:|B}IC{1[K$ sD0ekWV Jіm[1G̸`k0p;#poo?x)Irml_-!^$*o&B>Fè8d#\w"&I$I~ϝ\Utw?oO;A f+7o0_!*v~uT OƜ['fĎquQo4 A>"xA>p=n9^V$IXpIU+;k! =>#/NTtP K qBJۮǀGsM=h((UÓ1&b^yļVWC 5zGcc^':7^$I觿]ǼYsE^`0(I:U ӀI:_x8ؚRڻo9Ur!1I,|@s%Y 4Cp- ~} uK(J_ D;.O$I{oz([oٲ+_nw},&KځQug`',#fF@n #Glt!*$-adGC/MO^2Dƣ| ڵ8$"qy"~XGCusH$~ϝ\y.ޢ,8wD%IxK(X6gPO'_%f5KT?N .#)$IHuk\J8W~$ձL#ղnbCoRYhu^__'%F9ۀ+Jv`C&Z>/gΥ9$@3Kx?,DՠU$I?.3[㥵oyv*TXsn&I\Z8̑zﳔ4' DF RIyS0pq`4l,cNX  XH)m :$DCCoym RJOV$IRƗю43z-ݽ(/Y=(I5k[D77S)D@n2!Ֆ:t(B`;mcے֊-,灮^iH䜛 *zDvWo~Ov]ݶ 9hv·™s!8"lk+*UW %ITV.\ҵx,8|CC0/^0/[w[hS^vgss3w:;0$ՄLbco{yR+׆j "`N7lY4^4$r-D+SV]! *w}D.qġFOC~G(2xE$I;??6Zp,8|x3$\rpcM"Ϝ>J 7Mh2tB7MKDWYdbC)I`sJY>b~hw\VJU"'xϯGoވ`oyMO)$IR-ZtiV j$UBBkVZ˖z^^E7\5"OhΙOg$Ջ}Z/}o=NlDZuڢޫy0QOǒqU~b _,'f>F5eq`!0e$IR-ZPզc,,^0OZA׶m,~7uk&\pˮ>]_{~3}VIj$WJ(Xf 3kKlaCs7X]ְCMD Gg-IG!FT!Mxx;Q!NU i"|xI$InM7^9}W i7%i5@  L6mDkD`53+D;zoaJ}{RJ}>r ppID hW|/pW,h#Q^y=I$^|7$-&h]7?5Dׁ#R"چ>ARJ>×sn99 | 8R%ڃ>IT K)4'8to xץvx9H$^V[BH}TBfbSjR9`V=G̸ZCTc\"SH:|B{T*? #Z9Jo!*n!;Z<ڈAM,kV0K$Y-(ILTmlOITdM%BO~`q@~ X<\˵X3K}=$IR[ti]IG(-gLzRJUD“D]^"|Wvz}H& \|p Ў+]Dr"\1JJi!1R(V'SJz]I$8[P$Uz(wVٿ^Bh<ѺAEC4`ONվv4C[Yr_ymy<RiאkN,du=8 jy$Iw~pWA$5a`+ ڦ6Q)Rn!µ=xXK]lnI)e2!i&FL57 iw(h,qe_vI$5}[.$I `K.}ߘ ɥDy~b4:俯/"*w^ J#aLy.8h:Lf־J#vu9 S)IoK'>s!I:,.BPp7*K֜n`;bnfaB'#ZoZM?|8}:P:(p60xZ/QPBpدrS:48k˵lJY$I"7.$̝=EP)8_\GFx9Q:AP#]|80(B'Z*o)>h؍.NJ^`3 P$I,~Ss1$Ij0-fY/#pa[շ+!۞9CTm%ZuLbh>+!*(!*vܠFι8< XN-><֥l8rjֱm=λ]^מ&.I$_LW^|i9}!IRi!*(bPC(6*JைdP0FIv6`WJi_L>LTvjqW\).ȿf귪uWy}]lE$IV_BHTl-Dg.jG^j\&6._~Qޞ DT"MÆ, l/-vnJoD͹ic[tNwZ#N?^ZDI$IӵTK] IUO~%즶µ>"Y5WZv7ukflbv 1h#B{V[@p51!"|uvtp9|;?J = h>.Ւfy^JpSJiS5:k:"4$IK.K[vCP-073jeJ){JDDER'NBL5%w=Ok<6 XJb0 B):hO7U"眈&SpU: %Z /I$/}k$Aj(Kg;RW@o[ٴm!cʾJwE7T n'BW׉MyJ A8OTz.-`1.˥">ԣ]Df`{y}$It$p@KP}J`9 LNeb)*vL]'<ԁ=a_kpFE'MĬPp+ђ2+Y$I;$L5. Vڳ^6u߮ma-trc0b{ٞdau'*d#TQrMO~^w{|=$I_߱?s!$I3׮y}CS68Iιhz`وJn]?롥sjN"P!a=z3K.I$E7ݜ|:C::CAI Tݎf L'.`U"$:zS߳17k}$Օn޾c$i|/9?ϝ5Ő$ Jj896`1+p!<`.QӁV^N)u4U7c'Sߡ`3%I$ǿ-|AIU0J G7 eDXb / xԄx8PP7B6$IXpIח5B"ԁZ 1@kٙ_Qy>qpp p6p"ЉwRJ{]0DY;$I-7ܘor!$I3 1۠Jze Egkvd0^~ `wJFߣN]zl*I$^Ŵ| B覛,i2Glv5Ղ;qO~J8 BQ{?A`aՁ'BU;]2NkhۇJ$Ib3Ӗ]$Շ&"%66k=}h򑴟VCN> |pq@ 6O'xJiGJ%9ycs%"ASI$i\Ϻ$ՉJ>J"Z7xW?#a;&a]D@ۥYw(C[PP$IKo#}_s!$]vgV'ZJ sIm"Z[ l%fMf&څASsՁ5R` p/v5Hcc6v՗$IϏ/i3W>w!IR bNX-q_O& cw LT< ku~4p\y> V$I _L;W]bHT#mCLvbER)UPd` KLlUj/j"P4y*we}/$I44>kܕO平$ՀVC^j+T NK+5&bFDЫM]<{J6 ,c*zh}/$I4tۻ(3/WEnh  8 0G=g"6bL葎EfZGHg1ؒsԎ-11DA+%Pօkݾ۩RAnu߯*UT={~}R9N  pyqrwQJtf;8I$:",O%ہ-D$I_IKqC@8eѷf7)U+N!ơZ\TR9ss> |g?3 ZG.cq;X?xhK)uZR/ÈQ;6'!o$Is/>H$UwT.׊ӉΠs;\`e"|# Y*cߏ;R0K$Io"xG1(I0vEQ-zOPG\\(>VN+ng]}9$ <2w^J)m@SJi)E1s[$I!b0(I5xvzՂvw:|xڐsE1..%hǦxM{X Τܻ31xxѡ$Ir$մ}~PT \g4"l9wzqPnEx7\*Ę spo1HڈoF"LvJq|4!wC$I$I棇mąZKXMĎ!*sFA> pp63p ?Dm։Yb] ww$IT%*9Iq3ϳD $Bk|":$> Gtt?*sM`$ =H#< nJ婋cjxq\B,⹿o'$IT]V/*])5nT]*CjکPbDZlR)vU8j38KZ_~U^%^eyHXE=s}wI$z]9ij+`1$Ib5Bt ȹDg;.9s>ŇY:9a99O o8f#CcCJ +&`WJ#Q#biusw[i I$UyBj޵m5) ta` D% ąѩx1>9boTbWs z"ZX0S`+I$UT$I?Xݴ~Ƽ*I cZH(R9#FrC\lYC?Se%D8-^ͥWt+%CTLS t*#$IڱzSi5nȎwR9ؾ}+djo8+:Y` 1vORF/*8O}4hD04%x ^sv^ $IRmr{ӂHRErPܑsn%^?8FQD'9N)uK.<8gC݀SscBO\75#W/hxؗR:d8<$p='D`= Ol&FzLH$I%<}uZ|[ISj r.k \ O~1>ұ+QD ;@L5ϧ39$gV^tw>$IR,iaw I \RiÉ S/9'+Q`_s4gl@!xhsL gWsDt 'dדݚ;I$|V/*]9Ő!-M퇂ÀS}g?&Oi!}Tydt" ]D@CCt!F@|!ZJ%cqDιz CAI$7md5,KD(xlLcPK kg30b tO/?S/P\AFPI$I%Ww͂H k;".*v5\ !1]jǠ]9rΟ$von. 9"$<4<9;D3߁gM)SJc2|.)!i:=z"0o":%I$ՉM5GŐAt;kƏvۏ8%B}gąa39"S|B/.oW@6+gѡ{KcZ?S vo`$ITr;3{L "I̝p]G poJPDs΍@[JOUyNt]\Dt!]Jî4^6F"| *3}3p!BL+ $I$?|4ܾ| Pq&pw6q47$I~K;UY$Ih"B+NӎsY`9LqQ9'`,p6{݀cn]1~ymq[E,T"<D$Iǒ;uAIgs.E5n>r]X=Ę׀ˉQ#JRQv ^N\|=.:q!ӮՒ34"L,۫b"tpW :W_ [:ʈBt#F7$I0uKXN"8X@tT+/ՒY  6`0Z] < B%]&:n#wPP$IXrq o~Z36Mtl&O4,c .CfE`7 S6螚\pe̜h269ssssDx-v#8;a :boc/R[J]h[{0p7$!I$IGe8(I'gڔ,B [va< wxan81rO]Vai>T*];_׀[@pBqJl~ < ~JI'YK %I$J8wԼ͂H1R:潀)s>DZMd)nD@L^9o$:ѐ97g dD#p4>ŵD[Dwu!.` }C$I҉,./+/1{L"Icڔ-B WR9AgaXIs*b%y)֜RO% s*QN!Ƃ^ \PD`8[`GJH'#v4;9%I$T;o*tE:wVUm6o: zN'+pWPfLRJ}'1&I$i@=vdY 7^wC_U:~#]''LP~ZtbK8I۳렖@GXs|"$|Itm9o'.lkPÉ`8#¿󋿟U.3xDw5}ku_V{:+I$i4>|kϧeyWn,T7oy7ob}cyZq_08#>G{+,Вs݃u0.!F~,iL ZwI픒󴥁Um~U$I4$*ŋ7^wT#V]ES6r*Z -~/ Œm8IEtADF ۀ=Δ#FK,| pn) IDATr 8\ \]%h^x=i$Ib@(U?|{JƧo:oyyc?5.t،aD?|D*0;=> \ &n*n[>`?1 kR#A.OiDנ^Wq.G]J ARJ-$IjT?`;i6nƊ>jsE?6rPb f+eTK v{BBc݋]m~7?w䜻 kGy1 b9ĮKp20^<F1N[]J+O$IT LukmogUv 'XHN:H)!b$D(K%*<-޿!AM=5| l'@wJDzs pT'vj^<bgD+p$֭[s]6^7it/i":w[I$I`Y l?3"o}FZLajR$.G f Ax]AoFqE}ر.#F5tN% +?WVB(Y;O7EtV^@PTׁqbI$I$ղƧom|o3=}R\6}˭"zk0xA~xqqSeDX9>c78A 8(>{%l IDw4*}cdos{;( ɱFSJ$IT*},\g_5ӐP52gWΝ`WskjvďK(X9o!“δ*#F ':'|-NNBkz+݄W\=ο{m1c.K ]M%ԼnP=OtR}8̇⤌&:N'FOZ@+MA\dC\p.޶*݄]9Bl&BÜ<$:?+4";xg~ty޵87G)tn.oG4O$IT7*y߭iS/~m,BkR:sD2DrUvULJTc[΋N"i._j':*^ghT]|_fsk Ft!9O+~zqDx&%Z:2*mb4oRJ;,Tzc޲vK$Izc}>u&̾j&Ӧ\ rmt=v5>52.q_tNw:r1FзCN%JzLv z P1l':}C/ud3^GG+>~ p.CÊ`D#)hwkmk~H<} cIN4$I#h|FQN䉓 H%tUvzS~:n7o@r/:\lx}4lJ)mDRMo{?_/FK$ILp;(# $I$I4'X?Co8h.&bǠmDQ%|h@PJrI5c?516t{J۲H$I$  5>C'. ^mD߁ľ j9S"oI$I$Iέy zW\@Gy7<1 @J&wD 1.t+/a:8K$I$ 3P"+~kCڙRڛs^GF#}s^"| x3L)oL]=ű8;<%I$ICːL)s33! }xR!F ^-D`+IX@R~$I$Iz3˓'L%rާ*vrcJ+7EO}ϑRid%5c\$I$iv,B>#-:_;RppT*Y7~aX FeW&xK$I$UkZ*7o:}FT7Rڗs~Kh"T;10-U" lRJI*v`1E$I$ISj6r Q"m5)XR9#N#:CAu]_݁/{ R{xϋ)-C$I$zx -V\oxg h!> \ LĀPc 4]BۋMDHeR#ƅxA$I$I˧yݧ*Cb^`cιGO hPЩ㶽8f7o_%FY.ĈۖE$I$z8:~hQ?>h/E`:p-5$niHdbN"ܶ@>"~S#$I$IT%Z>2:j L)us;Xѳq>Ҡ&.c~o)JB7!xxR$I$I-mt5sumH 1!bf"5q7x8V%Տ@P$I$8:otLP5ؙsn#v ۧa8RT/N|廵F4W xn| I$IT}::SB㡜b.&4`40%JXLtpG1e$I$IN7^wE(K t;d`T ~Ni":_'sJ2Iu-;~_&:_%J$I$ ݺxQ&. 4c:->^M)Z$I$v-^)֮>y2`J㉱R=q>6 ;B;%}v`sbl!K"I$ITW-BI5mgs7kp1q `2=x1p.0Nj2+;Q[ CSJ^ܗt$w͔"I$ITn_rWn;Bu963<zyϓSD8h@zj}@"tnRJ=LQns˻3`OJH$I$U{XlJP8zr]@/ b20|8z-DDxx^vp%xe/TgA$I$Iܜ 3-D55o?d c:9wΈNOs;/: 5:pyxݰtzKρC_$I$Ij]rͪ㺿asλбE `))]D':kV"${[NV7uK/1$I$Iv և?|&[ As'1Aۈ1jO )DPQn"t4;߷oî@I8^$vJ$I$˯yq1H)UšDP!|:p>p 0] LcEvVnCV!"tl!T_!FH)uYFI XlJ)<$I$I.rCwO6.Ӏ3;x&p F!< ]^v-Ę u7B\[<ߺ-R  n(A$I$I!߿>P7n:1IlVRmi$I$IjKʓ'Lu`9vsp"aৈ"qѱVt`YNt J-:xۉTK>\ \=d'1~A.ޗRѐ$I$I--ma8 QRJǝֿٍ@%ȩt"4IpM G.SG:q$ƔVF򃢇n~q{Ao%:=~M ]]^ڋ]$I$I!KXf X'Nd  ":tF#D?A Oaa>Sgx ÎρxM 4^}>e@IU8z`*I$I3u{Bԉu'0: Ls>Dt :FoFw;(EohXXeD"D@ìuA~"}:-D_kCDG`Nt+MJR`,"vAI$IXrw]8}.F" ,>:rĞ{ZvK#I$ITn_rW=}#7o"sqÉ`tzþS۩zgae({c}*>"Pm)Q7ѽUʨ$:1w(>=z;ڋ[wDw!zCHGJk[K׀&:XyI$I.:Լ&^pB5& s>+ڷo 1f FPHϝD08cI; Bԧn;mz@a,Γ[3һF$I$v= :r\COe V: HD7]3K:GσXewVQ]z_c ( DfcZ$I$I5ŋ`!s'O KϞs>Z7Mt "<\`}Q뀕oWR$I$I]{EC+׮k(:e$u/ (5jY$I$IjcCSS6~ JT>8M_TI$I$հ-dž֩'$I&([0'@cJ=#I$ITf̟cSO>I}~$Uk[ӻw[)%%I$Ijܺ yڔ-DJ)Tg$Ipx--tH$I$վ_n Xox_PPrh6%1xȲH$I$վ|MX:/9a((IRm;^$R<$I$Im;sO>ӓ$զ t#CˉG$I$M;ៗ}BԹ6V/*1$6k>"($I$IR 4g!ܓi|CAIjK E":;-$I$IR9<B01$uЕj`SJ}#I$ITKXo !F$I5&`5(I$I}]- ,$I#yZ`:F]C=l$I$I%wBRJ)(IRu@phaovZ"I$Ir1P0$t7W?[I$Irp?GC%I*9狁ˀq$I$I2c0v1~\Cxv JT]#1J$I$έ@PߣCPPR:$I$IAMLJJ$I$I$ AMS6.xAgx,$I$I$I3ԱѡPI$I$Ie-:?PI$I$Im7b!tT+׮⚫NAI$I$Iij+`!tL~_k)(I$I$I45nӦ\n!tLZ?aaX$I$I$̘?/?À~}CAI$I$I~r~DqC<~ ;%I$I$Iy(B'~LϷa((I$I$It[B=} y$I$I$I'hyy:a+׮bM J$I$I$&Y {IZ$I$I$<|MXm\4A$I$I$I:F37_ڿe$I$I$I1ܱ,N`v $I$I$IgWB f )(I$I$ItDs.v_ v )(I$I$ItX{|Zo|A7$I$I$Icy{cڔ-ʵ檫=SP$I$I$e-0KNAI$I$IT`x? I>g$I$I$Ikvj|;{$I$I$Ihyy]A i|֡*I$I$I݁LM۸hC)(I$I$IƜ [ 5{{SP$I$I$Յ=P -Փ)7]?g39;%I$I$IRݺxQ޲}]k{IDATν{!I$I$IhY 7[n!OϷVPI$I$IT:w[;0vАXv\uudqv J$I$IҘ1^~6r!Ƣo='CAI$I$IT {!*,U36b$I$I$Ie.^[Z Uy%I$I$I4 (I$I$Ie88xB,\` (I$I$IsE5/ ']a(I$I$I1g~te (I$I$Id8xr5n33$I$I$IRpA~|ǗJ$I$I$L;p㵴[/2$I$I$IRm3<ּ`(I$I$Ir1ue (I$I$Ipp]n_rW޲}݁$I$I$IRz8ܚ$I$I$IŜ sk^05oJ$I$I$IkY ?_n(I$I$I$,Ѣϭy!Y@P$I$I$Io/kHGnپ5߾.@I$I$I$iM;{<[ZmoJ$I$I$ICŋϮ@@I$I$I$ܾ~ 5npL$I$I$ITn_rW~yG33 aH$I$I$էsg5Lry˴3me;6VYskWzSI%8͔haGIENDB`sphinxcontrib-django-2.5/docs/images/favicon.svg000066400000000000000000000063531450461522200220650ustar00rootroot00000000000000 sphinxcontrib-django-2.5/docs/index.rst000066400000000000000000000006221450461522200203040ustar00rootroot00000000000000Sphinx extension for Django apps ================================ `sphinxcontrib-django `__ is a sphinx extension which improves the documentation of Django apps. .. toctree:: :maxdepth: 4 :caption: Documentation README Source Code Reference Indices and tables ================== * :ref:`genindex` * :ref:`modindex` sphinxcontrib-django-2.5/docs/readme.rst000066400000000000000000000000321450461522200204250ustar00rootroot00000000000000.. include:: ../README.rstsphinxcontrib-django-2.5/docs/reference.rst000066400000000000000000000004731450461522200211370ustar00rootroot00000000000000sphinxcontrib_django ===================== .. automodule:: sphinxcontrib_django :members: :undoc-members: :show-inheritance: .. raw:: html

Docstrings

.. toctree:: docstrings Roles ----- .. automodule:: sphinxcontrib_django.roles :members: :undoc-members: :show-inheritance: sphinxcontrib-django-2.5/docs/templates/000077500000000000000000000000001450461522200204415ustar00rootroot00000000000000sphinxcontrib-django-2.5/docs/templates/layout.html000066400000000000000000000004761450461522200226530ustar00rootroot00000000000000{% extends "!layout.html" %} {% block footer %} {{ super() }} {% endblock %} sphinxcontrib-django-2.5/pyproject.toml000066400000000000000000000066601450461522200204370ustar00rootroot00000000000000[build-system] build-backend = "setuptools.build_meta" requires = ["setuptools"] [project] authors = [ { name = "Diederik van der Boor", email = "opensource@edoburu.nl" }, { name = "Timo Brembeck", email = "opensource@timo.brembeck.email" }, ] classifiers = [ "Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Framework :: Django :: 3.2", "Framework :: Django :: 4.1", "Framework :: Django :: 4.2", "Framework :: Django", "Framework :: Sphinx :: Extension", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python", "Topic :: Internet :: WWW/HTTP :: Dynamic Content", "Topic :: Internet :: WWW/HTTP", "Topic :: Software Development :: Libraries :: Application Frameworks", "Topic :: Software Development :: Libraries :: Python Modules", ] dependencies = ["Django>=3.2", "Sphinx>=3.4.0", "pprintpp"] description = "Improve the Sphinx autodoc for Django classes." dynamic = ["version"] keywords = ["django", "docstrings", "extension", "sphinx"] license = { text = "Apache2 2.0 License" } maintainers = [ { name = "Timo Brembeck", email = "opensource@timo.brembeck.email" }, ] name = "sphinxcontrib-django" readme = "README.rst" requires-python = ">=3.8" [project.urls] "Bug Tracker" = "https://github.com/edoburu/sphinxcontrib-django/issues" "Documentation" = "https://sphinxcontrib-django.readthedocs.io/" "Release Notes" = "https://github.com/edoburu/sphinxcontrib-django/blob/main/CHANGES.rst" "Source Code" = "https://github.com/edoburu/sphinxcontrib-django" [project.optional-dependencies] dev = ["pre-commit"] doc = ["sphinx-last-updated-by-git", "sphinx-rtd-theme"] optional = [ "django-mptt", "django-phonenumber-field[phonenumbers]", "psycopg2-binary", ] test = ["coverage", "pytest", "pytest-icdiff", "requests-mock"] [tool.setuptools.dynamic] version = { attr = "sphinxcontrib_django.__version__" } [tool.setuptools.packages.find] include = ["sphinxcontrib_django*"] [tool.black] skip-magic-trailing-comma = true preview = true [tool.coverage.run] command_line = "-m pytest" source = ["sphinxcontrib_django"] [tool.coverage.report] exclude_lines = [ "pragma: no cover", "if TYPE_CHECKING:", ] [tool.pytest.ini_options] addopts = "-ra -vv --color=yes" minversion = "6.0" testpaths = ["tests"] [tool.flake8] ignore = [ "D1", # Missing docstrings "E203", # whitespace before ':' in slice (incompatible with black) "E731", # Allow lambdas "F405", # name undefined due to star imports "W503", # line break before binary operator (incompatible with black) ] max-line-length = 99 [tool.isort] known_first_party = "sphinxcontrib_django" # Approach Black compatibility (just run black after isort) include_trailing_comma = true line_length = 88 multi_line_output = 3 sphinxcontrib-django-2.5/setup.py000077500000000000000000000000751450461522200172320ustar00rootroot00000000000000#!/usr/bin/env python3 from setuptools import setup setup() sphinxcontrib-django-2.5/sphinxcontrib_django/000077500000000000000000000000001450461522200217275ustar00rootroot00000000000000sphinxcontrib-django-2.5/sphinxcontrib_django/__init__.py000066400000000000000000000012651450461522200240440ustar00rootroot00000000000000""" This is a sphinx extension which improves the documentation of Django apps. """ from __future__ import annotations __version__ = "2.5" from sphinx.application import Sphinx from . import docstrings, roles def setup(app: Sphinx) -> dict: """ Allow this module to be used as sphinx extension. Setup the two sub-extensions :mod:`~sphinxcontrib_django.docstrings` and :mod:`~sphinxcontrib_django.roles` which can also be imported separately. :param app: The Sphinx application object """ docstrings.setup(app) roles.setup(app) return { "version:": __version__, "parallel_read_safe": True, "parallel_write_safe": True, } sphinxcontrib-django-2.5/sphinxcontrib_django/docstrings/000077500000000000000000000000001450461522200241065ustar00rootroot00000000000000sphinxcontrib-django-2.5/sphinxcontrib_django/docstrings/__init__.py000066400000000000000000000146701450461522200262270ustar00rootroot00000000000000""" Improve the docstrings of Django apps. For example: * List all model and form fields as parameters (see:mod:`~sphinxcontrib_django.docstrings.classes`) * Improve field representations in the documentation (see :mod:`~sphinxcontrib_django.docstrings.attributes`) * Add information about autogenerated methods (see :mod:`~sphinxcontrib_django.docstrings.methods`) * Improve the appearance of static iterable data (see :mod:`~sphinxcontrib_django.docstrings.data`) * Fix the intersphinx mappings to the Django documentation (see :mod:`~sphinxcontrib_django.docstrings.patches`) """ from __future__ import annotations import importlib import os from typing import TYPE_CHECKING import django from sphinx.errors import ConfigError from .. import __version__ from .attributes import improve_attribute_docstring from .classes import improve_class_docstring from .config import CHOICES_LIMIT, EXCLUDE_MEMBERS, INCLUDE_MEMBERS from .data import improve_data_docstring from .methods import improve_method_docstring if TYPE_CHECKING: from sphinx.application import Sphinx from sphinx.config import Config from sphinx.ext.autodoc import Options def setup(app: Sphinx) -> dict: """ Allow this package to be used as Sphinx extension. This is also called from the top-level :meth:`~sphinxcontrib_django.setup`. It connects to the sphinx events :event:`autodoc-skip-member` and :event:`autodoc-process-docstring`. Additionally, the sphinx config value ``django_settings`` is added via :meth:`~sphinx.application.Sphinx.add_config_value` and :meth:`~sphinxcontrib_django.docstrings.setup_django` is called on the :event:`config-inited` event. :param app: The Sphinx application object """ from .patches import patch_django_for_autodoc # When running, make sure Django doesn't execute querysets # Fix module paths for intersphinx mappings patch_django_for_autodoc() # Register custom event which can be emitted after Django has been set up app.add_event("django-configured") # Set default to environment variable to enable backwards compatibility app.add_config_value( "django_settings", os.environ.get("DJANGO_SETTINGS_MODULE"), True ) # Django models tables names configuration. # Set default of django_show_db_tables to False app.add_config_value("django_show_db_tables", False, True) # Set default of django_show_db_tables_abstract to False app.add_config_value("django_show_db_tables_abstract", False, True) # Integer amount of model field choices to show app.add_config_value("django_choices_to_show", CHOICES_LIMIT, True) # Setup Django after config is initialized app.connect("config-inited", setup_django) # Load sphinx.ext.autodoc extension before registering events app.setup_extension("sphinx.ext.autodoc") # Generate docstrings for Django model fields # Register the docstring processor with sphinx app.connect("autodoc-process-docstring", improve_docstring) # influence skip rules app.connect("autodoc-skip-member", autodoc_skip) return { "version:": __version__, "parallel_read_safe": True, "parallel_write_safe": True, } def setup_django(app: Sphinx, config: Config) -> None: """ This function calls :func:`django.setup` so it doesn't have to be done in the app's ``conf.py``. Called on the :event:`config-inited` event. :param app: The Sphinx application object :param config: The Sphinx configuration :raises ~sphinx.errors.ConfigError: If setting ``django_settings`` is not set correctly """ if not config.django_settings: raise ConfigError( "Please specify your Django settings in the configuration 'django_settings'" " in your conf.py" ) try: importlib.import_module(config.django_settings) except ModuleNotFoundError as e: raise ConfigError( "The module you specified in the configuration 'django_settings' in your" " conf.py cannot be imported. Make sure the module path is correct and the" " source directory is added to sys.path." ) from e os.environ["DJANGO_SETTINGS_MODULE"] = config.django_settings django.setup() # Emit event to allow code which depends on Django to run app.emit("django-configured") def autodoc_skip( app: Sphinx, what: str, name: str, obj: object, options: Options, lines: list[str] ) -> bool | None: """ Hook to tell autodoc to include or exclude certain fields (see :event:`autodoc-skip-member`). Sadly, it doesn't give a reference to the parent object, so only the ``name`` can be used for referencing. :param app: The Sphinx application object :param what: The parent type, ``class`` or ``module`` :param name: The name of the child method/attribute. :param obj: The child value (e.g. a method, dict, or module reference) :param options: The current autodoc settings. """ if name in EXCLUDE_MEMBERS: return True if name in INCLUDE_MEMBERS: return False return None def improve_docstring( app: Sphinx, what: str, name: str, obj: object, options: Options, lines: list[str] ) -> list[str]: """ Hook to improve the autodoc docstrings for Django models (see :event:`autodoc-process-docstring`). :param what: The type of the object which the docstring belongs to (one of ``module``, ``class``, ``exception``, ``function``, ``method`` and ``attribute``) :param name: The fully qualified name of the object :param obj: The documented object :param options: The options given to the directive: an object with attributes ``inherited_members``, ``undoc_members``, ``show_inheritance`` and ``noindex`` that are ``True`` if the flag option of same name was given to the auto directive :param lines: A list of strings – the lines of the processed docstring – that the event handler can modify in place to change what Sphinx puts into the output. :return: The modified list of lines """ if what == "class": improve_class_docstring(app, obj, lines) elif what == "attribute": improve_attribute_docstring(app, obj, name, lines) elif what == "method": improve_method_docstring(name, lines) elif what == "data": improve_data_docstring(obj, lines) # Return the extended docstring return lines sphinxcontrib-django-2.5/sphinxcontrib_django/docstrings/attributes.py000066400000000000000000000131331450461522200266470ustar00rootroot00000000000000""" This module contains all functions which are used to improve the documentation of attributes. """ from __future__ import annotations from django.db import models from django.db.models.fields import related_descriptors from django.db.models.fields.files import FileDescriptor from django.db.models.manager import ManagerDescriptor from django.db.models.query_utils import DeferredAttribute from django.utils.module_loading import import_string from sphinx.util.docstrings import prepare_docstring from .field_utils import get_field_type, get_field_verbose_name FIELD_DESCRIPTORS = (FileDescriptor, related_descriptors.ForwardManyToOneDescriptor) # Support for some common third party fields try: from phonenumber_field.modelfields import PhoneNumberDescriptor FIELD_DESCRIPTORS += (PhoneNumberDescriptor,) except ImportError: PhoneNumberDescriptor = None def improve_attribute_docstring(app, attribute, name, lines): """ Improve the documentation of various model fields. This improves the navigation between related objects. :param app: The Sphinx application object :type app: ~sphinx.application.Sphinx :param attribute: The instance of the object to document :type attribute: object :param name: The full dotted path to the object :type name: str :param lines: The docstring lines :type lines: list [ str ] """ # Save initial docstring lines to append them to the modified lines docstring_lines = lines.copy() lines.clear() if isinstance(attribute, DeferredAttribute): # This only points to a field name, not a field. # Get the field by importing the name. cls_path, field_name = name.rsplit(".", 1) model = import_string(cls_path) field = model._meta.get_field(field_name) if isinstance(field, models.fields.related.RelatedField): # If a deferred attribute is a related field, it is an automatically created field # with the postfix "_id" and contains the reference to the id of the related model # instance. These are usually undocumented, so they only are included in the docs # is sphinx is invoked with the undoc-members option. lines.append( f"Internal field, use :class:`~{cls_path}.{field.name}` instead." ) else: lines.extend(get_field_details(app, field)) elif isinstance(attribute, FIELD_DESCRIPTORS): # Display a reasonable output for forward descriptors (foreign key and one to one fields). lines.extend(get_field_details(app, attribute.field)) elif isinstance(attribute, related_descriptors.ManyToManyDescriptor): # Check this case first since ManyToManyDescriptor inherits from ReverseManyToOneDescriptor # This descriptor is used for both forward and reverse relationships if attribute.reverse: lines.extend(get_field_details(app, attribute.rel)) else: lines.extend(get_field_details(app, attribute.field)) elif isinstance(attribute, related_descriptors.ReverseManyToOneDescriptor): lines.extend(get_field_details(app, attribute.rel)) elif isinstance(attribute, related_descriptors.ReverseOneToOneDescriptor): lines.extend(get_field_details(app, attribute.related)) elif isinstance(attribute, (models.Manager, ManagerDescriptor)): # Somehow the 'objects' manager doesn't pass through the docstrings. module, model_name, field_name = name.rsplit(".", 2) lines.append("Django manager to access the ORM") lines.append(f"Use ``{model_name}.objects.all()`` to fetch all objects.") # Check if there are initial docstrings to be appended if docstring_lines: # Get default docstring of attribute parent_docstring = type(attribute).__doc__ # Ignore non-string __doc__ if not isinstance(parent_docstring, str): parent_docstring = "" # Only append the initial docstring of the attribute if it's overwritten if docstring_lines != prepare_docstring(parent_docstring) or not lines: if lines: # If lines are not empty, append a separating new line before docstring lines.append("") # Remove last element because it's a newline lines.extend(docstring_lines[:-1]) def get_field_details(app, field): """ This function returns the detail docstring of a model field. It includes the field type and the verbose name of the field. :param app: The Sphinx application object :type app: ~sphinx.application.Sphinx :param field: The field :type field: ~django.db.models.Field :return: The field details as list of strings :rtype: list [ str ] """ choices_limit = app.config.django_choices_to_show field_details = [ f"Type: {get_field_type(field)}", "", f"{get_field_verbose_name(field)}", ] if hasattr(field, "choices") and field.choices: field_details.extend(["", "Choices:", ""]) field_details.extend( [ f"* ``{key}``" if key != "" else "* ``''`` (Empty string)" for key, value in field.choices[:choices_limit] ] ) # Check if list has been truncated if len(field.choices) > choices_limit: # If only one element has been truncated, just list it as well if len(field.choices) == choices_limit + 1: field_details.append(f"* ``{field.choices[-1][0]}``") else: field_details.append(f"* and {len(field.choices) - choices_limit} more") return field_details sphinxcontrib-django-2.5/sphinxcontrib_django/docstrings/classes.py000066400000000000000000000133041450461522200261160ustar00rootroot00000000000000""" This module contains all functions which are used to improve the documentation of classes. """ from __future__ import annotations from django import forms from django.db import models from sphinx.application import Sphinx from sphinx.pycode import ModuleAnalyzer from .field_utils import get_field_type, get_field_verbose_name def improve_class_docstring(app: Sphinx, cls: type, lines: list[str]) -> None: """ Improve the documentation of a class if it's a Django model or form :param app: The Sphinx application object :param cls: The instance of the class to document :param lines: The docstring lines """ if issubclass(cls, models.Model): improve_model_docstring(app, cls, lines) elif issubclass(cls, forms.BaseForm): improve_form_docstring(cls, lines) def improve_model_docstring(app: Sphinx, model: models.Model, lines: list[str]) -> None: """ Improve the documentation of a Django :class:`~django.db.models.Model` subclass. This adds all model fields as parameters to the ``__init__()`` method. :param app: The Sphinx application object :param model: The instance of the model to document :param lines: The docstring lines """ # Add database table name if app.config.django_show_db_tables: add_db_table_name(app, model, lines) # Get predefined params to exclude them from the automatically inserted params param_offset = len(":param ") predefined_params = [ line[param_offset : line.find(":", param_offset)] for line in lines if line.startswith(":param ") and ":" in line[param_offset:] ] # Get all fields of this model which are not already explicitly included in the docstring all_fields = [ field for field in model._meta.get_fields(include_parents=True) if field.name not in predefined_params ] # Get all related fields (ForeignKey, OneToOneField, ManyToManyField) related_fields = [ field for field in all_fields if isinstance(field, models.fields.related.RelatedField) ] # Get all reverse relationships reverse_related_fields = [ field for field in all_fields if isinstance(field, models.fields.reverse_related.ForeignObjectRel) ] # All fields which are neither related nor reverse related non_related_fields = [ field for field in all_fields if field not in related_fields + reverse_related_fields ] # Analyze model to get inline field docstrings analyzer = ModuleAnalyzer.for_module(model.__module__) analyzer.analyze() field_docs = { field_name: field_docstring for (_, field_name), field_docstring in analyzer.attr_docs.items() } # Add the normal fields to the docstring add_model_parameters(non_related_fields, lines, field_docs) # Add the related fields if related_fields: lines.append("") lines.append("Relationship fields:") lines.append("") add_model_parameters(related_fields, lines, field_docs) # Add the reverse related fields if reverse_related_fields: lines.append("") lines.append("Reverse relationships:") lines.append("") add_model_parameters(reverse_related_fields, lines, field_docs) # Add the inheritance diagram if ( "sphinx.ext.inheritance_diagram" in app.extensions and "sphinx.ext.graphviz" in app.extensions and not any("inheritance-diagram::" in line for line in lines) ): lines.append("") lines.append(f".. inheritance-diagram:: {model.__module__}.{model.__name__}") lines.append("") def add_db_table_name(app: Sphinx, model: models.Model, lines: list[str]) -> None: """ Format and add table name by extension configuration. :param app: The Sphinx application object :param model: The instance of the model to document :param lines: The docstring lines """ if model._meta.abstract and not app.config.django_show_db_tables_abstract: return table_name = None if model._meta.abstract else model._meta.db_table lines.insert(0, "") lines.insert(0, f"**Database table:** ``{table_name}``") def add_model_parameters( fields: list[models.Field], lines: list[str], field_docs: dict ) -> None: """ Add the given fields as model parameter with the ``:param:`` directive :param fields: The list of fields :param lines: The list of current docstring lines :param field_docs: The attribute docstrings of the model """ for field in fields: # Add docstrings if they are found docstring_lines = field_docs.get(field.name, []) # Add param doc line param = f":param {field.name}: " lines.append(param + get_field_verbose_name(field)) if docstring_lines: # Separate from verbose name lines.append("") # Add and indent existing docstring lines lines.extend([(" " * len(param)) + line for line in docstring_lines]) # Add type lines.append(f":type {field.name}: {get_field_type(field, include_role=False)}") def improve_form_docstring(form: forms.Form, lines: list[str]) -> None: """ Improve the documentation of a Django :class:`~django.forms.Form` class. This highlights the available fields in the form. :param form: The form object :param lines: The list of existing docstring lines """ lines.append("**Form fields:**") lines.append("") for name, field in form.base_fields.items(): field_type = f"{field.__class__.__module__}.{field.__class__.__name__}" label = field.label or name.replace("_", " ").title() lines.append(f"* ``{name}``: {label} (:class:`~{field_type}`)") sphinxcontrib-django-2.5/sphinxcontrib_django/docstrings/config.py000066400000000000000000000013361450461522200257300ustar00rootroot00000000000000""" This module contains configuration of the members which should in-/excluded in sphinx (see :event:`autodoc-skip-member`) """ #: Ensure that the __init__ method gets documented (also see :confval:`autoclass_content` setting) INCLUDE_MEMBERS = {"__init__"} #: Members to hide. EXCLUDE_MEMBERS = { # BaseForm "base_fields", "declared_fields", "Meta", # BaseModelAdmin "declared_fieldsets", "fieldsets", # Wagtail Page "panels", "content_panels", # Polymorphic "polymorphic_primary_key_name", "polymorphic_super_sub_accessors_replaced", } #: How many choices should be shown for model fields by default, #: used as default for ``django_choices_to_show`` option CHOICES_LIMIT = 10 sphinxcontrib-django-2.5/sphinxcontrib_django/docstrings/data.py000066400000000000000000000015051450461522200253720ustar00rootroot00000000000000import io import sys from pprintpp import pprint as pp def improve_data_docstring(data, lines): """ Improve the documentation of data by pretty-printing into in the docstring. :param data: The documented object :type data: object :param lines: The lines of docstring lines :type lines: list [ str ] """ if isinstance(data, (list, tuple, dict, set)): # Redirect stdout to StringIO to catch print old_stdout = sys.stdout new_stdout = io.StringIO() sys.stdout = new_stdout # Pretty print iterable pp(data) output = new_stdout.getvalue() # Append pretty printed lines lines.append(".. code-block:: JavaScript") lines.append("") lines.append(" " + output) # Reset stdout sys.stdout = old_stdout sphinxcontrib-django-2.5/sphinxcontrib_django/docstrings/field_utils.py000066400000000000000000000143311450461522200267650ustar00rootroot00000000000000""" This module contains utility functions for fields which are used by both the :mod:`~sphinxcontrib_django.docstrings.attributes` and :mod:`~sphinxcontrib_django.docstrings.classes` modules. """ from __future__ import annotations from django.apps import apps from django.contrib import contenttypes from django.db import models from django.utils.encoding import force_str def get_field_type(field: models.Field, include_role: bool = True) -> str: """ Get the type of a field including the correct intersphinx mappings. :param field: The field :param include_directive: Whether or not the role :any:`py:class` should be included :return: The type of the field """ if isinstance(field, models.fields.related.RelatedField): to = field.remote_field.model if isinstance(to, str): # This happens with foreign keys of abstract models to = get_model_from_string(field, to) return ( f":class:`~{type(field).__module__}.{type(field).__name__}` to" f" :class:`~{to.__module__}.{to.__name__}`" ) if isinstance(field, models.fields.reverse_related.ForeignObjectRel): to = field.remote_field.model return ( "Reverse" f" :class:`~{type(field.remote_field).__module__}.{type(field.remote_field).__name__}`" f" from :class:`~{to.__module__}.{to.__name__}`" ) if include_role: # For the docstrings of attributes, the :class: role is required return f":class:`~{type(field).__module__}.{type(field).__name__}`" # For the :param: role in class docstrings, the :class: role is not required return f"~{type(field).__module__}.{type(field).__name__}" def get_field_verbose_name(field: models.Field) -> str: """ Get the verbose name of the field. If the field has a ``help_text``, it is also included. In case the field is a related field, the ``related_name`` is used to link to the remote model. For reverse related fields, the originating field is linked. :param field: The field """ help_text = "" # Check whether the field is a reverse related field if isinstance(field, models.fields.reverse_related.ForeignObjectRel): # Convert related name to a readable name if ``snake_case`` is used related_name = ( field.related_name.replace("_", " ") if field.related_name else None ) if isinstance(field, models.fields.reverse_related.OneToOneRel): # If a related name is given, use it, else use the verbose name of the remote model related_name = related_name or field.remote_field.model._meta.verbose_name # If field is a OneToOne field, use the prefix "The" verbose_name = ( f"The {related_name} of this {field.model._meta.verbose_name}" ) else: # This means field is an instance of ManyToOneRel or ManyToManyRel # If a related name is given, use it, else use the verbose name of the remote model related_name = ( related_name or field.remote_field.model._meta.verbose_name_plural ) # If field is a foreign key or a ManyToMany field, use the prefix "All" verbose_name = ( f"All {related_name} of this {field.model._meta.verbose_name}" ) # Link to the origin of the reverse related field if it's not from an abstract model if not field.remote_field.model._meta.abstract: verbose_name += ( f" (related name of :attr:`~{field.remote_field.model.__module__}" f".{field.remote_field.model.__name__}.{field.remote_field.name}`)" ) elif hasattr(contenttypes, "fields") and isinstance( field, contenttypes.fields.GenericForeignKey ): # GenericForeignKey does not inherit from django.db.models.Field and has no verbose_name return ( "Generic foreign key to the" " :class:`~django.contrib.contenttypes.models.ContentType` specified in" f" :attr:`~{field.model.__module__}.{field.model.__name__}.{field.ct_field}`" ) else: # This means the field is either a normal field or a forward related field # If the field is a primary key, include a notice primary_key = "Primary key: " if field.primary_key else "" field_verbose_name = force_str(field.verbose_name) # Make the first letter upper case while leave the rest unchanged # (str.capitalize() would make the rest lower case, e.g. ID => Id) verbose_name = ( primary_key + field_verbose_name[:1].upper() + field_verbose_name[1:] ) help_text = force_str(field.help_text) # Add help text if field has one if help_text: # Separate verbose name and help text by a dot if not verbose_name.endswith("."): verbose_name += ". " verbose_name += help_text if isinstance(field, models.fields.related.RelatedField): # If field is a forward related field, reference the remote model to = field.remote_field.model if isinstance(to, str): # This happens with foreign keys of abstract models to = get_model_from_string(field, to) # If a related name is defined if hasattr(field.remote_field, "related_name"): related_name = ( field.remote_field.related_name or field.model.__name__.lower() ) # Link to the related field if it's not an abstract model if not field.model._meta.abstract: verbose_name += ( " (related name:" f" :attr:`~{to.__module__}.{to.__name__}.{related_name}`)" ) return verbose_name def get_model_from_string(field: models.Field, model_string: str) -> type[models.Model]: """ Get a model class from a string :param field: The field :param model_string: The string label of the model :return: The class of the model """ if "." in model_string: model = apps.get_model(model_string) elif model_string == "self": model = field.model else: model = apps.get_model(field.model._meta.app_label, model_string) return model sphinxcontrib-django-2.5/sphinxcontrib_django/docstrings/methods.py000066400000000000000000000040321450461522200261220ustar00rootroot00000000000000""" This module contains all functions which are used to improve the documentation of methods. """ import re RE_GET_FOO_DISPLAY = re.compile(r"\.get_(?P[a-zA-Z0-9_]+)_display$") RE_GET_NEXT_BY = re.compile(r"\.get_next_by_(?P[a-zA-Z0-9_]+)$") RE_GET_PREVIOUS_BY = re.compile(r"\.get_previous_by_(?P[a-zA-Z0-9_]+)$") def improve_method_docstring(name, lines): """ Improve the documentation of methods automatically contributed to models by Django: * :meth:`~django.db.models.Model.get_FOO_display` * :meth:`~django.db.models.Model.get_next_by_FOO` * :meth:`~django.db.models.Model.get_previous_by_FOO` :param name: The full dotted path to the object. :type name: str :param lines: The lines of docstring lines :type lines: list [ str ] """ if not lines: # Not doing obj.__module__ lookups to avoid performance issues. if name.endswith("_display"): match = RE_GET_FOO_DISPLAY.search(name) if match is not None: # Django get_..._display method lines.append( f"Shows the label of the :attr:`{match.group('field')}`. See" " :meth:`~django.db.models.Model.get_FOO_display` for more" " information." ) elif ".get_next_by_" in name: match = RE_GET_NEXT_BY.search(name) if match is not None: lines.append( f"Finds next instance based on :attr:`{match.group('field')}`. See" " :meth:`~django.db.models.Model.get_next_by_FOO` for more" " information." ) elif ".get_previous_by_" in name: match = RE_GET_PREVIOUS_BY.search(name) if match is not None: lines.append( f"Finds previous instance based on :attr:`{match.group('field')}`." " See :meth:`~django.db.models.Model.get_previous_by_FOO` for more" " information." ) sphinxcontrib-django-2.5/sphinxcontrib_django/docstrings/patches.py000066400000000000000000000064701450461522200261160ustar00rootroot00000000000000""" This module contains patches for Django to improve its interaction with Sphinx. """ import contextlib from django import apps, forms, test from django.db import models try: from django.contrib.postgres import fields as postgres_fields from django.contrib.postgres import forms as postgres_forms POSTGRES = True except ModuleNotFoundError: # In case postgres is not used, pass POSTGRES = False try: from mptt.managers import TreeManager MPTT = True except ModuleNotFoundError: # In case postgres is not used, pass MPTT = False def patch_django_for_autodoc(): """ Fix the appearance of some classes in autodoc. E.g. the absolute path to the base model class is ``django.db.models.base.Model``, but its intersphinx mapping path is ``django.db.models.Model``. This also avoids query evaluation. """ # Fix Django's manager appearance models.manager.ManagerDescriptor.__get__ = ( lambda self, *args, **kwargs: self.manager ) # Stop Django from executing DB queries models.QuerySet.__repr__ = lambda self: self.__class__.__name__ # Fix django-mptt TreeManager in Django >=3.1 if MPTT: TreeManager.get_queryset = models.Manager.get_queryset # Module paths which are documented in the parent module DJANGO_MODULE_PATHS = { "django.db.models": [ models.base, models.fields, models.fields.files, models.fields.related, ], "django.forms": [forms.forms, forms.fields, forms.models, forms.widgets], "django.test": [test], "django.apps": [apps], } # Support django.db.models.JSONField in Django >= 3.1 if hasattr(models.fields, "json"): DJANGO_MODULE_PATHS["django.db.models"].append(models.fields.json) # Support postgres fields if used if POSTGRES: DJANGO_MODULE_PATHS["django.contrib.postgres.forms"] = [postgres_forms.array] # Support django.contrib.postgres.forms.JSONField in Django <= 3.2 if hasattr(postgres_forms, "jsonb"): DJANGO_MODULE_PATHS["django.contrib.postgres.forms"].append( postgres_forms.jsonb ) postgres_forms.jsonb.__all__ = ("JSONString", "JSONField") DJANGO_MODULE_PATHS["django.contrib.postgres.fields"] = [postgres_fields.array] if hasattr(postgres_fields, "jsonb"): DJANGO_MODULE_PATHS["django.contrib.postgres.forms"].append( postgres_fields.jsonb ) postgres_forms.array.__all__ = ("SimpleArrayField", "SplitArrayField") # Add __all__ where missing models.base.__all__ = ("Model", "FilteredRelation") models.fields.files.__all__ = ("FileField", "ImageField") models.fields.related.__all__ = ("ForeignKey", "OneToOneField", "ManyToManyField") # Set the __module__ to the parent module to make sure intersphinx mappings work as expected for parent_module_str, django_modules in DJANGO_MODULE_PATHS.items(): for django_module in django_modules: for module_class in map(django_module.__dict__.get, django_module.__all__): with contextlib.suppress(AttributeError): module_class.__module__ = parent_module_str # Fix module path of model manager models.manager.Manager.__module__ = "django.db.models" sphinxcontrib-django-2.5/sphinxcontrib_django/roles.py000066400000000000000000000062251450461522200234320ustar00rootroot00000000000000""" This module adds cross-reference types which are used in the documentation of Django and Sphinx to allow intersphinx mappings to these custom types. The supported text roles are: Django: * ``:setting:``, e.g. ``:setting:`INSTALLED_APPS``` renders as :setting:`INSTALLED_APPS` * ``:templatetag:``, e.g. ``:templatetag:`block``` renders as :templatetag:`block` * ``:templatefilter:``, e.g. ``:templatefilter:`add``` renders as :templatefilter:`add` * ``:fieldlookup:``, e.g. ``:fieldlookup:`equals``` renders as :fieldlookup:`equals` Sphinx: * ``:event:``, e.g. ``:event:`autodoc-skip-member``` renders as :event:`autodoc-skip-member` * ``:confval:``, e.g. ``:confval:`extensions``` renders as :confval:`extensions` This module can also be used separately in ``conf.py``:: extensions = [ "sphinxcontrib_django.roles", ] """ from __future__ import annotations import logging from sphinx.application import Sphinx from sphinx.config import Config from sphinx.errors import ExtensionError from . import __version__ logger = logging.getLogger(__name__) def setup(app: Sphinx) -> dict: """ Allow this module to be used as Sphinx extension. This is also called from the top-level :meth:`~sphinxcontrib_django.setup`. It adds cross-reference types via :meth:`~sphinx.application.Sphinx.add_crossref_type`. :param app: The Sphinx application object """ # Load sphinx.ext.intersphinx extension app.setup_extension("sphinx.ext.intersphinx") # Add default intersphinx mappings after config is initialized app.connect("config-inited", add_default_intersphinx_mappings) # Allow intersphinx mappings to custom Django roles django_crossref_types = ["setting", "templatetag", "templatefilter", "fieldlookup"] # Allow intersphinx mappings to custom Sphinx roles sphinx_crossref_types = ["event", "confval"] for crossref_type in django_crossref_types + sphinx_crossref_types: try: app.add_crossref_type(directivename=crossref_type, rolename=crossref_type) except ExtensionError as e: logger.warning("Unable to register cross-reference type: %s", e) return { "version:": __version__, "parallel_read_safe": True, "parallel_write_safe": True, } def add_default_intersphinx_mappings(app: Sphinx, config: Config) -> None: """ This function provides a default intersphinx mapping to the documentations of Python, Django and Sphinx if ``intersphinx_mapping`` is not given in ``conf.py``. Called on the :event:`config-inited` event. :param app: The Sphinx application object :param config: The Sphinx configuration """ DEFAULT_INTERSPHINX_MAPPING = { "python": ("https://docs.python.org/", None), "sphinx": ("https://www.sphinx-doc.org/en/master/", None), "django": ( "https://docs.djangoproject.com/en/stable/", "https://docs.djangoproject.com/en/stable/_objects/", ), } if not config.intersphinx_mapping: # TYPING: type hints are missing `.intersphinx_mapping` attribute. config.intersphinx_mapping = DEFAULT_INTERSPHINX_MAPPING # type: ignore[attr-defined ] sphinxcontrib-django-2.5/tests/000077500000000000000000000000001450461522200166555ustar00rootroot00000000000000sphinxcontrib-django-2.5/tests/conftest.py000066400000000000000000000045611450461522200210620ustar00rootroot00000000000000""" The recommended setup for testing sphinx extension is undocumented (see issue #7008: https://github.com/sphinx-doc/sphinx/issues/7008), so this setup was created using the given code snippets and the existing test cases for the autodoc extension. """ from unittest.mock import Mock import pytest from sphinx.ext.autodoc.directive import DocumenterBridge, process_documenter_options from sphinx.testing.path import path from sphinx.util.docutils import LoggingReporter pytest_plugins = "sphinx.testing.fixtures" @pytest.fixture(scope="session") def rootdir(): """ Path to the root directory of the testing targets """ return path(__file__).parent.abspath() / "roots" @pytest.fixture(scope="function") def app(test_params, app_params, make_app, shared_result, requests_mock): """ Overwrite sphinx.testing.fixtures.app to take the additional fixture requests_mock to fake intersphinx requests """ args, kwargs = app_params app_ = make_app(*args, **kwargs) yield app_ @pytest.fixture(scope="function") def setup_app_with_different_config(app_params, make_app): """ Simulate the setup of the sphinx app with a different config Return the function instead of the final app object to make sure exceptions occur inside the test and not inside the fixture """ def setup_app_with_different_config(**confoverrides): args, kwargs = app_params kwargs["confoverrides"] = confoverrides return make_app(*args, **kwargs) return setup_app_with_different_config @pytest.fixture(scope="function") def do_autodoc(): """ This function simulates the autodoc functionality. Taken from https://github.com/sphinx-doc/sphinx/blob/d635d94eebbca0ebb1a5402aa07ed58c0464c6d3/tests/test_ext_autodoc.py#L33-L45 # noqa: E501 """ def do_autodoc(app, objtype, name, options=None): if options is None: options = {} app.env.temp_data.setdefault("docname", "index") # set dummy docname doccls = app.registry.documenters[objtype] docoptions = process_documenter_options(doccls, app.config, options) state = Mock() state.document.settings.tab_width = 8 bridge = DocumenterBridge(app.env, LoggingReporter(""), docoptions, 1, state) documenter = doccls(bridge, name) documenter.generate() return bridge.result return do_autodoc sphinxcontrib-django-2.5/tests/roots/000077500000000000000000000000001450461522200200235ustar00rootroot00000000000000sphinxcontrib-django-2.5/tests/roots/test-docstrings/000077500000000000000000000000001450461522200231575ustar00rootroot00000000000000sphinxcontrib-django-2.5/tests/roots/test-docstrings/conf.py000066400000000000000000000012431450461522200244560ustar00rootroot00000000000000import os import sys # Add directory containing dummy app to sys.path sys.path.insert(0, os.path.abspath(".")) project = "sphinx dummy Test" extensions = [ "sphinxcontrib_django", "sphinx.ext.graphviz", "sphinx.ext.inheritance_diagram", ] # Configure Django settings module django_settings = "dummy_django_app.settings" nitpicky = True def patch_django_for_autodoc(app): """ Monkeypatch application """ from dummy_django_app.models import MonkeyPatched MonkeyPatched.__doc__ = "Monkeypatched docstring" def setup(app): # Run method after Django config is initialized app.connect("django-configured", patch_django_for_autodoc) sphinxcontrib-django-2.5/tests/roots/test-docstrings/conflicting_sphinx_extension.py000066400000000000000000000003301450461522200315110ustar00rootroot00000000000000def setup(app): """ Sphinx extension which also registers a "setting" directive """ app.add_crossref_type( directivename="setting", rolename="setting", indextemplate="pair: %s; setting" ) sphinxcontrib-django-2.5/tests/roots/test-docstrings/dummy_django_app/000077500000000000000000000000001450461522200264745ustar00rootroot00000000000000sphinxcontrib-django-2.5/tests/roots/test-docstrings/dummy_django_app/forms.py000066400000000000000000000007431450461522200302000ustar00rootroot00000000000000from __future__ import annotations from django import forms from .models import SimpleModel class SimpleForm(forms.ModelForm): test1 = forms.CharField(label="Test1") test2 = forms.CharField(help_text="Test2") def __init__(self, *args, **kwargs) -> None: """ This is a custom init method """ super().__init__(*args, **kwargs) class Meta: model = SimpleModel fields = ("file", "childA", "childrenB", "dummy_field") sphinxcontrib-django-2.5/tests/roots/test-docstrings/dummy_django_app/models.py000066400000000000000000000061701450461522200303350ustar00rootroot00000000000000from __future__ import annotations from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType from django.db import models from sphinxcontrib_django.docstrings.config import CHOICES_LIMIT try: from phonenumber_field.modelfields import PhoneNumberField PHONENUMBER = True except ModuleNotFoundError: # In case phonenumber is not used, pass PHONENUMBER = False class SimpleModelManager(models.Manager): pass class FileModel(models.Model): upload = models.FileField() class SimpleModel(models.Model): #: Docstring of foreign key file = models.ForeignKey( "FileModel", related_name="simple_models", on_delete=models.CASCADE ) #: Docstring of one to one field childA = models.OneToOneField( "ChildModelA", related_name="simple_model", on_delete=models.CASCADE ) childrenB = models.ManyToManyField("ChildModelB", related_name="simple_models") """ Docstring of many to many field .. note:: This syntax is also supported. """ #: Docstring of char field #: #: .. warning:: #: #: Inline directives should be preserved. dummy_field = models.CharField( max_length=3, help_text="This should help you", verbose_name="Very verbose name of dummy field", ) #: Custom model manager custom_objects = SimpleModelManager() # Mock get_..._display method of Django models def get_dummy_field_display(self): pass # Mock common get_next_by_ method def get_next_by_dummy_field(self): pass # Mock common get_previous_by_ method def get_previous_by_dummy_field(self): pass class AbstractModel(models.Model): simple_model = models.ForeignKey("SimpleModel", on_delete=models.CASCADE) user = models.ForeignKey("auth.User", related_name="+", on_delete=models.CASCADE) foreignkey_self = models.ForeignKey("self", on_delete=models.CASCADE) class Meta: abstract = True class ChildModelA(AbstractModel): pass class ChildModelB(AbstractModel): pass class ChoiceModel(models.Model): choice_limit_below = models.IntegerField( choices=[(i, i) for i in range(CHOICES_LIMIT - 1)] ) choice_limit_exact = models.IntegerField( choices=[(i, i) for i in range(CHOICES_LIMIT + 1)] ) choice_limit_above = models.IntegerField( choices=[(i, i) for i in range(CHOICES_LIMIT + 2)] ) choice_with_empty = models.CharField( choices=[("", "Empty"), ("Something", "Not empty")] ) class TaggedItem(models.Model): # Test model taken from: # https://docs.djangoproject.com/en/stable/ref/contrib/contenttypes/#generic-relations tag = models.SlugField() content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) object_id = models.PositiveIntegerField() content_object = GenericForeignKey("content_type", "object_id") def __str__(self) -> str: return self.tag if PHONENUMBER: class PhoneNumberModel(models.Model): phone_number = PhoneNumberField() class MonkeyPatched(models.Model): pass sphinxcontrib-django-2.5/tests/roots/test-docstrings/dummy_django_app/settings.py000066400000000000000000000003311450461522200307030ustar00rootroot00000000000000""" Dummy Django settings file """ SECRET_KEY = "dummy-key" #: These are the installed apps INSTALLED_APPS = [ "django.contrib.auth", "django.contrib.contenttypes", "dummy_django_app", ] USE_TZ = False sphinxcontrib-django-2.5/tests/test_attribute_docstrings.py000066400000000000000000000306701450461522200245360ustar00rootroot00000000000000import pytest try: from phonenumber_field.modelfields import PhoneNumberField # noqa: F401 PHONENUMBER = True except ModuleNotFoundError: # In case phonenumber is not used, pass PHONENUMBER = False @pytest.mark.sphinx("html", testroot="docstrings") def test_model_field(app, do_autodoc): actual = do_autodoc( app, "attribute", "dummy_django_app.models.SimpleModel.dummy_field" ) print(actual) assert list(actual) == [ "", ".. py:attribute:: SimpleModel.dummy_field", " :module: dummy_django_app.models", "", " Type: :class:`~django.db.models.CharField`", "", " Very verbose name of dummy field. This should help you", "", " Docstring of char field", "", " .. warning::", "", " Inline directives should be preserved.", "", ] @pytest.mark.sphinx("html", testroot="docstrings") def test_foreignkey(app, do_autodoc): actual = do_autodoc(app, "attribute", "dummy_django_app.models.SimpleModel.file") print(actual) assert list(actual) == [ "", ".. py:attribute:: SimpleModel.file", " :module: dummy_django_app.models", "", ( " Type: :class:`~django.db.models.ForeignKey` to" " :class:`~dummy_django_app.models.FileModel`" ), "", ( " File (related name:" " :attr:`~dummy_django_app.models.FileModel.simple_models`)" ), "", " Docstring of foreign key", "", ] @pytest.mark.sphinx("html", testroot="docstrings") def test_foreignkey_id(app, do_autodoc): actual = do_autodoc(app, "attribute", "dummy_django_app.models.SimpleModel.file_id") print(actual) assert list(actual) == [ "", ".. py:attribute:: SimpleModel.file_id", " :module: dummy_django_app.models", "", ( " Internal field, use :class:`~dummy_django_app.models.SimpleModel.file`" " instead." ), "", ] @pytest.mark.sphinx("html", testroot="docstrings") def test_foreignkey_string(app, do_autodoc): actual = do_autodoc(app, "attribute", "dummy_django_app.models.SimpleModel.file") print(actual) assert list(actual) == [ "", ".. py:attribute:: SimpleModel.file", " :module: dummy_django_app.models", "", ( " Type: :class:`~django.db.models.ForeignKey` to" " :class:`~dummy_django_app.models.FileModel`" ), "", ( " File (related name:" " :attr:`~dummy_django_app.models.FileModel.simple_models`)" ), "", " Docstring of foreign key", "", ] @pytest.mark.sphinx("html", testroot="docstrings") def test_foreignkey_string_abstract_model(app, do_autodoc): actual = do_autodoc( app, "attribute", "dummy_django_app.models.AbstractModel.simple_model" ) print(actual) assert list(actual) == [ "", ".. py:attribute:: AbstractModel.simple_model", " :module: dummy_django_app.models", "", ( " Type: :class:`~django.db.models.ForeignKey` to" " :class:`~dummy_django_app.models.SimpleModel`" ), "", " Simple model", "", ] @pytest.mark.sphinx("html", testroot="docstrings") def test_reverse_foreignkey(app, do_autodoc): actual = do_autodoc( app, "attribute", "dummy_django_app.models.FileModel.simple_models" ) print(actual) assert list(actual) == [ "", ".. py:attribute:: FileModel.simple_models", " :module: dummy_django_app.models", "", ( " Type: Reverse :class:`~django.db.models.ForeignKey` from" " :class:`~dummy_django_app.models.SimpleModel`" ), "", ( " All simple models of this file model (related name of" " :attr:`~dummy_django_app.models.SimpleModel.file`)" ), "", ] @pytest.mark.sphinx("html", testroot="docstrings") def test_manytomany_field(app, do_autodoc): actual = do_autodoc( app, "attribute", "dummy_django_app.models.SimpleModel.childrenB" ) print(actual) assert list(actual) == [ "", ".. py:attribute:: SimpleModel.childrenB", " :module: dummy_django_app.models", "", ( " Type: :class:`~django.db.models.ManyToManyField` to" " :class:`~dummy_django_app.models.ChildModelB`" ), "", ( " ChildrenB (related name:" " :attr:`~dummy_django_app.models.ChildModelB.simple_models`)" ), "", " Docstring of many to many field", "", " .. note::", "", " This syntax is also supported.", "", ] @pytest.mark.sphinx("html", testroot="docstrings") def test_reverse_manytomany_field(app, do_autodoc): actual = do_autodoc( app, "attribute", "dummy_django_app.models.ChildModelB.simple_models" ) print(actual) assert list(actual) == [ "", ".. py:attribute:: ChildModelB.simple_models", " :module: dummy_django_app.models", "", ( " Type: Reverse :class:`~django.db.models.ManyToManyField` from" " :class:`~dummy_django_app.models.SimpleModel`" ), "", ( " All simple models of this child model b (related name of" " :attr:`~dummy_django_app.models.SimpleModel.childrenB`)" ), "", ] @pytest.mark.sphinx("html", testroot="docstrings") def test_reverse_onetoone_field(app, do_autodoc): actual = do_autodoc( app, "attribute", "dummy_django_app.models.ChildModelA.simple_model" ) print(actual) assert list(actual) == [ "", ".. py:attribute:: ChildModelA.simple_model", " :module: dummy_django_app.models", "", ( " Type: Reverse :class:`~django.db.models.OneToOneField` from" " :class:`~dummy_django_app.models.SimpleModel`" ), "", ( " The simple model of this child model a (related name of" " :attr:`~dummy_django_app.models.SimpleModel.childA`)" ), "", ] @pytest.mark.sphinx("html", testroot="docstrings") def test_generic_foreign_key(app, do_autodoc): actual = do_autodoc( app, "attribute", "dummy_django_app.models.TaggedItem.content_object" ) print(actual) assert list(actual) == [ "", ".. py:attribute:: TaggedItem.content_object", " :module: dummy_django_app.models", "", " Provide a generic many-to-one relation through the ``content_type`` and", " ``object_id`` fields.", "", " This class also doubles as an accessor to the related object (similar to", " ForwardManyToOneDescriptor) by adding itself as a model attribute.", "", ] @pytest.mark.sphinx("html", testroot="docstrings") def test_model_manager_fields(app, do_autodoc): actual = do_autodoc( app, "attribute", "dummy_django_app.models.SimpleModel.custom_objects" ) print(actual) assert list(actual) == [ "", ".. py:attribute:: SimpleModel.custom_objects", " :module: dummy_django_app.models", " :value: ", "", " Django manager to access the ORM", " Use ``SimpleModel.objects.all()`` to fetch all objects.", "", " Custom model manager", "", ] @pytest.mark.sphinx("html", testroot="docstrings") def test_file_field(app, do_autodoc): actual = do_autodoc(app, "attribute", "dummy_django_app.models.FileModel.upload") print(actual) assert list(actual) == [ "", ".. py:attribute:: FileModel.upload", " :module: dummy_django_app.models", "", " Type: :class:`~django.db.models.FileField`", "", " Upload", "", ] @pytest.mark.sphinx("html", testroot="docstrings") def test_choice_field(app, do_autodoc): actual = do_autodoc( app, "attribute", "dummy_django_app.models.ChoiceModel.choice_limit_below" ) print(actual) assert list(actual) == [ "", ".. py:attribute:: ChoiceModel.choice_limit_below", " :module: dummy_django_app.models", "", " Type: :class:`~django.db.models.IntegerField`", "", " Choice limit below", "", " Choices:", "", " * ``0``", " * ``1``", " * ``2``", " * ``3``", " * ``4``", " * ``5``", " * ``6``", " * ``7``", " * ``8``", "", ] @pytest.mark.sphinx("html", testroot="docstrings") def test_choice_field_limit_exact(app, do_autodoc): actual = do_autodoc( app, "attribute", "dummy_django_app.models.ChoiceModel.choice_limit_exact" ) print(actual) assert list(actual) == [ "", ".. py:attribute:: ChoiceModel.choice_limit_exact", " :module: dummy_django_app.models", "", " Type: :class:`~django.db.models.IntegerField`", "", " Choice limit exact", "", " Choices:", "", " * ``0``", " * ``1``", " * ``2``", " * ``3``", " * ``4``", " * ``5``", " * ``6``", " * ``7``", " * ``8``", " * ``9``", " * ``10``", "", ] @pytest.mark.sphinx("html", testroot="docstrings") def test_choice_field_limit_above(app, do_autodoc): actual = do_autodoc( app, "attribute", "dummy_django_app.models.ChoiceModel.choice_limit_above" ) print(actual) assert list(actual) == [ "", ".. py:attribute:: ChoiceModel.choice_limit_above", " :module: dummy_django_app.models", "", " Type: :class:`~django.db.models.IntegerField`", "", " Choice limit above", "", " Choices:", "", " * ``0``", " * ``1``", " * ``2``", " * ``3``", " * ``4``", " * ``5``", " * ``6``", " * ``7``", " * ``8``", " * ``9``", " * and 2 more", "", ] @pytest.mark.sphinx( "html", testroot="docstrings", confoverrides={"django_choices_to_show": 15} ) def test_choice_field_custom_limit(app, do_autodoc): actual = do_autodoc( app, "attribute", "dummy_django_app.models.ChoiceModel.choice_limit_above" ) print(actual) assert list(actual) == [ "", ".. py:attribute:: ChoiceModel.choice_limit_above", " :module: dummy_django_app.models", "", " Type: :class:`~django.db.models.IntegerField`", "", " Choice limit above", "", " Choices:", "", " * ``0``", " * ``1``", " * ``2``", " * ``3``", " * ``4``", " * ``5``", " * ``6``", " * ``7``", " * ``8``", " * ``9``", " * ``10``", " * ``11``", "", ] @pytest.mark.sphinx("html", testroot="docstrings") def test_choice_field_empty(app, do_autodoc): actual = do_autodoc( app, "attribute", "dummy_django_app.models.ChoiceModel.choice_with_empty" ) print(actual) assert list(actual) == [ "", ".. py:attribute:: ChoiceModel.choice_with_empty", " :module: dummy_django_app.models", "", " Type: :class:`~django.db.models.CharField`", "", " Choice with empty", "", " Choices:", "", " * ``''`` (Empty string)", " * ``Something``", "", ] if PHONENUMBER: @pytest.mark.sphinx("html", testroot="docstrings") def test_phonenumber_field(app, do_autodoc): actual = do_autodoc( app, "attribute", "dummy_django_app.models.PhoneNumberModel.phone_number" ) print(actual) assert list(actual) == [ "", ".. py:attribute:: PhoneNumberModel.phone_number", " :module: dummy_django_app.models", "", " Type: :class:`~phonenumber_field.modelfields.PhoneNumberField`", "", " Phone number", "", ] sphinxcontrib-django-2.5/tests/test_autodoc_skip.py000066400000000000000000000010601450461522200227470ustar00rootroot00000000000000import pytest @pytest.mark.sphinx("html", testroot="docstrings") def test_exclude_members(app, do_autodoc): options = {"members": None, "undoc-members": None} assert not any( "base_fields" in line for line in do_autodoc(app, "module", "dummy_django_app.forms", options) ) @pytest.mark.sphinx("html", testroot="docstrings") def test_include_members(app, do_autodoc): options = {"members": None} assert any( "__init__" in line for line in do_autodoc(app, "module", "dummy_django_app.forms", options) ) sphinxcontrib-django-2.5/tests/test_class_docstrings.py000066400000000000000000000322161450461522200236360ustar00rootroot00000000000000import pytest @pytest.mark.sphinx("html", testroot="docstrings") def test_simple_model(app, do_autodoc): actual = do_autodoc(app, "class", "dummy_django_app.models.SimpleModel") print(actual) assert list(actual) == [ "", ".. py:class:: SimpleModel(id, file, childA, dummy_field)", " :module: dummy_django_app.models", "", " :param id: Primary key: ID", " :type id: ~django.db.models.AutoField", " :param dummy_field: Very verbose name of dummy field. This should help you", "", " Docstring of char field", "", " .. warning::", "", " Inline directives should be preserved.", "", " :type dummy_field: ~django.db.models.CharField", "", " Relationship fields:", "", ( " :param file: File (related name:" " :attr:`~dummy_django_app.models.FileModel.simple_models`)" ), "", " Docstring of foreign key", "", ( " :type file: :class:`~django.db.models.ForeignKey` to" " :class:`~dummy_django_app.models.FileModel`" ), ( " :param childA: ChildA (related name:" " :attr:`~dummy_django_app.models.ChildModelA.simple_model`)" ), "", " Docstring of one to one field", "", ( " :type childA: :class:`~django.db.models.OneToOneField` to" " :class:`~dummy_django_app.models.ChildModelA`" ), ( " :param childrenB: ChildrenB (related name:" " :attr:`~dummy_django_app.models.ChildModelB.simple_models`)" ), "", " Docstring of many to many field", "", " .. note::", "", " This syntax is also supported.", "", ( " :type childrenB: :class:`~django.db.models.ManyToManyField` to" " :class:`~dummy_django_app.models.ChildModelB`" ), "", " Reverse relationships:", "", ( " :param childmodela: All child model as of this simple model (related" " name of :attr:`~dummy_django_app.models.ChildModelA.simple_model`)" ), ( " :type childmodela: Reverse :class:`~django.db.models.ForeignKey` from" " :class:`~dummy_django_app.models.ChildModelA`" ), ( " :param childmodelb: All child model bs of this simple model (related" " name of :attr:`~dummy_django_app.models.ChildModelB.simple_model`)" ), ( " :type childmodelb: Reverse :class:`~django.db.models.ForeignKey` from" " :class:`~dummy_django_app.models.ChildModelB`" ), "", " .. inheritance-diagram:: dummy_django_app.models.SimpleModel", "", ] @pytest.mark.sphinx( "html", testroot="docstrings", confoverrides={"django_show_db_tables": True} ) def test_database_table(app, do_autodoc): actual = do_autodoc(app, "class", "dummy_django_app.models.SimpleModel") print(actual) assert list(actual) == [ "", ".. py:class:: SimpleModel(id, file, childA, dummy_field)", " :module: dummy_django_app.models", "", " **Database table:** ``dummy_django_app_simplemodel``", "", " :param id: Primary key: ID", " :type id: ~django.db.models.AutoField", " :param dummy_field: Very verbose name of dummy field. This should help you", "", " Docstring of char field", "", " .. warning::", "", " Inline directives should be preserved.", "", " :type dummy_field: ~django.db.models.CharField", "", " Relationship fields:", "", ( " :param file: File (related name:" " :attr:`~dummy_django_app.models.FileModel.simple_models`)" ), "", " Docstring of foreign key", "", ( " :type file: :class:`~django.db.models.ForeignKey` to" " :class:`~dummy_django_app.models.FileModel`" ), ( " :param childA: ChildA (related name:" " :attr:`~dummy_django_app.models.ChildModelA.simple_model`)" ), "", " Docstring of one to one field", "", ( " :type childA: :class:`~django.db.models.OneToOneField` to" " :class:`~dummy_django_app.models.ChildModelA`" ), ( " :param childrenB: ChildrenB (related name:" " :attr:`~dummy_django_app.models.ChildModelB.simple_models`)" ), "", " Docstring of many to many field", "", " .. note::", "", " This syntax is also supported.", "", ( " :type childrenB: :class:`~django.db.models.ManyToManyField` to" " :class:`~dummy_django_app.models.ChildModelB`" ), "", " Reverse relationships:", "", ( " :param childmodela: All child model as of this simple model (related" " name of :attr:`~dummy_django_app.models.ChildModelA.simple_model`)" ), ( " :type childmodela: Reverse :class:`~django.db.models.ForeignKey` from" " :class:`~dummy_django_app.models.ChildModelA`" ), ( " :param childmodelb: All child model bs of this simple model (related" " name of :attr:`~dummy_django_app.models.ChildModelB.simple_model`)" ), ( " :type childmodelb: Reverse :class:`~django.db.models.ForeignKey` from" " :class:`~dummy_django_app.models.ChildModelB`" ), "", " .. inheritance-diagram:: dummy_django_app.models.SimpleModel", "", ] @pytest.mark.sphinx("html", testroot="docstrings") def test_abstract_model(app, do_autodoc): actual = do_autodoc(app, "class", "dummy_django_app.models.AbstractModel") print(actual) assert list(actual) == [ "", ".. py:class:: AbstractModel(*args, **kwargs)", " :module: dummy_django_app.models", "", "", " Relationship fields:", "", " :param simple_model: Simple model", ( " :type simple_model: :class:`~django.db.models.ForeignKey` to" " :class:`~dummy_django_app.models.SimpleModel`" ), " :param user: User", ( " :type user: :class:`~django.db.models.ForeignKey` to" " :class:`~django.contrib.auth.models.User`" ), " :param foreignkey_self: Foreignkey self", ( " :type foreignkey_self: :class:`~django.db.models.ForeignKey` to" " :class:`~dummy_django_app.models.AbstractModel`" ), "", " .. inheritance-diagram:: dummy_django_app.models.AbstractModel", "", ] @pytest.mark.sphinx( "html", testroot="docstrings", confoverrides={"django_show_db_tables": True} ) def test_abstract_model_with_tables_names_and_ignore_abstract(app, do_autodoc): actual = do_autodoc(app, "class", "dummy_django_app.models.AbstractModel") print(actual) assert list(actual) == [ "", ".. py:class:: AbstractModel(*args, **kwargs)", " :module: dummy_django_app.models", "", "", " Relationship fields:", "", " :param simple_model: Simple model", ( " :type simple_model: :class:`~django.db.models.ForeignKey` to" " :class:`~dummy_django_app.models.SimpleModel`" ), " :param user: User", ( " :type user: :class:`~django.db.models.ForeignKey` to" " :class:`~django.contrib.auth.models.User`" ), " :param foreignkey_self: Foreignkey self", ( " :type foreignkey_self: :class:`~django.db.models.ForeignKey` to" " :class:`~dummy_django_app.models.AbstractModel`" ), "", " .. inheritance-diagram:: dummy_django_app.models.AbstractModel", "", ] @pytest.mark.sphinx( "html", testroot="docstrings", confoverrides={ "django_show_db_tables": True, "django_show_db_tables_abstract": True, }, ) def test_abstract_model_with_tables_names_and_abstract_show(app, do_autodoc): actual = do_autodoc(app, "class", "dummy_django_app.models.AbstractModel") print(actual) assert list(actual) == [ "", ".. py:class:: AbstractModel(*args, **kwargs)", " :module: dummy_django_app.models", "", " **Database table:** ``None``", "", "", " Relationship fields:", "", " :param simple_model: Simple model", ( " :type simple_model: :class:`~django.db.models.ForeignKey` to" " :class:`~dummy_django_app.models.SimpleModel`" ), " :param user: User", ( " :type user: :class:`~django.db.models.ForeignKey` to" " :class:`~django.contrib.auth.models.User`" ), " :param foreignkey_self: Foreignkey self", ( " :type foreignkey_self: :class:`~django.db.models.ForeignKey` to" " :class:`~dummy_django_app.models.AbstractModel`" ), "", " .. inheritance-diagram:: dummy_django_app.models.AbstractModel", "", ] @pytest.mark.sphinx("html", testroot="docstrings") def test_file_model(app, do_autodoc): actual = do_autodoc(app, "class", "dummy_django_app.models.FileModel") print(actual) assert list(actual) == [ "", ".. py:class:: FileModel(id, upload)", " :module: dummy_django_app.models", "", " :param id: Primary key: ID", " :type id: ~django.db.models.AutoField", " :param upload: Upload", " :type upload: ~django.db.models.FileField", "", " Reverse relationships:", "", ( " :param simple_models: All simple models of this file model (related" " name of :attr:`~dummy_django_app.models.SimpleModel.file`)" ), ( " :type simple_models: Reverse :class:`~django.db.models.ForeignKey` from" " :class:`~dummy_django_app.models.SimpleModel`" ), "", " .. inheritance-diagram:: dummy_django_app.models.FileModel", "", ] @pytest.mark.sphinx("html", testroot="docstrings") def test_tagged_item(app, do_autodoc): actual = do_autodoc(app, "class", "dummy_django_app.models.TaggedItem") print(actual) assert list(actual) == [ "", ".. py:class:: TaggedItem(id, tag, content_type, object_id)", " :module: dummy_django_app.models", "", " :param id: Primary key: ID", " :type id: ~django.db.models.AutoField", " :param tag: Tag", " :type tag: ~django.db.models.SlugField", " :param object_id: Object id", " :type object_id: ~django.db.models.PositiveIntegerField", ( " :param content_object: Generic foreign key to the" " :class:`~django.contrib.contenttypes.models.ContentType` specified in" " :attr:`~dummy_django_app.models.TaggedItem.content_type`" ), ( " :type content_object:" " ~django.contrib.contenttypes.fields.GenericForeignKey" ), "", " Relationship fields:", "", ( " :param content_type: Content type (related name:" " :attr:`~django.contrib.contenttypes.models.ContentType.taggeditem`)" ), ( " :type content_type: :class:`~django.db.models.ForeignKey` to" " :class:`~django.contrib.contenttypes.models.ContentType`" ), "", " .. inheritance-diagram:: dummy_django_app.models.TaggedItem", "", ] @pytest.mark.sphinx("html", testroot="docstrings") def test_form(app, do_autodoc): actual = do_autodoc(app, "class", "dummy_django_app.forms.SimpleForm") print(actual) assert list(actual) == [ "", ".. py:class:: SimpleForm(*args, **kwargs)", " :module: dummy_django_app.forms", "", " **Form fields:**", "", " * ``file``: File (:class:`~django.forms.ModelChoiceField`)", " * ``childA``: ChildA (:class:`~django.forms.ModelChoiceField`)", ( " * ``childrenB``: ChildrenB" " (:class:`~django.forms.ModelMultipleChoiceField`)" ), ( " * ``dummy_field``: Very verbose name of dummy field" " (:class:`~django.forms.CharField`)" ), " * ``test1``: Test1 (:class:`~django.forms.CharField`)", " * ``test2``: Test2 (:class:`~django.forms.CharField`)", "", ] sphinxcontrib-django-2.5/tests/test_data_docstrings.py000066400000000000000000000015741450461522200234450ustar00rootroot00000000000000import pytest @pytest.mark.sphinx("html", testroot="docstrings") def test_data(app, do_autodoc): options = {"members": None} actual = do_autodoc(app, "module", "dummy_django_app.settings", options) print(actual) assert list(actual) == [ "", ".. py:module:: dummy_django_app.settings", "", " Dummy Django settings file", "", "", ".. py:data:: INSTALLED_APPS", " :module: dummy_django_app.settings", ( " :value: ['django.contrib.auth', 'django.contrib.contenttypes'," " 'dummy_django_app']" ), "", " These are the installed apps", "", " .. code-block:: JavaScript", "", ( " ['django.contrib.auth', 'django.contrib.contenttypes'," " 'dummy_django_app']\n" ), "", ] sphinxcontrib-django-2.5/tests/test_django_configured.py000066400000000000000000000011471450461522200237400ustar00rootroot00000000000000import pytest @pytest.mark.sphinx("html", testroot="docstrings") def test_django_configured(app, do_autodoc): actual = do_autodoc(app, "class", "dummy_django_app.models.MonkeyPatched") print(actual) assert list(actual) == [ "", ".. py:class:: MonkeyPatched(*args, **kwargs)", " :module: dummy_django_app.models", "", " Monkeypatched docstring", "", " :param id: Primary key: ID", " :type id: ~django.db.models.AutoField", "", " .. inheritance-diagram:: dummy_django_app.models.MonkeyPatched", "", ] sphinxcontrib-django-2.5/tests/test_django_setup.py000066400000000000000000000012461450461522200227530ustar00rootroot00000000000000import pytest from sphinx.errors import ConfigError @pytest.mark.sphinx("html", testroot="docstrings") def test_setup_with_missing_config(setup_app_with_different_config): """ Simulate the missing configuration of the Django settings """ with pytest.raises(ConfigError): setup_app_with_different_config(django_settings="") @pytest.mark.sphinx("html", testroot="docstrings") def test_setup_with_incorrect_config(setup_app_with_different_config): """ Simulate the incorrect configuration of the Django settings """ with pytest.raises(ConfigError): setup_app_with_different_config(django_settings="non_existing_module.settings") sphinxcontrib-django-2.5/tests/test_method_docstrings.py000066400000000000000000000034321450461522200240070ustar00rootroot00000000000000import pytest @pytest.mark.sphinx("html", testroot="docstrings") def test_model_method_display(app, do_autodoc): actual = do_autodoc( app, "method", "dummy_django_app.models.SimpleModel.get_dummy_field_display" ) print(actual) assert list(actual) == [ "", ".. py:method:: SimpleModel.get_dummy_field_display()", " :module: dummy_django_app.models", "", ( " Shows the label of the :attr:`dummy_field`. See" " :meth:`~django.db.models.Model.get_FOO_display` for more information." ), "", ] @pytest.mark.sphinx("html", testroot="docstrings") def test_model_method_get_next_by(app, do_autodoc): actual = do_autodoc( app, "method", "dummy_django_app.models.SimpleModel.get_next_by_dummy_field" ) print(actual) assert list(actual) == [ "", ".. py:method:: SimpleModel.get_next_by_dummy_field()", " :module: dummy_django_app.models", "", ( " Finds next instance based on :attr:`dummy_field`. See" " :meth:`~django.db.models.Model.get_next_by_FOO` for more information." ), "", ] @pytest.mark.sphinx("html", testroot="docstrings") def test_model_method_get_previous_by(app, do_autodoc): actual = do_autodoc( app, "method", "dummy_django_app.models.SimpleModel.get_previous_by_dummy_field" ) print(actual) assert list(actual) == [ "", ".. py:method:: SimpleModel.get_previous_by_dummy_field()", " :module: dummy_django_app.models", "", ( " Finds previous instance based on :attr:`dummy_field`. See" " :meth:`~django.db.models.Model.get_previous_by_FOO` for more information." ), "", ] sphinxcontrib-django-2.5/tests/test_roles.py000066400000000000000000000007231450461522200214140ustar00rootroot00000000000000import pytest @pytest.mark.sphinx( "html", testroot="docstrings", confoverrides={ "extensions": ["conflicting_sphinx_extension", "sphinxcontrib_django"] }, ) def test_setup_with_conflicting_extension(app, caplog): setup_records = caplog.get_records("setup") assert len(setup_records) == 1 assert setup_records[0].name == "sphinxcontrib_django.roles" assert "Unable to register cross-reference type: " in setup_records[0].msg