././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/.hg_archival.txt0000644000000000000000000000017100000000000013355 0ustar00repo: 9d8a29ccadafeae1d60e7ac0c6932e4915e3aad6 node: 9ae2484713649a34ae63a1b5a221bb5922cdd22a branch: default tag: 3.0.9 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/.coveragerc0000644000000000000000000000060400000000000012411 0ustar00[report] exclude_lines = pragma: no cover omit = */tests/* */test_* *conftest.py */openpyxl/packaging/interface.py */openpyxl/worksheet/cell_watch.py */openpyxl/workhseet/controls.py */openpyxl/worksheet/custom.py */openpyxl/worksheet/errors.py */openpyxl/worksheet/ole.py */openpyxl/worksheet/picture.py */openpyxl/worksheet/smart_tag.py ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/.flow0000644000000000000000000000017200000000000011240 0ustar00[branchname] master = default develop = develop feature = feature/ release = release/ hotfix = hotfix/ support = support/ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/.gitlab-ci.yml0000644000000000000000000000251200000000000012724 0ustar00stages: - test .unit-test: &unit stage: test variables: PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip" script: - tox --skip-missing-interpreters -- -qqrf before_script: - python -V - pip install tox - pip install -e . coverage: '/TOTAL.+ ([0-9]{1,3}%)/' test-python36: <<: *unit image: python:3.6 variables: TOXENV: py36 test-python37: <<: *unit image: python:3.7 variables: script: - tox --skip-missing-interpreters -p auto -- -rf test-python38: <<: *unit image: python:3.8 variables: TOXENV: py38 test-python39: <<: *unit image: python:3.9-rc variables: TOXENV: py39 test-pypy3: <<: *unit image: pypy:3 variables: TOXENV: pypy3 test-coverage: <<: *unit image: python:3.7 script: - export GIT_ID=$(hg tip --template '{node}\n') - export GIT_AUTHOR_NAME=$(hg tip --template '{author|person}\n') - export GIT_AUTHOR_EMAIL=$(hg tip --template '{author|email}\n') - export GIT_COMMITTER_NAME=$(hg tip --template '{author|person}\n') - export GIT_COMMITTER_EMAIL=$(hg tip --template '{author|email}\n') - export GIT_MESSAGE=$(hg tip --template '{desc}\n') - export GIT_BRANCH=$(hg branch) - export GIT_URL=https://foss.heptapod.net/openpyxl/openpyxl - tox -e cov ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/.hgeol0000644000000000000000000000024000000000000011363 0ustar00[repository] [patterns] **.ini = native **.yml = native **.py = native **.xml = native **.rst = native **.txt = native **.xlsx = BIN **.png = BIN **.zip = BIN ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/.hgignore0000644000000000000000000000053500000000000012076 0ustar00\.tox \.ve syntax: regexp \.pyc$ .coverage org.eclipse \.pytest (build|dist|openpyxl.egg-info) \.(dot|svg|pf) \.noseids \.*\.swp \.*\.DS_Store \.*\.~.* syntax: glob *~ *.orig .idea *.pstats *.sh .git travis.yml cover Include/ Lib/ Scripts/ downloads/ Compliance Spec doc/api openpyxl-env *.c bin/ Issues/ lib/ lib/ scratchpad/ pyvenv.cfg .gitignore ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/.hgtags0000644000000000000000000001241200000000000011546 0ustar005fb1fd7f5c5aee376b40f824eb7f06174088a30e 1.0 3daa16bd3534d4afc163df1f63eb2e8ad7685bce 0.0.2 5baae8239fe680564b638620f439f2ab1cc2a6cb 1.0.1 604a4d6d78e20733add59ef415dfb1a4b7220877 1.1.0 7425eace055b37c9a2d54b23d8bdf44bdbaa116e 1.1.3 9cc6056621aa3478a570d51a8fa873db5ff9e142 1.1.4 f81c93f5f3a931da48648dad5f76c92cb07a791c 1.1.5 2e6a72cda680542afccbbdbf162829f4b2c674da 1.1.6 06f7fe3cb60e595eb8ecaadabecd9e615685b0ea 1.1.7 1977f08f7a825c2f476ca4fe934c3c089138ef0f 1.1.8 943e433711d530d33b85cf99f50b360502a5c6a5 1.2.0 222faa0614f117efa67b1f0526b8e2a51b9f3d8f 1.2.1 e99a864c2c4eb51143436ceefc8a4c701b330218 1.2.2 938c3296f5c2f5dba0cf4d0ece10484588f01f2d 1.2.3 a318264664b441d479151dcbc40ef3e5b2d1e5d6 1.2.3 99f77f5865e099bdace2944e86c47a779d85829d 1.3.0 94086a8241ffac8f6cc19371173c723793e6feb3 1.3.1 8e0dab0e9912f3de0c916ca519be5623932760b3 1.3.2 501be08e2e7cab0ba465eed4adc4d19a36e30a67 1.3.4 112be0811b65a6b35f848509b8b1db67be755a33 1.3.5 b4d2ad724e69e7e52ef18e7f70cf9d3380c8ecaf 1.3.6 0f01fc00b3600ad60791c9222dd2fb3834beadc8 1.3.7 5e1bbdcce9f19459b56f418ac8aeba0ff459df72 1.4.0 80642f44d93c162b457bdf52ebc5a7a9857a9eee 1.4.1 75ccbfaf7bde91270d797923a5db00f75b5e8d52 1.5.0 46daa81226afca071813eacb30d2d14790267b76 1.5.1 bb2891e7d81add7b240b0dda2b723b3332153204 1.5.2 01585e84159563aba715baed831eed5036980cfb 1.5.3 dbdd9171212b8051a00468f70efa47ce915a6b2c 1.5.4 dad4800d3db642d782fdde2eb524e48944fca9fe 1.5.5 e5934500ffacc584ab5f0b4b0c795c1cbc862384 1.5.6 fa3065fd5d72c871108fb8f6a3412f91d83f46cd 1.5.7 ed41b6ba0d589b7c64ba3e8d76a1ac90b36acc1b 1.5.8 1a9b8e4976754ddd8e89799fc1d1941782ef3d9b 1.5.9 ef6a1c94a59563bac2c0b1f3af2ac4683724e378 1.6.0 48ceb29049c4d85ff5160ed2724a84b86b8d1106 1.6.1 dc1bfe095ee3bd9d28f95ef849bd8eac033742df 1.6.2 712bdf6a8e9bcce0f3c81dd3571b5773987fb664 1.7.0 c9c6d5e877677e43b8602bdcab6625fe264d0dca 1.8.0 6f91d07c4fbbf95a82770b65efd9959c2b2d8716 1.8.1 581cf3b4ccb55c90ceaf225b2a94fa68b5dd2a0f 1.8.2 64e943a7d3df92491e44370994cd272f9e52c9bf 1.8.3 e3bec545653f0fddbf05751efdc31462a4506e6b 1.8.4 d298dafdad907b1094a07c550a226ccfeb6dc1ec 1.8.5 5d2c0c8704d257e761ec93d4d14a5c6cbbb6eb03 1.8.6 16fe5e4962de6ce07011bb4d7247292938491d11 2.0.0 c35a48e6d809406150cc3e4a97587613cb77dc83 2.0.1 a7c70e52f6f182dc965b977807c06df3c6143614 2.0.2 10ba9602980054e1fa087bb7955482e3eafb23fa 2.0.3 a07d28c65ea46f10e63537b15bfa6b8e91cf1768 2.0.4 0dacda62629898ec9fd3282b7d40832c7c15713c 2.1.0 fe1a14c5cacdeb805c501c6aa583c1884675ec8a 2.1.1 181f63545fbc45e2ebc1ef93f4079e51f7f9517b 2.1.2 27bb987d6e3b49e0397872cedee157c3126761ef 2.1.3 a4824c9ead3a45fedba4267cd39319dc2c7fba0f 2.1.4 0e331da41f2b7d0e1953ca5ec2e36e5c160b56cd 2.1.5 96fe53dc6932c0093533780d6b1537da85b573b9 2.2.0 96fe53dc6932c0093533780d6b1537da85b573b9 2.2.0 78606351e8ec5e48b72adaa7d5407762476eec1e 2.2.0 836430cce62dc7b9dda871a5f595a5afadd6e37e 2.2.1 f435cf21084ac981b14b0d99451307770d9f62c5 2.2.2 f24a18130d305a8c9c18ba81854f91d53ae68dfb 2.2.3 a7208374333736a1880bd569b28af6f7471849a1 2.2.4 8a282e182ebfc155f8e62f6af026afc50f93fc14 2.3.0-b1 aaed71744209852706257d15e92ada8b6f2aec70 2.2.6 a87c01850d8c262af4b701d74a249dbfe013c78b 2.3.0-b2 17ebc853f5304e9f63531758eff85613cf419e48 2.3.0 b6ae470715f14381e7629a3266fb88156b0f266b 2.3.1 d3971b7f90e3ff24ed300f7faf3b67c6f05c3912 2.3.2 93e017b03d2a11057d7935e193f3080b3036ee57 2.3.3 e0820e3fa62ccde44733e058770477b0b3a897e7 2.3.4 12ee1b8fa3a56cc3c317bb460e49595bdab0c2f6 2.4.0-a1 335afecd9a610d07de0b8a2eb939170659715c3c 2.4.0-b1 802efb7800d827c21b33be52f7c96409253d8a87 2.3.5 571d0a60d8742ba911ac2d16329306b1dc5b6890 2.4.0 d786a9744c7172c7460e88d7c642448bd4392a77 2.4.1 f8bb58ea697d7f57e0f0dd0db13debf4e5be62b6 2.4.2 ca503da36b72ecd8dcc85ce33b7451cec69e871b 2.4.4 84f1f24f8fac1d86c455bafb62f4ced0a9ad0da2 2.4.5 24e08ce56e3c968031b9a2c3492eedcd3cc072d7 2.4.6 a8e07fa3006422850ff7d591c5fdf4ab25d54f43 2.4.7 d26bb79d9448fa348f59243600fee5c27695ec06 2.4.8 a610430a415a3997291ddbb04d6af8a96394fd9d 2.5.0-a1 bac1d2b4ce3a6a16b9f3c2d19736dc981dd8d907 2.5.0-a3 2b77055eecb3999de3e28fa623838c2db9a25b2d 2.4.9 e8b3cf798591c681dfac88546bc91c48446ace51 2.4.10 c70b22998c6855226cd0e74b707a3ece2da82ef5 2.4.11 5267be8c732de75c6c42775188c0389d678da117 2.5.0-b1 17614d3763320b4d154580f84054ac2ccf538f42 2.5.0-b2 ebba397b98d5f01d9deac6634ab2fd5c206fa348 2.5.0 a17806a0b75561e4ad44888ca8f3bca4bbe69fe2 2.5.1 3ddffe18fe158787f32eb23775ccf51038d8ae83 2.5.2 a4494d23a4b6dce8b31f95b1d3ea1a42d200adfb 2.5.3 5983d4ba5c18b85171185e8b1ca136876ec52864 2.5.4 c0235e89c62962df89df12946bff07f33aa971a7 2.5.5 260d5b0b9caf7c648d86f39bb524e18e55c48d72 2.5.6 41b72fd5175b200803b9160d4b453a30b1ef2a0b 2.5.7 e49d1f8b5ee836cf4ffa195e1c985fdce9d7470b 2.5.8 4cfe457487e2a5aa7ad7759c13e7901308943c04 2.5.10 9035a8ec775d6d1f994c5a8c5c7bc90bda7dc808 2.5.9 f26ee3951de99bc5b612771b396d6f837e89a701 2.5.11 eee167cb1c26e41a269c6b5ee97e6d6ddcc3b352 2.5.12 516a765c8fa1c2455ec3857c63c0330212d4193e 2.5.14 a275c9c73d563f318bcc125126263757b4ae169c 2.6.0 5eaaf27880d045a21d21c2ead53e55e63343a282 3.0.0 983cb2595f1c398f532ad015996d34f61a2eb2b3 2.6.4 a2ee53b78166726a265cacfa04ac91b01f8b9b92 3.0.1 8ef423aef738a6c8c88b702a5f7db10c2e80c934 3.0.2 ca7b1baf75f2fc6b270320ea91d82404f5039e1e 3.0.3 e1024c1296f5250167050892431107b795349f3b 3.0.4 b21e9536ad9fc1c666b900e8c39253fe04111d77 3.0.5 4e4d4024eb4d703901de5c75c913e1a23a669f72 3.0.6 f06cd1654c17d5d121328ec37e097bca09ec0b23 3.0.7 249330a473efff0e9ab64b0bd0bfa0db333777fb 3.0.8 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/AUTHORS.rst0000644000000000000000000000331300000000000012147 0ustar00This project was started by Eric Gazoni. In 2013 Charlie Clark became co-maintainer of the project. It was initially *heavily* inspired by the PHPExcel library: http://www.phpexcel.net/ Thanks to all those who participate in the project (in alphabetical order): * aceMueller * Adam Lofts * Adam Morris * Alessandro Cucci * Alex Gronholm * Alexandre Fayolle * Amin Mirzaee * Anders Chrigstrom * Bernt R. Brenna * Brent Hoover * Brice Gelineau * ccoacley * Chi Ho Kwok * Cory Kramer * Day Barr * Detlef Lannert * Dieter Vandenbussche * Dmitriy Chernyshov * Dominik Geldmacher * Don Freeman * Eirikur Fannar Torfason * Elias Rabel * Eric Chlebek * Eric Gazoni * Eric Hurkman * Etienne Desautels * Felipe Ochoa * Felix Siebeneicker * Fumito Hamamura * Gabi Nagy * Gar Thompson * Gerald Van Huffelen * Greg Lehmann * Heikki Junes * Israel Barth Rubio * Jacob Middag * James Smagala * JarekPS * Jean Pierre Huart * Jeff Holman * John Woltman IV * Jonathan Peirce * Joseph Tate * Josh Haywood * Jun Omae * Kay Webber * Khchine Hamza * Klaus Bremer * Koert van der Veer * Laurent Laporte * Laurent Vasseur * Maarten De Paepe * Magnus Schieder * Mark Gemmill * Marko Loparic * Masato Yoshida * Max Bolingbroke * Nicholas Laver * Nis Martensen * Paul Joyce * Paul Van Der Linden * Philip Roche * ramn_se * René Neumann * Rick Rankin * Samuel Loretan * Sergey Pikhovkin * Shekhar Gyanwali * Shibukawa Yoshiki * Stefan Behnel * Stephane Bard * Stephen Rauch * Sven Burk * Ted Pollari * Thomas Nygards * Victor Korobkovsky * Waldemar Osuch * Wojciech Rola * Wolfgane Scherer * Yaroslav Halchenko * Yash Jhunjhunwala * Yingjie Lan * Leetao Project logo designed by Eric Gazoni, font by claudeserieux (http://www.dafont.com/profile.php?user=337503) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/CONTRIBUTING.txt0000644000000000000000000000030000000000000012731 0ustar00Contributing ============ Contributions to openpyxl are welcome. Please see the [developer documentation](https://openpyxl.readthedocs.io/en/stable/development.html) for further information. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/LICENCE.rst0000644000000000000000000000215300000000000012065 0ustar00This software is under the MIT Licence ====================================== Copyright (c) 2010 openpyxl Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/MANIFEST.in0000644000000000000000000000016100000000000012024 0ustar00prune openpyxl/sample prune openpyxl/benchmarks prune openpyxl/develop prune scratchpad prune doc include *.rst ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/README.rst0000644000000000000000000000255400000000000011765 0ustar00.. image:: https://coveralls.io/repos/bitbucket/openpyxl/openpyxl/badge.svg?branch=default :target: https://coveralls.io/bitbucket/openpyxl/openpyxl?branch=default :alt: coverage status Introduction ------------ openpyxl is a Python library to read/write Excel 2010 xlsx/xlsm/xltx/xltm files. It was born from lack of existing library to read/write natively from Python the Office Open XML format. All kudos to the PHPExcel team as openpyxl was initially based on PHPExcel. Security -------- By default openpyxl does not guard against quadratic blowup or billion laughs xml attacks. To guard against these attacks install defusedxml. Mailing List ------------ The user list can be found on http://groups.google.com/group/openpyxl-users Sample code:: from openpyxl import Workbook wb = Workbook() # grab the active worksheet ws = wb.active # Data can be assigned directly to cells ws['A1'] = 42 # Rows can also be appended ws.append([1, 2, 3]) # Python types will automatically be converted import datetime ws['A2'] = datetime.datetime.now() # Save the file wb.save("sample.xlsx") Documentation ------------- The documentation is at: https://openpyxl.readthedocs.io * installation methods * code examples * instructions for contributing Release notes: https://openpyxl.readthedocs.io/en/stable/changes.html ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/bitbucket-pipelines.yml0000644000000000000000000000164400000000000014762 0ustar00image: openpyxl/openpyxl-ci pipelines: pull-requests: '**': - step: caches: - pip script: - /tools/clean-launch.sh tox --skip-missing-interpreters -e py27,py37 -- -qrf default: - step: caches: - pip script: - /tools/clean-launch.sh tox --skip-missing-interpreters -- -qrf - export GIT_ID=$(hg tip --template '{node}\n') - export GIT_AUTHOR_NAME=$(hg tip --template '{author|person}\n') - export GIT_AUTHOR_EMAIL=$(hg tip --template '{author|email}\n') - export GIT_COMMITTER_NAME=$(hg tip --template '{author|person}\n') - export GIT_COMMITTER_EMAIL=$(hg tip --template '{author|email}\n') - export GIT_MESSAGE=$(hg tip --template '{desc}\n') - export GIT_BRANCH=$(hg branch) - export GIT_URL=https://bitbucket.org/openpyxl/openpyxl # - /tools/clean-launch.sh tox -e cov ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/conftest.py0000644000000000000000000000357500000000000012501 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest import platform ### Markers ### def pytest_runtest_setup(item): from openpyxl import DEFUSEDXML, LXML if isinstance(item, pytest.Function): try: from PIL import Image except ImportError: Image = False if item.get_closest_marker("pil_required") and Image is False: pytest.skip("PIL must be installed") elif item.get_closest_marker("pil_not_installed") and Image: pytest.skip("PIL is installed") elif item.get_closest_marker("not_py33"): pytest.skip("Ordering is not a given in Python 3") elif item.get_closest_marker("defusedxml_required"): if LXML or not DEFUSEDXML: pytest.skip("defusedxml is required to guard against these vulnerabilities") elif item.get_closest_marker("lxml_required"): if not LXML: pytest.skip("LXML is required for some features such as schema validation") elif item.get_closest_marker("lxml_buffering"): from lxml.etree import LIBXML_VERSION if LIBXML_VERSION < (3, 4, 0, 0): pytest.skip("LXML >= 3.4 is required") elif item.get_closest_marker("no_lxml"): from openpyxl import LXML if LXML: pytest.skip("LXML has a different interface") elif item.get_closest_marker("numpy_required"): from openpyxl import NUMPY if not NUMPY: pytest.skip("Numpy must be installed") elif item.get_closest_marker("pandas_required"): try: import pandas except ImportError as e: pytest.skip("Pandas must be installed") elif item.get_closest_marker("no_pypy"): if platform.python_implementation() == "PyPy": pytest.skip("Skipping pypy") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/Makefile0000644000000000000000000001077200000000000012504 0ustar00# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = build # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " text to make text files" @echo " man to make manual pages" @echo " changes to make an overview of all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: -rm -rf $(BUILDDIR)/* html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/openpyxl.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/openpyxl.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/openpyxl" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/openpyxl" @echo "# devhelp" epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." make -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/_static/.placeholder0000644000000000000000000000000000000000000014734 0ustar00././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/changes.rst0000644000000000000000000017550000000000000013207 0ustar003.0.9 (2021-09-22) ================== Bugfixes -------- * `#1284 `_ Ignore blank ignored in existing Data Validations * `#1539 `_ Add support for cell protection for merged cell ranges * `#1645 `_ Timezone-aware datetimes raise an Exception * `#1666 `_ Improved normalisation of chart series * `#1670 `_ Catch OverflowError for out of range datetimes * `#1708 `_ Alignment.relativeIndent can be negative * `#1736 `_ Incorrect default value `groupBy` attribute 3.0.8 (brown bag) ================== Deleted because it contained breaking changes from 3.1 3.0.7 (2021-03-09) ================== Bugfixes -------- * `#1510 `_ Problems with zero time values * `#1588 `_ Not possible to correctly convert excel dates to timedelta * `#1589 `_ Exception raised when merging cells which do not have borders all the way round. * `#1594 `_ Python 2 print statement in the tutorial Pull Requests ------------- * `PR392 `_ Add documentation on datetime handling * `PR393 `_ Drop dependency on jdcal * `PR394 `_ Datetime rounding * `PR395 `_ Unify handling of 1900 epoch * `PR397 `_ Add explicit support for reading datetime deltas * `PR399 `_ Millisecond precision for datetimes 3.0.6 (2021-01-14) ================== Bugfixes -------- * `#1154 `_ Borders in differential styles are incorrect * `#1287 `_ Error when opening some pivot tables * `#1366 `_ Resave breaks the border format in conditional formatting rules * `#1450 `_ Read-only workbook not closed properly if generator interrupted * `#1547 `_ Pandas.Multiindex.labels deprecated * `#1552 `_ Pandas.Multiinex not expanded correctly * `#1557 `_ Cannot read rows with exponents * `#1568 `_ numpy.float is deprecated * `#1571 `_ Cells without coordinate attributes not always correctly handled Pull Requests ------------- * `PR385 `_ Improved handling of borders for differential styles * `PR386 `_ Support subclasses of datetime objects * `PR387 `_ Improved handling of cells without coordinates 3.0.5 (2020-08-21) ================== Bugfixes -------- * `#1413 `_ Incorrectly consider currency format as datetime * `#1490 `_ Cannot copy worksheets with merged cells * `#1492 `_ Empty worksheets do not return generators when looping. * `#1496 `_ Hyperlinks duplicated on multiple saves * `#1500 `_ Incorrectly literal format as datetime * `#1502 `_ Links set to range of cells not preserved * `#1507 `_ Exception when opening workbook with chartsheets and tables 3.0.4 (2020-06-24) ================== Bugfixes -------- * `#844 `_ Find tables by name * `#1414 `_ Worksheet protection missing in existing files * `#1439 `_ Exception when reading files with external images * `#1452 `_ Reading lots of merged cells is very slow. * `#1455 `_ Read support for Bubble Charts. * `#1458 `_ Preserve any indexed colours * `#1473 `_ Reading many thousand of merged cells is really slow. * `#1474 `_ Adding tables in write-only mode raises an exception. Pull Requests ------------- * `PR377 `_ Add support for finding tables by name or range. 3.0.3 (2020-01-20) ================== Bugfixes -------- * `#1260 `_ Exception when handling merged cells with hyperlinks * `#1373 `_ Problems when both lxml and defusedxml are installed * `#1385 `_ CFVO with incorrect values cannot be processed 3.0.2 (2019-11-25) ================== Bug fixes --------- * `#1267 `_ DeprecationError if both defusedxml and lxml are installed * `#1345 `_ ws._current_row is higher than ws.max_row * `#1365 `_ Border bottom style is not optional when it should be * `#1367 `_ Empty cells in read-only, values-only mode are sometimes returned as ReadOnlyCells * `#1368 `_ Cannot add page breaks to existing worksheets if none exist already Pull Requests ------------- * `PR359 `_ Improvements to the documentation 3.0.1 (2019-11-14) ================== Bugfixes -------- * `#1250 `_ Cannot read empty charts. Pull Requests ------------- * `PR354 `_ Fix for #1250 * `PR352 `_ TableStyleElement is a sequence 3.0.0 (2019-09-25) ================== Python 3.6+ only release ------------------------ 2.6.4 (2019-09-25) ================== Final release for Python 2.7 and 3.5 ------------------------------------ Bugfixes -------- * ` #1330 `_ Cannot save workbooks with comments more than once. 2.6.3 (2019-08-19) ================== Bugfixes -------- * `#1237 `_ Fix 3D charts. * `#1290 `_ Minimum for holeSize in Doughnut charts too high * `#1291 `_ Warning for MergedCells with comments * `#1296 `_ Pagebreaks duplicated * `#1309 `_ Workbook has no default CellStyle * `#1330 `_ Workbooks with comments cannot be saved multiple times Pull Requests ------------- * `PR344 `_ Make sure NamedStyles number formats are correctly handled 2.6.2 (2019-03-29) ================== Bugfixes -------- * `#1173 `_ Workbook has no _date_formats attribute * `#1190 `_ Cannot create charts for worksheets with quotes in the title * `#1228 `_ MergedCells not removed when range is unmerged * `#1232 `_ Link to pivot table lost from charts * `#1233 `_ Chart colours change after saving * `#1236 `_ Cannot use ws.cell in read-only mode with Python 2.7 2.6.1 (2019-03-04) ================== Bugfixes -------- * `#1174 `_ ReadOnlyCell.is_date does not work properly * `#1175 `_ Cannot read Google Docs spreadsheet with a Pivot Table * `#1180 `_ Charts created with openpyxl cannot be styled * `#1181 `_ Cannot handle some numpy number types * `#1182 `_ Exception when reading unknowable number formats * `#1186 `_ Only last formatting rule for a range loaded * `#1191 `_ Give MergedCell a `value` attribute * `#1193 `_ Cannot process worksheets with comments * `#1197 `_ Cannot process worksheets with both row and page breaks * `#1204 `_ Cannot reset dimensions in ReadOnlyWorksheets * `#1211 `_ Incorrect descriptor in ParagraphProperties * `#1213 `_ Missing `hier` attribute in PageField raises an exception 2.6.0 (2019-02-06) ================== Bugfixes -------- * `#1162 `_ Exception on tables with names containing spaces. * `#1170 `_ Cannot save files with existing images. 2.6.-b1 (2019-01-08) ==================== Bugfixes -------- * `#1141 `_ Cannot use read-only mode with stream * `#1143 `_ Hyperlinks always set on A1 * `#1151 `_ Internal row counter not initialised when reading files * `#1152 `_ Exception raised on out of bounds date 2.6-a1 (2018-11-21) =================== Major changes ------------- * Implement robust for merged cells so that these can be formatted the way Excel does without confusion. Thanks to Magnus Schieder. Minor changes ------------- * Add support for worksheet scenarios * Add read support for chartsheets * Add method for moving ranges of cells on a worksheet * Drop support for Python 3.4 * Last version to support Python 2.7 Deprecations ------------ * Type inference and coercion for cell values 2.5.14 (2019-01-23) =================== Bugfixes -------- * `#1150 `_ Correct typo in LineProperties * `#1142 `_ Exception raised for unsupported image files * `#1159 `_ Exception raised when cannot find source for non-local cache object Pull Requests ------------- * `PR301 `_ Add support for nested brackets to the tokeniser * `PR303 `_ Improvements on handling nested brackets in the tokeniser 2.5.13 (brown bag) ================== 2.5.12 (2018-11-29) =================== Bugfixes -------- * `#1130 `_ Overwriting default font in Normal style affects library default * `#1133 `_ Images not added to anchors. * `#1134 `_ Cannot read pivot table formats without dxId * `#1138 `_ Repeated registration of simple filter could lead to memory leaks Pull Requests ------------- * `PR300 `_ Use defusedxml if available 2.5.11 (2018-11-21) =================== Pull Requests ------------- * `PR295 `_ Improved handling of missing rows * `PR296 `_ Add support for defined names to tokeniser 2.5.10 (2018-11-13) =================== Bugfixes -------- * `#1114 `_ Empty column dimensions should not be saved. Pull Requests ------------- * `PR285 `_ Tokenizer failure for quoted sheet name in second half of range * `PR289 `_ Improved error detection in ranges. 2.5.9 (2018-10-19) ================== Bugfixes -------- * `#1000 `_ Clean AutoFilter name definitions * `#1106 `_ Attribute missing from Shape object * `#1109 `_ Failure to read all DrawingML means workbook can't be read Pull Requests ------------- * `PR281 `_ Allow newlines in formulae * `PR284 `_ Fix whitespace in front of infix operator in formulae 2.5.8 (2018-09-25) ================== * `#877 `_ Cannot control how missing values are displayed in charts. * `#948 `_ Cell references can't be used for chart titles * `#1095 `_ Params in iter_cols and iter_rows methods are slightly wrong. 2.5.7 (2018-09-13) ================== * `#954 `_ Sheet title containing % need quoting in references * `#1047 `_ Cannot set quote prefix * `#1093 `_ Pandas timestamps raise KeyError 2.5.6 (2018-08-30) ================== * `#832 `_ Read-only mode can leave find-handles open when reading dimensions * `#933 `_ Set a worksheet directly as active * `#1086 `_ Internal row counter not adjusted when rows are deleted or inserted 2.5.5 (2018-08-04) ================== Bugfixes -------- * `#1049 `_ Files with Mac epoch are read incorrectly * `#1058 `_ Cannot copy merged cells * `#1066 `_ Cannot access ws.active_cell Pull Requests ------------- * `PR267 `_ Introduce read-support for images 2.5.4 (2018-06-07) ================== Bugfixes -------- * `#1025 `_ Cannot read files with 3D charts. * `#1030 `_ Merged cells take a long time to parse Minor changes ------------- * Improve read support for pivot tables and don't always create a Filters child for filterColumn objects. * `Support folding rows` `_ 2.5.3 (2018-04-18) ================== Bugfixes -------- * `#983 `_ Warning level too aggressive. * `#1015 `_ Alignment and protection values not saved for named styles. * `#1017 `_ Deleting elements from a legend doesn't work. * `#1018 `_ Index names repeated for every row in dataframe. * `#1020 `_ Worksheet protection not being stored. * `#1023 `_ Exception raised when reading a tooltip. 2.5.2 (2018-04-06) ================== Bugfixes -------- * `#949 `_ High memory use when reading text-heavy files. * `#970 `_ Copying merged cells copies references. * `#978 `_ Cannot set comment size. * `#985 `_ Exception when trying to save workbooks with no views. * `#995 `_ Cannot delete last row or column. * `#1002 `_ Cannot read Drawings containing embedded images. Minor changes ------------- * Support for dataframes with multiple columns and multiple indices. 2.5.1 (2018-03-12) ================== Bugfixes -------- * `#934 `_ Headers and footers not included in write-only mode. * `#960 `_ Deprecation warning raised when using ad-hoc access in read-only mode. * `#964 `_ Not all cells removed when deleting multiple rows. * `#966 `_ Cannot read 3d bar chart correctly. * `#967 `_ Problems reading some charts. * `#968 `_ Worksheets with SHA protection become corrupted after saving. * `#974 `_ Problem when deleting ragged rows or columns. * `#976 `_ GroupTransforms and GroupShapeProperties have incorrect descriptors * Make sure that headers and footers in chartsheets are included in the file 2.5.0 (2018-01-24) ================== Minor changes ------------- * Correct definition for Connection Shapes. Related to # 958 2.5.0-b2 (2018-01-19) ===================== Bugfixes -------- * `#915 `_ TableStyleInfo has no required attributes * `#925 `_ Cannot read files with 3D drawings * `#926 `_ Incorrect version check in installer * Cell merging uses transposed parameters * `#928 `_ ExtLst missing keyword for PivotFields * `#932 `_ Inf causes problems for Excel * `#952 `_ Cannot load table styles with custom names Major Changes ------------- * You can now insert and delete rows and columns in worksheets Minor Changes ------------- * pip now handles which Python versions can be used. 2.5.0-b1 (2017-10-19) ===================== Bugfixes -------- * `#812 `_ Explicitly support for multiple cell ranges in conditonal formatting * `#827 `_ Non-contiguous cell ranges in validators get merged * `#837 `_ Empty data validators create invalid Excel files * `#860 `_ Large validation ranges use lots of memory * `#876 `_ Unicode in chart axes not handled correctly in Python 2 * `#882 `_ ScatterCharts have defective axes * `#885 `_ Charts with empty numVal elements cannot be read * `#894 `_ Scaling options from existing files ignored * `#895 `_ Charts with PivotSource cannot be read * `#903 `_ Cannot read gradient fills * `#904 `_ Quotes in number formats could be treated as datetimes Major Changes ------------- `worksheet.cell()` no longer accepts a `coordinate` parameter. The syntax is now `ws.cell(row, column, value=None)` Minor Changes ------------- Added CellRange and MultiCellRange types (thanks to Laurent LaPorte for the suggestion) as a utility type for things like data validations, conditional formatting and merged cells. Deprecations ------------ ws.merged_cell_ranges has been deprecated because MultiCellRange provides sufficient functionality 2.5.0-a3 (2017-08-14) ===================== Bugfixes -------- * `#848 `_ Reading workbooks with Pie Charts raises an exception * `#857 `_ Pivot Tables without Worksheet Sources raise an exception 2.5.0-a2 (2017-06-25) ===================== Major Changes ------------- * Read support for charts Bugfixes -------- * `#833 `_ Cannot access chartsheets by title * `#834 `_ Preserve workbook views * `#841 `_ Incorrect classification of a datetime 2.5.0-a1 (2017-05-30) ===================== Compatibility ------------- * Dropped support for Python 2.6 and 3.3. openpyxl will not run with Python 2.6 Major Changes ------------- * Read/write support for pivot tables Deprecations ------------ * Dropped the anchor method from images and additional constructor arguments Bugfixes -------- * `#779 `_ Fails to recognise Chinese date format` * `#828 `_ Include hidden cells in charts` Pull requests ------------- * `163 `_ Improved GradientFill Minor changes ------------- * Remove deprecated methods from Cell * Remove deprecated methods from Worksheet * Added read/write support for the datetime type for cells 2.4.11 (2018-01-24) =================== * #957 ``_ Relationship type for tables is borked 2.4.10 (2018-01-19) =================== Bugfixes -------- * #912 ``_ Copying objects uses shallow copy * #921 ``_ API documentation not generated automatically * #927 ``_ Exception raised when adding coloured borders together * #931 ``_ Number formats not correctly deduplicated Pull requests ------------- * 203 ``_ Correction to worksheet protection description * 210 ``_ Some improvements to the API docs * 211 ``_ Improved deprecation decorator * 218 ``_ Fix problems with deepcopy 2.4.9 (2017-10-19) ================== Bugfixes -------- * `#809 `_ Incomplete documentation of `copy_worksheet` method * `#811 `_ Scoped definedNames not removed when worksheet is deleted * `#824 `_ Raise an exception if a chart is used in multiple sheets * `#842 `_ Non-ASCII table column headings cause an exception in Python 2 * `#846 `_ Conditional formats not supported in write-only mode * `#849 `_ Conditional formats with no sqref cause an exception * `#859 `_ Headers that start with a number conflict with font size * `#902 `_ TableStyleElements don't always have a condtional format * `#908 `_ Read-only mode sometimes returns too many cells Pull requests ------------- * `#179 `_ Cells kept in a set * `#180 `_ Support for Workbook protection * `#182 `_ Read support for page breaks * `#183 `_ Improve documentation of `copy_worksheet` method * `#198 `_ Fix for #908 2.4.8 (2017-05-30) ================== Bugfixes -------- * AutoFilter.sortState being assignd to the ws.sortState * `#766 `_ Sheetnames with apostrophes need additional escaping * `#729 `_ Cannot open files created by Microsoft Dynamics * `#819 `_ Negative percents not case correctly * `#821 `_ Runtime imports can cause deadlock * `#855 `_ Print area containing only columns leads to corrupt file Minor changes ------------- * Preserve any table styles 2.4.7 (2017-04-24) ================== Bugfixes -------- * `#807 `_ Sample files being included by mistake in sdist 2.4.6 (2017-04-14) ================== Bugfixes -------- * `#776 `_ Cannot apply formatting to plot area * `#780 `_ Exception when element attributes are Python keywords * `#781 `_ Exception raised when saving files with styled columns * `#785 `_ Number formats for data labels are incorrect * `#788 `_ Worksheet titles not quoted in defined names * `#800 `_ Font underlines not read correctly 2.4.5 (2017-03-07) ================== Bugfixes -------- * `#750 `_ Adding images keeps file handles open * `#772 `_ Exception for column-only ranges * `#773 `_ Cannot copy worksheets with non-ascii titles on Python 2 Pull requests ------------- * `161 `_ Support for non-standard names for Workbook part. * `162 `_ Documentation correction 2.4.4 (2017-02-23) ================== Bugfixes -------- * `#673 `_ Add close method to workbooks * `#762 `_ openpyxl can create files with invalid style indices * `#729 `_ Allow images in write-only mode * `#744 `_ Rounded corners for charts * `#747 `_ Use repr when handling non-convertible objects * `#764 `_ Hashing function is incorrect * `#765 `_ Named styles share underlying array Minor Changes ------------- * Add roundtrip support for worksheet tables. Pull requests ------------- * `160 `_ Don't init mimetypes more than once. 2.4.3 (unreleased) ================== bad release 2.4.2 (2017-01-31) ================== Bug fixes --------- * `#727 `_ DeprecationWarning is incorrect * `#734 `_ Exception raised if userName is missing * `#739 `_ Always provide a date1904 attribute * `#740 `_ Hashes should be stored as Base64 * `#743 `_ Print titles broken on sheetnames with spaces * `#748 `_ Workbook breaks when active sheet is removed * `#754 `_ Incorrect descriptor for Filter values * `#756 `_ Potential XXE vulerability * `#758 `_ Cannot create files with page breaks and charts * `#759 `_ Problems with worksheets with commas in their titles Minor Changes ------------- * Add unicode support for sheet name incrementation. 2.4.1 (2016-11-23) ================== Bug fixes --------- * `#643 `_ Make checking for duplicate sheet titles case insensitive * `#647 `_ Trouble handling LibreOffice files with named styles * `#687 `_ Directly assigned new named styles always refer to "Normal" * `#690 `_ Cannot parse print titles with multiple sheet names * `#691 `_ Cannot work with macro files created by LibreOffice * Prevent duplicate differential styles * `#694 `_ Allow sheet titles longer than 31 characters * `#697 `_ Cannot unset hyperlinks * `#699 `_ Exception raised when format objects use cell references * `#703 `_ Copy height and width when copying comments * `#705 `_ Incorrect content type for VBA macros * `#707 `_ IndexError raised in read-only mode when accessing individual cells * `#711 `_ Files with external links become corrupted * `#715 `_ Cannot read files containing macro sheets * `#717 `_ Details from named styles not preserved when reading files * `#722 `_ Remove broken Print Title and Print Area definitions Minor changes ------------- * Add support for Python 3.6 * Correct documentation for headers and footers Deprecations ------------ Worksheet methods `get_named_range()` and `get_sqaured_range()` Bug fixes --------- 2.4.0 (2016-09-15) ================== Bug fixes --------- * `#652 `_ Exception raised when epoch is 1904 * `#642 `_ Cannot handle unicode in headers and footers in Python 2 * `#646 `_ Cannot handle unicode sheetnames in Python 2 * `#658 `_ Chart styles, and axis units should not be 0 * `#663 `_ Strings in external workbooks not unicode Major changes ------------- * Add support for builtin styles and include one for Pandas Minor changes ------------- * Add a `keep_links` option to `load_workbook`. External links contain cached copies of the external workbooks. If these are big it can be advantageous to be able to disable them. * Provide an example for using cell ranges in DataValidation. * PR 138 - add copy support to comments. 2.4.0-b1 (2016-06-08) ===================== Minor changes ------------- * Add an the alias `hide_drop_down` to DataValidation for `showDropDown` because that is how Excel works. Bug fixes --------- * `#625 `_ Exception raises when inspecting EmptyCells in read-only mode * `#547 `_ Functions for handling OOXML "escaped" ST_XStrings * `#629 `_ Row Dimensions not supported in write-only mode * `#530 `_ Problems when removing worksheets with charts * `#630 `_ Cannot use SheetProtection in write-only mode Features -------- * Add write support for worksheet tables 2.4.0-a1 (2016-04-11) ===================== Minor changes ------------- * Remove deprecated methods from DataValidation * Remove deprecated methods from PrintPageSetup * Convert AutoFilter to Serialisable and extend support for filters * Add support for SortState * Removed `use_iterators` keyword when loading workbooks. Use `read_only` instead. * Removed `optimized_write` keyword for new workbooks. Use `write_only` instead. * Improve print title support * Add print area support * New implementation of defined names * New implementation of page headers and footers * Add support for Python's NaN * Added iter_cols method for worksheets * ws.rows and ws.columns now always return generators and start at the top of the worksheet * Add a `values` property for worksheets * Default column width changed to 8 as per the specification Deprecations ------------ * Cell anchor method * Worksheet point_pos method * Worksheet add_print_title method * Worksheet HeaderFooter attribute, replaced by individual ones * Flatten function for cells * Workbook get_named_range, add_named_range, remove_named_range, get_sheet_names, get_sheet_by_name * Comment text attribute * Use of range strings deprecated for ws.iter_rows() * Use of coordinates deprecated for ws.cell() * Deprecate .copy() method for StyleProxy objects Bug fixes --------- * `#152 `_ Hyperlinks lost when reading files * `#171 `_ Add function for copying worksheets * `#386 `_ Cells with inline strings considered empty * `#397 `_ Add support for ranges of rows and columns * `#446 `_ Workbook with definedNames corrupted by openpyxl * `#481 `_ "safe" reserved ranges are not read from workbooks * `#501 `_ Discarding named ranges can lead to corrupt files * `#574 `_ Exception raised when using the class method to parse Relationships * `#579 `_ Crashes when reading defined names with no content * `#597 `_ Cannot read worksheets without coordinates * `#617 `_ Customised named styles not correctly preserved 2.3.5 (2016-04-11) ================== Bug fixes --------- * `#618 `_ Comments not written in write-only mode 2.3.4 (2016-03-16) ================== Bug fixes --------- * `#594 `_ Content types might be missing when keeping VBA * `#599 `_ Cells with only one cell look empty * `#607 `_ Serialise NaN as '' Minor changes ------------- * Preserve the order of external references because formualae use numerical indices. * Typo corrected in cell unit tests (PR 118) 2.3.3 (2016-01-18) ================== Bug fixes --------- * `#540 `_ Cannot read merged cells in read-only mode * `#565 `_ Empty styled text blocks cannot be parsed * `#569 `_ Issue warning rather than raise Exception raised for unparsable definedNames * `#575 `_ Cannot open workbooks with embdedded OLE files * `#584 `_ Exception when saving borders with attributes Minor changes ------------- * `PR 103 `_ Documentation about chart scaling and axis limits * Raise an exception when trying to copy cells from other workbooks. 2.3.2 (2015-12-07) ================== Bug fixes --------- * `#554 `_ Cannot add comments to a worksheet when preserving VBA * `#561 `_ Exception when reading phonetic text * `#562 `_ DARKBLUE is the same as RED * `#563 `_ Minimum for row and column indexes not enforced Minor changes ------------- * `PR 97 `_ One VML file per worksheet. * `PR 96 `_ Correct descriptor for CharacterProperties.rtl * `#498 `_ Metadata is not essential to use the package. 2.3.1 (2015-11-20) ================== Bug fixes --------- * `#534 `_ Exception when using columns property in read-only mode. * `#536 `_ Incorrectly handle comments from Google Docs files. * `#539 `_ Flexible value types for conditional formatting. * `#542 `_ Missing content types for images. * `#543 `_ Make sure images fit containers on all OSes. * `#544 `_ Gracefully handle missing cell styles. * `#546 `_ ExternalLink duplicated when editing a file with macros. * `#548 `_ Exception with non-ASCII worksheet titles * `#551 `_ Combine multiple LineCharts Minor changes ------------- * `PR 88 `_ Fix page margins in parser. 2.3.0 (2015-10-20) ================== Major changes ------------- * Support the creation of chartsheets Bug fixes --------- * `#532 `_ Problems when cells have no style in read-only mode. Minor changes ------------- * PR 79 Make PlotArea editable in charts * Use graphicalProperties as the alias for spPr 2.3.0-b2 (2015-09-04) ===================== Bug fixes --------- * `#488 `_ Support hashValue attribute for sheetProtection * `#493 `_ Warn that unsupported extensions will be dropped * `#494 `_ Cells with exponentials causes a ValueError * `#497 `_ Scatter charts are broken * `#499 `_ Inconsistent conversion of localised datetimes * `#500 `_ Adding images leads to unreadable files * `#509 `_ Improve handling of sheet names * `#515 `_ Non-ascii titles have bad repr * `#516 `_ Ignore unassigned worksheets Minor changes ------------- * Worksheets are now iterable by row. * Assign individual cell styles only if they are explicitly set. 2.3.0-b1 (2015-06-29) ===================== Major changes ------------- * Shift to using (row, column) indexing for cells. Cells will at some point *lose* coordinates. * New implementation of conditional formatting. Databars now partially preserved. * et_xmlfile is now a standalone library. * Complete rewrite of chart package * Include a tokenizer for fomulae to be able to adjust cell references in them. PR 63 Minor changes ------------- * Read-only and write-only worksheets renamed. * Write-only workbooks support charts and images. * `PR76 `_ Prevent comment images from conflicting with VBA Bug fixes --------- * `#81 `_ Support stacked bar charts * `#88 `_ Charts break hyperlinks * `#97 `_ Pie and combination charts * `#99 `_ Quote worksheet names in chart references * `#150 `_ Support additional chart options * `#172 `_ Support surface charts * `#381 `_ Preserve named styles * `#470 `_ Adding more than 10 worksheets with the same name leads to duplicates sheet names and an invalid file 2.2.6 (unreleased) ================== Bug fixes --------- * `#502 `_ Unexpected keyword "mergeCell" * `#503 `_ tostring missing in dump_worksheet * `#506 `_ Non-ASCII formulae cannot be parsed * `#508 `_ Cannot save files with coloured tabs * Regex for ignoring named ranges is wrong (character class instead of prefix) 2.2.5 (2015-06-29) ================== Bug fixes --------- * `#463 `_ Unexpected keyword "mergeCell" * `#484 `_ Unusual dimensions breaks read-only mode * `#485 `_ Move return out of loop 2.2.4 (2015-06-17) ================== Bug fixes --------- * `#464 `_ Cannot use images when preserving macros * `#465 `_ ws.cell() returns an empty cell on read-only workbooks * `#467 `_ Cannot edit a file with ActiveX components * `#471 `_ Sheet properties elements must be in order * `#475 `_ Do not redefine class __slots__ in subclasses * `#477 `_ Write-only support for SheetProtection * `#478 `_ Write-only support for DataValidation * Improved regex when checking for datetime formats 2.2.3 (2015-05-26) ================== Bug fixes --------- * `#451 `_ fitToPage setting ignored * `#458 `_ Trailing spaces lost when saving files. * `#459 `_ setup.py install fails with Python 3 * `#462 `_ Vestigial rId conflicts when adding charts, images or comments * `#455 `_ Enable Zip64 extensions for all versions of Python 2.2.2 (2015-04-28) ================== Bug fixes --------- * `#447 `_ Uppercase datetime number formats not recognised. * `#453 `_ Borders broken in shared_styles. 2.2.1 (2015-03-31) ================== Minor changes ------------- * `PR54 `_ Improved precision on times near midnight. * `PR55 `_ Preserve macro buttons Bug fixes --------- * `#429 `_ Workbook fails to load because header and footers cannot be parsed. * `#433 `_ File-like object with encoding=None * `#434 `_ SyntaxError when writing page breaks. * `#436 `_ Read-only mode duplicates empty rows. * `#437 `_ Cell.offset raises an exception * `#438 `_ Cells with pivotButton and quotePrefix styles cannot be read * `#440 `_ Error when customised versions of builtin formats * `#442 `_ Exception raised when a fill element contains no children * `#444 `_ Styles cannot be copied 2.2.0 (2015-03-11) ================== Bug fixes --------- * `#415 `_ Improved exception when passing in invalid in memory files. 2.2.0-b1 (2015-02-18) ===================== Major changes ------------- * Cell styles deprecated, use formatting objects (fonts, fills, borders, etc.) directly instead * Charts will no longer try and calculate axes by default * Support for template file types - PR21 * Moved ancillary functions and classes into utils package - single place of reference * `PR 34 `_ Fully support page setup * Removed SAX-based XML Generator. Special thanks to Elias Rabel for implementing xmlfile for xml.etree * Preserve sheet view definitions in existing files (frozen panes, zoom, etc.) Bug fixes --------- * `#103 `_ Set the zoom of a sheet * `#199 `_ Hide gridlines * `#215 `_ Preserve sheet view setings * `#262 `_ Set the zoom of a sheet * `#392 `_ Worksheet header not read * `#387 `_ Cannot read files without styles.xml * `#410 `_ Exception when preserving whitespace in strings * `#417 `_ Cannot create print titles * `#420 `_ Rename confusing constants * `#422 `_ Preserve color index in a workbook if it differs from the standard Minor changes ------------- * Use a 2-way cache for column index lookups * Clean up tests in cells * `PR 40 `_ Support frozen panes and autofilter in write-only mode * Use ws.calculate_dimension(force=True) in read-only mode for unsized worksheets 2.1.5 (2015-02-18) ================== Bug fixes --------- * `#403 `_ Cannot add comments in write-only mode * `#401 `_ Creating cells in an empty row raises an exception * `#408 `_ from_excel adjustment for Julian dates 1 < x < 60 * `#409 `_ refersTo is an optional attribute Minor changes ------------- * Allow cells to be appended to standard worksheets for code compatibility with write-only mode. 2.1.4 (2014-12-16) ================== Bug fixes --------- * `#393 `_ IterableWorksheet skips empty cells in rows * `#394 `_ Date format is applied to all columns (while only first column contains dates) * `#395 `_ temporary files not cleaned properly * `#396 `_ Cannot write "=" in Excel file * `#398 `_ Cannot write empty rows in write-only mode with LXML installed Minor changes ------------- * Add relation namespace to root element for compatibility with iWork * Serialize comments relation in LXML-backend 2.1.3 (2014-12-09) ================== Minor changes ------------- * `PR 31 `_ Correct tutorial * `PR 32 `_ See #380 * `PR 37 `_ Bind worksheet to ColumnDimension objects Bug fixes --------- * `#379 `_ ws.append() doesn't set RowDimension Correctly * `#380 `_ empty cells formatted as datetimes raise exceptions 2.1.2 (2014-10-23) ================== Minor changes ------------- * `PR 30 `_ Fix regex for positive exponentials * `PR 28 `_ Fix for #328 Bug fixes --------- * `#120 `_, `#168 `_ defined names with formulae raise exceptions, `#292 `_ * `#328 `_ ValueError when reading cells with hyperlinks * `#369 `_ IndexError when reading definedNames * `#372 `_ number_format not consistently applied from styles 2.1.1 (2014-10-08) ================== Minor changes ------------- * PR 20 Support different workbook code names * Allow auto_axis keyword for ScatterCharts Bug fixes --------- * `#332 `_ Fills lost in ConditionalFormatting * `#360 `_ Support value="none" in attributes * `#363 `_ Support undocumented value for textRotation * `#364 `_ Preserve integers in read-only mode * `#366 `_ Complete read support for DataValidation * `#367 `_ Iterate over unsized worksheets 2.1.0 (2014-09-21) ================== Major changes ------------- * "read_only" and "write_only" new flags for workbooks * Support for reading and writing worksheet protection * Support for reading hidden rows * Cells now manage their styles directly * ColumnDimension and RowDimension object manage their styles directly * Use xmlfile for writing worksheets if available - around 3 times faster * Datavalidation now part of the worksheet package Minor changes ------------- * Number formats are now just strings * Strings can be used for RGB and aRGB colours for Fonts, Fills and Borders * Create all style tags in a single pass * Performance improvement when appending rows * Cleaner conversion of Python to Excel values * PR6 reserve formatting for empty rows * standard worksheets can append from ranges and generators Bug fixes --------- * `#153 `_ Cannot read visibility of sheets and rows * `#181 `_ No content type for worksheets * `241 `_ Cannot read sheets with inline strings * `322 `_ 1-indexing for merged cells * `339 `_ Correctly handle removal of cell protection * `341 `_ Cells with formulae do not round-trip * `347 `_ Read DataValidations * `353 `_ Support Defined Named Ranges to external workbooks 2.0.5 (2014-08-08) ================== Bug fixes --------- * `#348 `_ incorrect casting of boolean strings * `#349 `_ roundtripping cells with formulae 2.0.4 (2014-06-25) ================== Minor changes ------------- * Add a sample file illustrating colours Bug fixes --------- * `#331 `_ DARKYELLOW was incorrect * Correctly handle extend attribute for fonts 2.0.3 (2014-05-22) ================== Minor changes ------------- * Updated docs Bug fixes --------- * `#319 `_ Cannot load Workbooks with vertAlign styling for fonts 2.0.2 (2014-05-13) ================== 2.0.1 (2014-05-13) brown bag ============================= 2.0.0 (2014-05-13) brown bag ============================= Major changes ------------- * This is last release that will support Python 3.2 * Cells are referenced with 1-indexing: A1 == cell(row=1, column=1) * Use jdcal for more efficient and reliable conversion of datetimes * Significant speed up when reading files * Merged immutable styles * Type inference is disabled by default * RawCell renamed ReadOnlyCell * ReadOnlyCell.internal_value and ReadOnlyCell.value now behave the same as Cell * Provide no size information on unsized worksheets * Lower memory footprint when reading files Minor changes ------------- * All tests converted to pytest * Pyflakes used for static code analysis * Sample code in the documentation is automatically run * Support GradientFills * BaseColWidth set Pull requests ------------- * #70 Add filterColumn, sortCondition support to AutoFilter * #80 Reorder worksheets parts * #82 Update API for conditional formatting * #87 Add support for writing Protection styles, others * #89 Better handling of content types when preserving macros Bug fixes --------- * `#46 `_ ColumnDimension style error * `#86 `_ reader.worksheet.fast_parse sets booleans to integers * `#98 `_ Auto sizing column widths does not work * `#137 `_ Workbooks with chartsheets * `#185 `_ Invalid PageMargins * `#230 `_ Using \v in cells creates invalid files * `#243 `_ - IndexError when loading workbook * `#263 `_ - Forded conversion of line breaks * `#267 `_ - Raise exceptions when passed invalid types * `#270 `_ - Cannot open files which use non-standard sheet names or reference Ids * `#269 `_ - Handling unsized worksheets in IterableWorksheet * `#270 `_ - Handling Workbooks with non-standard references * `#275 `_ - Handling auto filters where there are only custom filters * `#277 `_ - Harmonise chart and cell coordinates * `#280 `_- Explicit exception raising for invalid characters * `#286 `_ - Optimized writer can not handle a datetime.time value * `#296 `_ - Cell coordinates not consistent with documentation * `#300 `_ - Missing column width causes load_workbook() exception * `#304 `_ - Handling Workbooks with absolute paths for worksheets (from Sharepoint) 1.8.6 (2014-05-05) ================== Minor changes ------------- Fixed typo for import Elementtree Bugfixes -------- * `#279 `_ Incorrect path for comments files on Windows 1.8.5 (2014-03-25) ================== Minor changes ------------- * The '=' string is no longer interpreted as a formula * When a client writes empty xml tags for cells (e.g. ), reader will not crash 1.8.4 (2014-02-25) ================== Bugfixes -------- * `#260 `_ better handling of undimensioned worksheets * `#268 `_ non-ascii in formualae * `#282 `_ correct implementation of register_namepsace for Python 2.6 1.8.3 (2014-02-09) ================== Major changes ------------- Always parse using cElementTree Minor changes ------------- Slight improvements in memory use when parsing * `#256 `_ - error when trying to read comments with optimised reader * `#260 `_ - unsized worksheets * `#264 `_ - only numeric cells can be dates 1.8.2 (2014-01-17) ================== * `#247 `_ - iterable worksheets open too many files * `#252 `_ - improved handling of lxml * `#253 `_ - better handling of unique sheetnames 1.8.1 (2014-01-14) ================== * `#246 `_ 1.8.0 (2014-01-08) ================== Compatibility ------------- Support for Python 2.5 dropped. Major changes ------------- * Support conditional formatting * Support lxml as backend * Support reading and writing comments * pytest as testrunner now required * Improvements in charts: new types, more reliable Minor changes ------------- * load_workbook now accepts data_only to allow extracting values only from formulae. Default is false. * Images can now be anchored to cells * Docs updated * Provisional benchmarking * Added convenience methods for accessing worksheets and cells by key 1.7.0 (2013-10-31) ================== Major changes ------------- Drops support for Python < 2.5 and last version to support Python 2.5 Compatibility ------------- Tests run on Python 2.5, 2.6, 2.7, 3.2, 3.3 Merged pull requests -------------------- * 27 Include more metadata * 41 Able to read files with chart sheets * 45 Configurable Worksheet classes * 3 Correct serialisation of Decimal * 36 Preserve VBA macros when reading files * 44 Handle empty oddheader and oddFooter tags * 43 Fixed issue that the reader never set the active sheet * 33 Reader set value and type explicitly and TYPE_ERROR checking * 22 added page breaks, fixed formula serialization * 39 Fix Python 2.6 compatibility * 47 Improvements in styling Known bugfixes -------------- * `#109 `_ * `#165 `_ * `#209 `_ * `#112 `_ * `#166 `_ * `#109 `_ * `#223 `_ * `#124 `_ * `#157 `_ Miscellaneous ------------- Performance improvements in optimised writer Docs updated ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/area.png0000644000000000000000000011156500000000000013750 0ustar00PNG  IHDRt٣sRGB@IDATx|F$!wP)"((X@>>DP  * {Nzu3lIn=;Ι[˗ ``L ͛a0uNc~{z+tJ5KT&~%{I 2 >m;NG Zn(ґ6xc[TVVѦ7-{m!)^{MI ёӱ:\UQYFjdjOyRk=?Qa*L,ާ&qZ:X:WCq+6{*)L/B,%"è|]C]b'@M2)_~he˳ 6 ~uZk׶jEbXRXOm4iT>-G^H~myצCGY kgkWǑ^%JqYs|[RzS\lMIzgF --kVHq:I!HСnvoDe؉ Tr~嗭!R^{e!ˑGGɽ-E>)Oq?"D]*yo /]ݣR&G'ӒKy0БUGy<=7ghPxS)z(-U @W)JW%U2N$?U?eyyHW_+<ʣ%26q=!C7('V_me^yj6G[zuDIiKE*bE[աVZh >>>|H+ʷJ,RHɟW%h^{qmtm|. @>*6'yخғG6EvJck7Q5O^X!<3`鼑,s TZeVQl3K?-9Ou7.[Y?ng4FBBZo yPn/2 ͓;\~ORnyqt2Υ_+T*{$w2~׶_[#/&ny5yK?lR%@#L#HbqwP'Rf W#<|_3Lm SԳ15E~upexũz߸q#\&ULN %{ĉ2ţ`~:VFpCcq^#e LB҅v҅2S9_QXH/Kd srohQ W% v6{3cHFwDQntOekef) /ˑGd#7)!&&<6tNI:% BT^(_ZAoy%!/1{EaZy}_<ċ&;rQ2L{Զ^g'G$hLS?Ke/GSSQtPn#Dmʛ.M4VfpB7tdiW$^D!zZ^ C_vnV[m(ūͯMr[;RzͫSFt2LUrCt&߁v_-wdfmTץDjޑ"_i:2~MQzij+\JGr'hͯ.SZ:؞=`d$:C~WEa䗲W~*RY¨|KNJqo:Vv|irWy\o[0w7-rG -ꯨJKڨWV~Yo~.>:'ٴ=z6oF+Cv9Kkk1+eP7+y+jQǫjM=Nc(!.44WZPѦz"dX?4?lpǞ٬[-.=%~!e #WW`S8gRq`J?IlW!VK4Hi~Ky&7\;~wƃwBSC>Oxt`xiW!i!}RVyj68mZKκ]DZDdEa2ejV$OmV-p5a䗽MV,cݵQO,vE`Sb-Z_YJ<&3Hl2U2}ei*adee̙3hذ!BBBčc;?|QPAAU%K ZJ~:Ztvn&-3kp{poɃڠcVhS8UP~tM/ky+Oe\|qg+VcL}5sm4kW4^]>1hy俚)~ CZm7Ud.~:QO{nRFt(9GoW'ıXMILBvIݲ<,W(CdKSY7e''iZON0lE3Q{ j/#1iyJ>O2'\/)~)kid^YlJJ'P)kQ+AS%OMXA%esrs'2/iQ5dK+,R[l#q/P-qEI1ћ2d^:P:Rz{GM~Y/8kGu1/%JQ#GR~()Ē#AeC kז^u?ڈ d0/o۫-޹%S70<>6g,LQG.2\}TIg/Vt(Qˣ Wq/Ng+\Ls{;Sɶo Wi)L3Ϙ?yչ_# tҥF>7xܾ};GOrZZpg=nU&ğ??>^Q[4#22Cް{I<"`3WmmދWr+5+`X25_L ,>e*'qQ'tYЛ'0G[o|nqg̘n /I1ށoŃ3e>l‘{P,KYk:5_˪ $E"7-2\\ ] p ǀxD}2LOvzLj27 ǏǠ [#z&aϒ0~" F">ȵdbX3Ldb˳H7k2Qnp'Vs>ÅڅCc p>^iNՒ^(aqϻ87s_/t{aҵ(.O1UV5 ";<6;<\;>ybpнw0n7g-} F _j<}֜xB Eg-+fa ah[|qbt/k" h^>{=H7<('xhgL'\7D"1"`ij'6YC>]]w <,5=ԏXrs:;bX|gV霧)ˡS3ՏFI[f!agg`@ :c]"ep h!%6n6h&,ًc^F3~r|b i=n |W'qxe(_,VG{$RL]֏$_ !,rÎ 0$[`5kG?*޷ƦUN;lWyHR -j?,;59!hi>%bj˷Ǧc]%2˴N[0XV6>5ڮӃ|>wpWfziwDQzq2 2vGt5ߝVLܳX\+>^B# ?yԳU%f߀+!)H'0~յ•kt;=>tW"H'n,=)? gm#nhʢ:c ۋ[c1|t+v9Ŗ3u.~.8;!Y(=3_Ƣs{+7Ej>hadFj'qMUG\γ+Q{cjE$b\+([M@9>Ġ)1{$&! yW%#3 z÷XsQͣ>g"B!9VTA<t}1d!/{&Sz.C:8H_B_Q 6Z_ix2S+8ؓXVBka,Bf;ؓTdFn| *%HCzĐ luNl_4wƾ ;2qdƳvSJ>\lW8fjzˊDH_>Ey<ԻHUo0vvn5xa2<5<:d6iWߒgRxY eg@ n[(d@w1۱:nLNL l:·vGDfPf*úbb]Cqe(`[,n΋װ}ҞTQiF c/T͆I ]N|#F!R,=)>I>trH3RHek mVfz;ۖ6> bgJ/ݞX(,cǗQ%6}fi+|Ep.F#O,mq2=;9 C@գVj կAպXo*uq>h& ~j*p{V, `L 0J͝;שߘK{cL 0&ج]ʚq11)3u<ǗX͊9ZpL 0&qJbhdPvc+mSN6W͊9JY1q Miӌ_4,PɄZ0KZdo~({'FN0;ׯ͊91q{Sf%P|Mr|.XQ!2w{U` aYY$ ?\VS[fx9훸3tyЁurQLuXQMF)p6b1EY.v\dd)N<5L9]2rr-AjbBôy&&v©ĝeb˳qK]X݉_1o]stjN:qfc5_8n!JV8YfჅ?`4VL9lViߚtpsNh$`N \p#`UqhxMt>f !^B+[KfŜtl ޝCn$a'5e5Uiɇ Ƥ[ :5I-232:B,6+2*`N[{|ZKݗ9N]Q b `^[)'UY1'\C;&|:N+3ǰp pLf8ՈRG yB[GqΕc9_lVԎ7ƊaJj;3<#p{g{\dggC/F`|"@+1<;'cI[lVWԎ;A/P8q) B+6\+8uE8!>Љ@i_M9UAܲ 6&-'+/ d5Eũ ,dmY7 0&r\!`L 26+bWfp\L*m.3ueb\"`L 1'֤,Bz\4Sxk^<3jq24q5mdL)\qn+bN~?B;Y &s5]řc9-Y%K"wܫi4&>^%z%ݽ:@-Qd['n~,=ƌ`$Wٹ/1q^$$K\R+3u.~.V]w/HlWԢy,W5z[7fnIĸV V.>sOB}|b"`35qb:%+v·1&˜5M''jX_ _nĚ t d&fd">%@&wG~~Fw̴,.8Vg [CbmᗫC/lvO=aUYy!=N0cj=bIƨsXT]G@v6 X1qLmRH `Qqfl ;t=]-:Nܐn [ܒvrz3g? C`q $bU;X'`3c|CCu ]TW2ْ [xc Po;߈Yrm` v^4-GCPezxR3wX} ,U4ux)+FAbl&s{汜P{/G>ŋ]GB߿^|BLZĬPotp#-w9̹T"`Qq_x)Gr7pZD YKѩ汜Z+n-B!xDދGKvE!B1%$HN;fjx\5s12p||ED|`ec9|w*0LRr j!*m1aW!F]F_ r\z;&i9rw&PũGʹH3 6u+WlV2ض;fZ=X\L 0&O͊9)`nL͊ŭJL2Sp|O٬`nLgqz"gL:թmXNڥ gXθ|z Me.Lf͊#`uUmھ`[_xT+" c —[T2/d wJL` [c1|t+v9Ŭҫ bw$b =lݕO%&4yq^8U9TI$$+y}+FɌ X4\h6+pJal͊98RՒ :& (fkb k$n2@6&WU:S`8/"22Wbm->EʩVǪ]F6KfŜ wVgD"*=yˊ,!6.*6H3VQbk bg=Ɨ:X뮘!̊]LfƲY1Dm0S|8#hK.DUX#F˽Nvc9Nw(M`9*-͊e!E⬋~|[2ӕOCKIuz*Kkfpj512Sp|O٬`nL'gA4k~nLGydm>m9{c,:糶m38tb 0eh(j6|$|YU&ƵbZ%3n֝(IxnsZ1nE=;>"lpP-g#Vj ;(-4󿘾ַ‚^yX֛7A<[ 7nHc6zI/r”Y{1{D44 %ЈMYY6WHĭ XT>gl:gAb s<ޯ9wDV_SxJ }ց@Гxd'8%g]%ȃ'ϊS3?bVכ#uX4lWiw@yEw,3'HR!_gӪu4Llyv4b2u);+kN"ЩWG4vY2׶ꎾūI\=*͸lܛ㓕kaZ,`UU<D{4f:G8\7CI,[?I:N8~n |S#6F,*ZƕA(ž|nN&5LcodHׯu'kXCk`sRѠΘ8x qG}U2l ^xw&[ `Wƹ(K4߹eF:EY]{ʖbtEbП9ZsM']RE. cw ;FJ=Vz]<` S]pqb `QqZPp) "eX}^Q O,xk֢w%NY%yo11O,U82!1{1,~z[-#г;;8X^T_g>2kr}qZ$>"tOkN=l\a:]\_ BrfxY%CRx:[V2%83fT%l0>Q0b:hKQqv# i$ЪYr{cV \ fjSE]EhqZw$`Qq򁟯5!WwV  ӭ DLԡט9'Z*NE lY̵( 0&J͊9/`F͊JL2Sp|O٬`nLgnJ54l E';c= {nz mm cOY\qnkh;~nXwgYeBH;KVmGMfJi\Q,31\' E=6aB0Ozh-6 /E3g17NU2sIK'bx; ARp=*`# XQ!ݷpC^|1k.Bi)NW'z X*yi%q6w"`UqQX~\0 wʒ;xOD-%jq zi;+z*MVgt6祍kq+/L6e?Eדq~K\+a-[bIxЏI<̴B8{xK?&})/hg^zQϗܣ[fO,4j^}fZYrύhMgd ^j S4{A@SBynx혹:=6J0+30 +e!EDX +w5nmf%Fe".,M3W>h);93uK.Xt5AL 0& \`L 6+bfp\L*m.3ueb\"`L 1H 8<`iu3 7X4&(3}7#Fw>Y7>nbY 0&ܔUYt$z!gX4y? Qi[) 0&MVzu*UDm̥u1"`h- <I#`L Xqw)?8̛GO_6*w `v XT8|5g P>; `L 38tm.|Sh%FhϞB;`٘`L !`q7(Hɖc Dhdpi*G3&8 Æ?C1"೻@0X0&`XTd4ݥGJv>|| (@+1ȴW"3&pcYq`0!ȍ1hL 0&G4fQ|$9`L x6+dL 0G`b"YET N5%al̔:K}f-D&pc68S/t]Bn̂EcL 0&`Y?,s>bzѧ@ { ٭0&p ՠWEi?]O_QBL 0&*KW-y6WZ\bڌ;&`J Vxc sqyZ#R{Ï-yr3& `q3/zW W.,` o^! ř?j f`L 0!`Qqzfj`Ѱ< 8m& P_<,(`L 0s(GŹh~ȥÑe^1& gq6Qr_zC Ɉ 8,*`L 0-ȿr.wjh0+ 0&DRvL 0&S(HLa|aibZhWWe2>2&&ř}Ve#OUґZ9`&psZrPXPVQq &PpyWa\\N7+hYrW$g7˗W# ;K.oY1D 1}tvmvo޼r vލ}r Ν;nsL>\2nV- L |߿d6l؀#GVck,WM_xo!&Mŋ]v8z(VZonF8)zZR7+N'AbN2/٬/233eW_Yf?~TO=K\w u]| ߏ#G(=gS'{Lʓpw9N2+8XZSK(6D`܍/Bz?~2 Yv?(.hBI[Vz_K۾};Ȉ|6mP~}eh)[,S}(IIR%BʇmV! HJJ˕"y]w3?(..V5Pt _Ǝ('*?ǩSqF%iXGԤ{1<#شiHڵKzyy)ʖ(E\0)۷W^Ms&LS1+N-+|fzp=QR = D 9R`>SL:Kܹ'(2R(ӦMSzu;kРRΘ1cI8?̙3A*?#?&0zm)N~%G=Պ:R+B QSRR*,#￱vZS&L0]n9sF9N 6l2g)e\{^7߬,@IDAT(L*H6պuj x,P%,[Lӌ-3I _ٳg[zj6m(uBa`:~i%K^AEvQz4JCZe̘1M41St9s(/ڍ,X$W[3w%P:1aŬ +Brz sx. HbbzSx\0""4oHLZ)gA;ǧD hH\Z*)DQ99-!Gs{4$JhؖDZKz_z2IA{ 2ivO+O(x1w&`R̊ѻżX'CaW(w²yZAJ4Hs ~b"R4GH[yҭ[⣏>R?h.hޓVy睊CӤ[QFfщX\e]%gj* ^0+<):s4Іz`+5GЪ][i[rwG󫁁2GZ=Kwԓ}vUELhG{mVY+Ù0ON9Z'Lk*NSJ"9`bvŸL 0&0lVa( &lV2`J@3If j2̉EG 1;޵Bֹ>dsL 0&ԍnV, >Z|tmYo}#\WJʕ1&v&iݬXM#[4Cp%wr4oVp`L T%T̊!YW~~iλPhYA1aӪR 0&@U0)Nf U{l:'j/ dk1& %>͊G{_oBrHchJӃ 0&Jz6\ډ9mG^ XuHt6sp$`L 0$P8ɬFItĥ^`šo @]X0$&A[€ B1&F8b ؏Gp/btIݞdG&&h,m&xaE\nMe#2scL 0&9L3?<"-ȭC!.GS ۆ6*f ʕ+˗/*Kr`L 0ͪZMCU 8pOƎ; oQ9 `L +ܹsK:p5Ր0Ν;c֭8y$'K > J?X$s!% ZÁL T1뮻kt!6mTXx™ʛaŊMZҐz ={ī5k(ff֭Ԯ]Lu:㲩B%_HHH4`5y_V$' S(wIRWg`` rg9Q4 @%T@%&p+9N2+8/5MN˧w< E8WPzYYYSz聽{*ahԨ`Uv3&c VZ7+m ˏ"Hw,{}\ܬ… 1g[ e=à1pZaˎ 0&$`R͊ /^xmK.%e ښk׮YUN:UWG&`D83q15DMWE4-XU@1&0)Nf&|g0H-{/pw1y?שL 0&l,Қg)쌗yo=nl䏠`TD|`Lhe((ig<[DXqZšL 0&LCbV,دqGNqXPK}/]VZח˲1&IqZ3+672Ï9øyam-PY?rL-[(-Ν;_fRrL 0&vLӚY ܜ<>>u_بXa7/۫W/>]ތ34i0yul]# 0&LӚY1:dKj0!WӒ6lM%+p)m{ALL 0&PMʵ80@/v)((;TҤc7oތ'xBde׼ysw}ظq6ϙ`L \M6]UՕ,DGG[bh`L 0k6.xo)%͊R=zkKo~!FiJwiB?~Mq4@^1W"@.߷οbAƪȬX"V횔ndjG^BPI(,[T%vsصky̞=[7T }wgGE֭zj| ž}0bzĉAMi<#j,z}fh?33Syxn(..V"kNyvy<'0)N[fdvei n\/cx+ʓf(iXaÆj⌊}B+t[\u[~7;Qk٫mڨS7I(rsE9s6P/"$$:tرcѩS't >L( /5j'ۨQ#~Ps*Pqq!v?b>2tHy=D#v}+obf4BezӋ 7]%A] nVbkN̘6kgxjԞ/->}ɿ{n$%%)J]v->_NC+=ƍ| JaԛReq?<,|tRYQQEyy#;'EQ!%rIͺ;Dѻh;b_~gr"0ň^(8Tűs>4VUvx^z< EػkIC[X <>K-E=eDEt^u')s$eJSZCnV&eԩSC Ry=J/?Gl^\?[9E7t]f 'M!Aܠ/C>|Z@7FQeۦ A*Cy[6qJLiR6x_>vܩ}W^iJJ2mf:uA4Y!'&a|ļ|JQ8y\4 邁=oC/Nj @sM!!{Bd@bV,ŭxQ%ʹ^x;|%6 wV@Ǐ 7΋/*M}k Zdʒ"1S\l\s)(.Dtqq:w[ȘᯩʜRVQT@|÷yoV"skrs=m&iլ_ΝM0-oP{^(M_Spz{Qv2dHYOر.:mger-y(Js6vO837Vo4,$ۤCwaN0A| ]hvڶm(v! 9RWz"#3|兄C̉ت(#;@ۦ7_gy![8>y̜$q㫚_#eVL]`~EDw`֭B\fY+qAGyj.2Rx{ !+^Fjc.eky-Xgh*\j?˜>`AYIqqڐ=...\Pfi8}l>-"➦QRYR*iΒai3ԬV[o -Dؗht ]3 :B+֑qHiҧ&^sq5)&pYb'iF/He^z`W#&< do3jlrNH?U^EVнȧCbVn'T [g/I~afE5E81+F魌#ִ7=9//ddʦ5yb;ɈfCC+{_'AHK^ʷq+]ɫk"#'|fvAʹIq2+  ?=rW0eS= :mіy&I[oUǖsiWĦW\̣._\i '8/Jrս1Oμ;^Cw}Ɇ"/rXofi#s{[XqNWi'M8m#hw5nZ(̯Jݻ76n܈#F(zRgǏ={\;:u s1LiQю;b_ui*ߡC\K[}-a9(x&mFjO\_hT-DӋ!ui42C6m]Ǘ|>8E$`R͊Qz8r"DηᑻC`5D .cذah[= ̉ѮAY@lO“۷oX~*ʐ7:Rls+rxfRbߌ䧉?ExuW'&axRWMȑ#1|P*=\ƌ|p m6fƌ2e%5'׭[d6W:.55gϟ{ML\mvSb^|'/*&4 r \bGl07\ʷOJs yD&mG. WVpݻWXs-}JFH“N;WƧ1gЋO^uEFv7"#6p#@8Cg~ƃtj-TqYd)ݦtLcD]@d\: 3aq3< U{9HPwMi,}b/YiWߣG%Fp5c]ž}bPI:B.^(/?}~wx\`0 Z5+֪m)V/٦0g{M${SЧ(Z(M9Ț 3$Hyv r [vL:ڪ,!7ܛl4:D/EZf6/SeVY?6zx F] DG%UԳ;v2)+r S>۷/?9gԩ-?ljf`N$@a6:k&;@}ND^Kf ķ;Ű,D\4Iq2+sW;3/ )HWc@pB>6[C Dof UVq&& iifUɋAre,M[8D|eaLJ\5Iqk`X TvEMOgggcȐ!'#L SSή]YS(za쪞qlr3®oX\֬+As~hӤ0=Fܤmӕ*FyIێ~ɫf8:2+F7O?u) { ~3qDs=`e0G_I< iOxWCοTr>6h?pz-N^JWp5+xbe 9TKʴ"p8- r8%6q*h24+ ~2\γh8-#$t;y 4 ou-"VÎ x2zxF܎k ÷ze!@=d/{5LjOM>zfyLӖY1俱t/,KJ0=ޏ[W 1z#bӦMcY-W+B>=*6o%{CXSaDu"IqZ7+߮e]S7{ ¤Xr"bSJvT(;g)ǎSPfNܜ@v^2~"Dn'uGUe/=7z/" e *V {_]Ŋ\ve Ų*tA`)`(Z '^fH`L&{7w2s9"@~{MiPiVȪrufҴ jC-2b11>"eKH }5j Z>@f~Ҋ1I9cVEP#''gtLA~eNKʄ @qл,@b4_8ъe!bg#ԫQ]1Tb{6.ݸk5& z ǚ?qC+80Y}J_E GԾAv[39Tb̟v!--[бcG|fOZj0a@4k,Gߙv̘1 5YBB\@m/>_6lҸK%9)>?QbB˼LfKVYv]8Щ;g'nǶXSFp+z|x g]nt9(KZIPPP&y_ta_5nuϦ3 gi~qzkg#ѡ2EALo7ܛ@fF|ѴY{o×];#4"~~voP`hbQa=7vF`4Wf"gPNgFKa߾} MXc~ᇆk(yyy&;9;<=z4DX?.aĠ9.(FdxɖTPsXIl2A Ю h"B C$EiE!zݢ,WǿCѯ(DtC,eDKЁʔ[YYY-o'rpNϞQP/W͔k\[jS8sZ(0$?U:_w}7-[fA pΝo3.MW$A5Jo6644s(!!!2N`ONH^mqѽ=n0B",[If 0Ej Ls嘑*C 48VGQa]d)2<#CP$9EKJm(%e6$r+*̪>~܎ē7+9))k}7d^ &/bu n1Щsg4˫+ɏKimVmU5KKY&O!^htE+//{sP B"3!9 V21bxO>i1,X`4f}22h?#䗊 )’ս/(0L~!BtwEFV){ȱ٭}eӠ(?͸W a!&aIE W!8YL؈,3@T=K4Pɼs KҕpbErC+ew]),ɔ LY.l,9a?\Ũ退fk3ЋK [Zf3Z1voz2tnEcnYܳ䫯2)z 9u)Y[5{d\x#5ڻv#P-Kwox.ױe'9^|E8pIHsM7:|xMp?n:\}Y;CEiUGWXX_1{O(>g:.OAAtqΛ7ϐ2k0-Yh>Sk&H*׽"ВpYvʕE㏿#XZ %1жj+fu5Ryn߾ݤ< gj;;ߘ?ܬPК^a㧟Iaxp^ :ChZ.WY~xrw3I'?1:M;x0z&Ma&Bfy5w1%kvv6Lb2 SK|رضm)g5ZtvKU~ D8YH3-(Y#sb17b̰$G+@)OǍgbK#f3iLI$ߠkԨ>K/5k/b09O>xpw8}d7o-q XYё57auWWV^Dž :,ceH_y啚z*$\2/c`g'm\8Tmܨ&ےu*W\qpBqxM i䐷n6͛7c>Z?1X{V,їR惬~CX=’3${`TMvtp xGJFEIwӦMի  /]ׯ? Tw"P 7[n11ᤇKlIΝMh]@!3g6ʕs 3gJ*A!--5Nf'7%$ g͚~|/DB5[ 89hS5]b`QjFٺjK裧eS p=(ɮ>| Oػ }idC8ikHp޻1&CMSιE*8IDb ZO`! 4t73ɓn5zaM>ܬl}\|qL8fB)|VV%>p)(ʴmt%$/F ,8(mJ#+RH5OK$Bq6Čb {|̄tHHԢi ۢbnH~$l-S@f.C+n8t9'.H+ EQ+Z1şyvmr6 -Q_6l0 \L0́۩S'3::Epҕ]-L3W $ڈu|lޫ@2\\RTRc2#j9YW o/zf;bКϴbDW0}UQZs3KW:a]YؕcKwCSpD5L+s>B|$#w׺ ѣG[MrYzkkV׽"@*ʱ7u!_2W赲 E@hEXU |!A.E3f4뭷ٶ6Yݬ`h孊@Aq&ػ]c kU+GT/eaH%o(S^^.r.)u|hdGٴḭfE`ZrlKZ6L"&p(NWba>/_ EX d&sgaÆ!>>0\wuHOOoiw#@mVPܵ>wDYp9OP@8]ъv Jm+🯾GqIb@-S IJJ$ZҥK)j}ZH݉-“E#m:Ecp(N{Ŕ',s'ʺƜŸ wmPYY}03?"֮](E(//Δ gwNz5yEm:E8wͯ,?`p0c5¶mŞVn%@`wǫ+LkE]l!cKň膉ºҷ('Gy-qleOh$Xv0ֳ[yH͖M_$zp^d5op iu&<_ٵZu*+ˑ3f㏺ ;!AQm}X@Iq"V$i"iPнcǎ8p ȃ|M79MSIgγ$82?f4bol>]xM Q,t.,+oaY \<}B*] Q)2( ZqF|&mBkV<[Q~OgO zy9+,vl>5*OmܹQQQꫯS&ej,` Cv`sN+fCN[8eGDL0КcLHZ2믿ƌ3̞<&Mji<=Ed g\m$zߴލJϚ8*:fw{;ʕ1)L)7C.eʗ_~?##tGHҘQBCCvl,Mڅx'V`Wjdg+|k֬ԩSCdڼ~<"WUƠ״te}tebk%WQ[NdHH ){` ˕q5 99>.\zxٲej 7@?řczoV8p(΃%zg}Fe''$$EINM+|\r Wgw ]|X#7oll}z"iċ^]Gb妷ˤ&*/TT S… qw &a9SՍ;ټy3On;vϟ? zWXakm,y}&iȏ7F25ƹ5U233  'e۶mƍtR_ƤeʋdD+cwWh<4{ E}dhT]T$XrY@ _`<٫aƍÖ-[йsgÉl'_3 zpiBV -E9Pwm\ dYZw!Ye믿:UoD] yihY~ߵRbͶ]ntmr%yfϞ *Wq2h̙3qw9h aok)S*,u)ìY̋\eK7%4t,jHCHf\d n$1#jV%ȷ^xZ 89Murn@uYj/_\MD}5n=Yh "B;!2;C!(~A((F~Q'HTTT^9[Ym!*< *|]EsQ^Q|9ռē5ʓO`!_4|g ii4c׭[ɓ'[jsZc_ J#{ t6r޽{Ҝ6myaO=.2#gPCxxxx- cgSD|,C#.7  BM14W KuBczE6Q(C;"80DQRjCie<6Y%,)"2z**MNoaMwlK+Cqm.a03Ȝ10:~֞퐳weN1bWp/0.nݺYyOo #q5.,1[nɏw8B;DHbl?lEFVjݾUJ}}!UW ea!2WaaIE,D^I*T^\#1٘v5ihF/cbLv8 K=k&|#z4#7)uTpQ;'Z(dUQ;eB'[RjA j(pt'I*-RsB5$֪[?FWxd(GXł ¦T  JSmpPy85^4bbMHOj  op/T^8cRS~Bi0f'n \*VZnk @h!ꯨ8lu yS~Bcd.>f+%J/]FjiC(QHyX3byy(HV9\mjCqZ1 TSA.Xud=͔Pj?8}7|R OQКPApk_I-`Q]/ *e%ynI%孫lDGѥM$ԏ(q5n =?UZ9ۮhMi0_ xX\7nըܦ%pϵC5A= EּFEeB)(Yaz{n0DwBǘ)2Jo(UT:/>͍|z삨cWs(Hd+.ALݪZ]|8suJ%WKo &2^(~_-Ya~چ3ϬW5A~{r-PC i`c*i0Jf M-ɸ}Ty\&ѧ I_o[Q(V X$ s[dmIjE&hZv@qVL#Z1?;XTX$"+eޱDWb՜$/3*dJ !׷o_)}M\UEMdM5HT15f|5V*72sӰ[qbQΥbZ\dn*kЊi֣%ʾ~^6_p|/(ob-6aX&]I*@{AβRsL֥2[Na"%zV"p88sZj8M^ ߒG"JҐn_r8뽊"4$dTEp'V,{nqoW&L"Iq'Z"("ty8uֳ"(@AMҊx"(Eє>ĹT1*"("p(AuxZ_O'rrݻ%׶E@P<gqv%gVZԧKImg9dx)mLw_?g]SE@hA/ގ4Kfr"xױxm7 z[~Gwy`uѸB"k0=zBPD & b2Ӝh݂Q!@n1aksvÚ8k)~{I>7̹?[n5-#h-Xc kQQQ%IDAT9oD𙙙 Y\luW G^9>kP:N طIzǃQw!ʆx&IBq mPY#G#dUcގ|x6<|8֭[gN: ܼ]ty.Zn4-N{9>%;PrUÑ7~椯>NjTRTB1^I'd*۷=PٶqzSӻh8g֪d~SDi}_Aq1i[LLl Rfć/L BԌ-iՊ"(m8}RV]䣨]FA1=0*=V)2?a fyITiE@P-N_;'7.^faHD |I,z g+G\cbVq("(މQ&`Μ+데,u7lH\agB\`9M([f-PE@PiKA ѧ)B-}0m4^'|'tͭ}`n^z$_I&{nmS*#+ eԋ/?U{T}~N:r f̘ 6/*G@i+x vڵ=37n=XǸ|rp [[⢋.-4L<SL1̜9[l&+M6! 7tc/YNZ'|I4~TTRq~95(//kwލ jv7=0v<-[ <t*]J+x]ɷ|s$''r\㦤`wfJOO7 Np(1cO<>Lɗ*邂Y6ڨd VZz?x`$7|]h^m& >&38Z,1Wm.]0~x|uMco_hiwqx0|M؃Gc+ }ѱ 4`W}e|Ԝ;裍e *Xs )̎?xs`Ĩ4ɾBKzŦPqz|x̗2$<:)C ?k֫7rn*Ώ[n^5N0?ӭ"ӺM^7oy <OZrDw݊^T_\xV#eǎrZ-i(-Ν;R|if%VΣ1p7tom\T5/2_~9^u=3FJƿynޘkϓ^$Z֜n񐊨,×psʈlM*͇Qiłu$&z6k+}ٿV߾})#G)$'08r;wy]T/ƍ7h9~6>1¼p|$|>|֜?wu7 ьVZ*W +pX^|A`7 -k4>۷oOB}3Tag!%T,;14U d~YK]>'q.?Bm]HC ˼-m-zmP rTѡNխ=|&h4UЊoK+V\"u%Ȕ}}m;?ƺJ`4TARQETA^ =Cj.-s@Ҋ$N+ב,i9^zFPE#p:k*/lhZ("XVlDT "'= J +"(u[.iPޜo/Q"(@{@(΃ъuo6EOo}B?)"(ދ<l.iǼ"("PZQO'E@PE@ҊED?+"V*.jK0pqZ SL5Yf.r&TQCDZb|y,\?raMd 1?ܫ ,~Kn^jK!@GSO=З;l9ΐ3I9׿"9ݣs5FFzzzXPQPeC||1d/c~Uȓs;v#fOޱGl3tGTwq:3ؗ_~_{ʐJ\veX`938\?p@`(͆}%pl%;E@>-RE@h ׯ?O<#1c޽{+Æ ×_~iя?AEG2n [lȑ#A|b̘1^IGB`i+ZĵǻK}|Zt-PAQ҆MoZ8q;w\1egy Qi(@ `8mb 1Õy^{,2!u:*m۷W_}uKK( ,7o׼[+ʕ[lNO B(NWbG`+M|⓹[%̾7'hnj3 o\ƍ7(qy cǎXl[|Wv…xGxb L4=m4p Ƣ$"sΝk"giKG!33^xوϟZǏotVpjW֤(0s e9`0 :|px뭷p'KQHi^pgΜiRֵi&G(@ #.#{FrK3լ*m2gϞ&ҶTPvڵKL=Ώ;ni"0߿ɣۨQ*"eWkzct TD@iE E@P!`\ъزDZBT XЩ}}]њE@PG(N״b@ʷ1oc,ږ&6 co +?a"([0Ӣ-U(ڧÜsaa4{iǃґY(S5[V("wZbYbZ*[䤠8S̠t iE@Pw#`W.iv'ٟ{/qaD5KyDSE@lj%@pF+V>ӞN <ȳSE@P܋CqVlw |0erfl[(O!MtU}Z"(@[@j]ъ HMQԥ'zDVb!D)>*" Z!2k|^d%GǓz8"("n Z16c7lAuu.5BSE@hA*Lj_&@PE_dR("4I*J+TzE@PA#i{=RUU)po{H:8]ъլ$=U5O89$D;Gg67Ww(9s.:-{(΃ъKŻ{4:1[e;)"(\XOƳz ]J("(4b 1/a`*`. Ǔ?f]XPE@oqځhV7qn.@qL%ֽ.>1C,T|h ?E@PE!$؛  C~Z1ш FPU~~ť8}6ߊWPE@0^W&HZ \.GA4g("KZtܑkP|QKfXE@PvQi*j5sk$6APE*oٲe3fLy>խHC^|KTK[p7d|_~5˨ɱTi|J .e2Va2%,UIFDy@%sT#ܫq[hs~M|Xr4ҕԷG_?mi|sEJ-U"U䯏~ʦZ>?gSSU)֭O_m`i;4 ""1"&Ⱦ__6.*[ٔMZ_F+-Ӱ*ש~W̴'P˿?lͽonao<-'~x+* GUVRQetGӦMeejڸ0y<$Nހ͙emnKZ'|^1NGٞo,:o-@gc7 QQ5KKٮ"=1\T=,WQqɮN*9~_X3NQ&z4<եީd{\/N7F5J+ #ڭl6W|UWe;^/UQ"g];&gpQϴJ#]xԵ='e,E/Pvo4BA ,Y^{,6m FYQqcwlj֭o SRMFޤMɷ߇/Kĺ‚ױjokLG[\xʦZ> SOi%KڼadNO« i3cD f L<\U)֭O”.~C_[}}V E+qf݌9glf?Vmg^5M/_uڪlK*nj7 w9M8"'|w*)֭O”.b N͙JPM4i-[Fh4# AZZZ")a,t?TI%)Hmצ%wQh7ao~T=j6G/q.Q}UCR /6|lsy &1 ~KѾff:ӱrxTHG[9jͿRe@dffP21DW}tQu jU*\ѱrpIS.&!@Nx11uSpyV;07ur=jNeKʏxVa}pC5Gǔ/?қY~4YSWpS ℸݩJxO_>Қڞkn':HC2tl%*,""ZICV*r"ñ0"Dqm#w_.5\Ե~2Ͷt|sNO{dB"/9O7omMPx; 9?E(?Bn2c}JSWҜ%_[Vm3]]Fpr`mQ8~L(/+UO:h7uk~m~!_ο&6&\ˏGϙ6P\/_3ePiTގQGnsZ\_ݯuz;Q:|ygʾdGCU˓µtsԀ֭[Y6p2aǩl&d7 D-Fqcq<ھZq^u'.v6S>]k/&uKmՍΑi+3[ςw"*<ѫ[/@?ˢn~Uw՞*/P,ϵPuOa*0eS1y}܅k"7]/YS ~n=OoWQ7ŖPxc[>f z\niH.Oq'_] l?KWgn)+->c3Gƶô? OqsQA$d!'=t?*Y&c(܀P^.WǣC˭ʨ:W[_}O̦*LVȏO?|*JD{Obq)]e@ݏ*4{*ն\7\'_VKiGS񔭏w~ŵMWiG (,g,F*"ϔ:זmW6og≷A S)~"-3R~lUg Gi/K"܃ɭ7?;!>1i:5*KN=-6?D*Wٔ^ bLêĕ.~ԍlq֡v8Zm\QQM ǥo~s+CS rA "~[&]ʦZ>0}\G+hUT^ainw$ZL$u*<C#껳*yY.PmU6ez]fj)#wXv|{SDC@νЩ_ZQT-˫_WS-9rF=-^B ɓطobbb)WRbPԩJ(iN(7#]8o_u  [ :#boiWͭi|uݨ޼z5Owlos#poxTc}Z:֗>~MõӚMOOO`ŁXFM?"Gv(O.?YG^iJk"&_p9pk}"*ŅnU('#i~ׇkJ=p:VLɭ]85õimpi! ?OK]*S^ML!( ,*sŊ*K;8+JO>7ix8Od"5XY~lU*̙MiTr61}XGU嫺۷_f+(Cʭ 4TSPW8 4lrrMF9qP ?-07LGM!zǑƪUA(r; 篏w0:]u:e2k!/r+];/_1]lTbukuTֆ)6L-UDo.~uf._]_6r/_)ۜWejឧ6ڪpGe( w~6[|hD } Ϣ\FGcmr+[^o3UUxq|SUw&U#N#N {_n%nZ7/#?1UeD7SD}[>wV ^kqLlvxXWo^vmpu Vw`3^9Ѓ']/u%(آqφlgZM(2i/.8 Kۯt.s2s~|)~ؕfN#6s/ғ Wvb),ؾ7Kky@~v~Z%s\7 ˯cB?Bz=u ~ GŦ/bDº8 ~~r~4L׭*S K[9uV46kaԉ(p$ܛ'VcKUx@& -)Qm8Y5|Ių|H$6X2}`5y=sN!;wcY gLt( wǰ30țC\-x~Pw{YnĿBm%9 sD-=Z!Hl%w O ڕȡDoֳ"D ZQxvw6vxK{&RX sG|]Vapi<Fӷp(U"ŧE^;L͞48,2]R_[{:DnL X} BHԒFq\x.DFE+Py$MoA/ p4P9t8% q]:RAobwp%?\s_7^wpg;p s*dačF|s>߂V#q "4?d♘ijZct#[ Q i6*mbZ ?w~7Ve$Ϗ"&1FO4G3 I&4!V݃x S1br[8t)Mh0&t³~pxxx-T Qº[q4"}b@%EHLs;ӱRhjDbQyEE(+J'b޺$TtXD&bay|qq i.RR냹\Tl@acԴɝ;` sk`zZ;X7ov1hiɫc[XmS sr ִXMzs?8uq4vE_k?Ɔ<#ZaӴt5]cv̌< /p($WScDŽ%a EuH."=\Ê`}R]Ὥ2EEzW0-؇f]YHM5g:6L xtFTΔ1CD*\U.?fz֚_k??b>2{ mQ8Takwqc]k_ąEm_߿ #DX8tV^CfK[Fphvnk&bwnN܂GGCՓVʛ!_a",ݭ`v5){O ‚Kȸz>cI#ԡ6n-Lť(H>+o^p0&m s̑ccO[;|aw"*CE8Px8NF"FW(Cualg!\-<#*D#fs8̈́9ߟ״Ѷg΅FL]A6S.O2UQ4; i!BGNբ|z7s(yG:o ^OuI˭OWcGW<7^> vqS; cL X'[2|=M E*D7h4NFB"Diȁg0KpL46{-Lgh?(ϗ w;￘RˍքrH|=K_t?@4|+-*^^c_D*!ۄ[6?} D㏗Gb0lR_œea,8_ i> .lhx:+Js(Rfz:,oOM qQD!6>܄R/6u[zeQAeѤ@*nyC%ںA魢7n슏3OE[+YŖ0{< Z[:a. Qw/ì]wYycNY/Z%fjE&!` DP_v~ܟb{"1cid"*!Rpf) Nh 8Sz={6ӗ?l(،ۺ܈3?(RљsfTSE[k>M @Aз_iƓ A m8g= a&P`үmO0ŰqN .;/kc3u΋C`]0D0o&I}QQz Z ð~ZsL<XBnQ s_f~@Fٸ"G~'O7=f/Y1x'>OnG_Tn9Ѩ!#0ZlXqTlǸJYWee1?XO2z.+x qúwF@.2m{SeG7bA~ᬐ:+TUPs }ś1(C\+Eo jbu1μ{аP9w''s\ٖa ΐCqݥ'3aPDM@a Cn}XxZix!EM7q 16Ntĕ-͗.źfYvAAs#^N2coGJ bۜLQb?' @c0o*,JHОBu1gs#|(|1Y6a6Aθ2IJAQyXꜾUV .k :iqh^FD&o60ӊ :C^W3`L 0/%`xw<=J? &`KUy /ojUz53e'=yJ2ϟΑ 0&|uS$ۺi3OAM#8}sZKvM;W4Lfaaۦ ^6/ $Uz5'1!%(6I\Vz WA7"$7Ҷ`MxqDĘJQ"b@>ɬڨ8H\lo, ='?' HO~%RVWf9zo4![*6 Xg2Se61uF X<+}3g╹cs=} ڳO"o'Tޙ*6Uqq3N)gdnq0B*;jꞹD[AqjM۞'Ż "܃{ϳh23Q|f3)Yy.Wj]}uʭu;%Ab[I?Mv8#|x0_̹ & 2Sg H$*AQKދv1KXkîÕ(XT5E$bCuj2Gfcve538$ Gf.9N+F1V0!{֍;5Pu݇SRμ{.ZP9w'0:7< ~ y/zFۿ霎L댗3MRxfŁ Rȕ71!Y&ʛz%WU5ݨr5}? DÃVNԻnO6 1 t-hn,Ofqp&){ 7CUw˨AZ^E T q-3 cRP8VIVy0:䞂!5E1S v1 ³#1/&ZϪթ sMn̴VL9, qØ`L x$8Rΐ 0&|$3I:^3Vռ 'oa[R?Vm@^Z& +XJu8RU6Z!2Ј"뫟9>ռ'cVY7_gûB|a8UUl>ռ'CVy7of  :4\j*VI>ռ'CVYXI N(+C$Z5P XVSj<3qY}_⌭XQh֩Ro@w癋DjԎ@HolPIvr$*\%5o "\mVb(B*ɘ+t,K.ʐz)RK˄(RY/5PRe_A>*>-",³9.x=\R/?M li8mݧ>1׍K5PuRM&\o)1y$Xg98 Χ)7 'R T%ڜWVVj_ h3LlsÆ 0&pIUÁL 0&`dUx'UxUNce3Sfyѓ)$`L h<ᑈk-}in^7aSQԣOp^[BfmI_x`8f+f>p_ 31ux7?WjdZd+zҁʡL*<|Wlmm'JuB z!P˳hu0}^zsW_}yg5o!W/: /ƱD/ݑm-"-:s^?1RZڀ4>D@ Oc>||+ \gEJN!?3 żmL,ࣽxrH7Y4֬歆0 ɞf͓p-o`KI!<˼L=[oa .)v:^`Q:oXj@`>KU/,UszЪٸ'{|LaO H$ȼ0> mObif[Fwܰ˰”/_q+4@[y݈ġKlzWDk0Ҝ00?4ei 4zRxFt*ҾcTKv(:Te!ΰPBd~}-ED.Ř9`5oX5c/GωEWW=%%< >)/y EGzM7q\~6uƅ}3XM}]OUL3[ /fht Glꏀw SRmE+Orf5o8!}Lu'IOl"SrQשN_& 2qAb֔e곡.8L.ռy۞Rσ+ 05sfL 0"*4`CUy /ojUz53e'=yJ2ϟΑ 0&|uγ(7NS`(bbZa4h~fBIL0/aȝxlxG;(G0:iB5mV>_ {tϵ*7fj `'ѼML6Êc(6خhB8#0g71e20wn4I20ܯy^'¼ [jbSO*7fL*<#1gqaq3-waHBpG+pwf|bك@Yb^V?v8&3~ r'b}|>{K0hm a. Qw/ì]wTSqA*7f1= AJ$} Đ -&-y8UhZa@@8DQO(&qNkeFEZ@aHTb"6#`wYt 8k*D[UXa 0w'&j4YCI>eAMp~\}ܘkp“&c?{l~'K5p_y[('TLe㎀SUn:Sv˱7 퍴V9TD |MA3Q%d B[$bCRyy0? +*7fGOGvpN|$ bGq66Pp D9~!CZռ0 s\J3uEuEɉs;d]-dr|bE\gmpWMk~Jje2B}V]<$n׍*7f{5Dk1oޭ O**5 R7paBaLR jTL2cO&`i2ӿi'pʍֈ%Gy9Oo)7 0&J2l`LJ2/?מTMm1Sϣf<'SVI92&.vƾL[ SiΟP1&@-Xg1{}P 9.\\9 `L 0jۓ8-!᝷¼)CEO"9϶͙31&Kϳkcx~As HL߮ȌՈ(GfL 0'`y1`Ui,`  | 2&@ HiHLJBQ „ <%r&`N@ ʔgmF Yg]^h=(u>&`5$ e Q ŶB~< {YvqΜ 0&1 yћ>7hYL 0&jOܯ h"sh1DZv 퉿vM&`LF@ g"GW."20F]L 0&9Yuv77+2#s&`~M@ BTQ|C3^=-5"n<`L 0{Rx*rm윈V%'X04%'S`L 0?'`b$6CnA3&³"~<됨HF ^-L 0&,ö8t0OSsr d(&`L)<e:(jK ==]Lm9JLQ3?G#*u3<7jV]j&uA|X  HI\`.֎T9rN֠'vx7:ŋq9.1bL 0&POZlM6yLFJz:Q-`L .t/tm K͛b>] 2&cGEpXDXR+7`u6,$`ԃg3`L +a&6kEH}ѯbnyfCʈ`L@@sAN%;saK9}POgখ&؁y0&((*@ A`b< lݺ#yz\%Gjř0"'`RЬ^Gn_ )C^k׮{qzNtQMCzn:N:!::Z~g ʐ{*Vp4M4-ʟb<83dOwI<3ٲP8FN1by6LPѪU+)@6m*Ii_-[G ;vEسg'%JBܹ eϐz!dggO?F*󪫮gQYY)˵ 7ƍ}ĉRػw/~T,!kz~;nV aoɞl@@4M$''K!Ks$H;tU Lg I%bV% w,u7owaGzQ$DH!!F7?P(7l؀~ CŒʴidzi-[;V M|*,y<˗_~@D=T*ޯ+ICdZSCojrh:77QQQRܹ˗/;@||<^~eWPFm N2@)SԴz 4jUTQkJ#vhaYxȣsC= >JâyyyXjO9Hؐ$C3++K Z'a]Y e |rHX N!z}nYœpg''ťi2IIIҦ4L=j(y~z%45&L b 3^%(>lmmoh*-aVZ 0b޽U4i\'5_"{111rpŊصkG=Y*&J2]jU"9HLL i24JKN{n, /j߾=yaL@02&o~W-gΜi|w4רEþ}gϞ $?+o0z)gġ2-dRIJJJ"#Fs_6/b)4r?4o\Lo TKxV^ 9δ*s$4I~Gx6zldڴi#6" Ґ0 R{/h.tGqizݻw�%ެ]3f@llϚ5K$7S3gn%>?>fDJ2j$rsQ$OJ@IDATn 8̟. _m+-!HK#RoVо[iТlbV*CBz}*B lЧڞ R:BvehnVj߇~JԜ'($*<(Oʥ].FdS7G=_6LTQIF*S~{Ӎ'Q~p!p{},%JJX9Jg`_y1Ҷ_k&N@$i/hV^yRA!qwyGnoȕ ̓aZ5L=Ϛr믿.yfKVCe˖ɞ1-b&lڗvguf(ɿU9(&!LHG}k߃:/m۶$Ċ\rJX+)_4dLbU#zvyHs=g+{eY_x&5]I _JapԩSMb__Om׿eˣְ0TkV)kj(=mu_TU|8>OצM\:դj-I #ŝ~.p4O>;q&.Pz5!q}$m`L 0j`dđ`L J2 v1&hPƢt$Z"Ud)ɩ*,A`(ğ1e. 0&d'ks >EW°ͼ!\3&` EJp FC K/ev{*Pr`L x-csѻ4l{`DPU%]Z`Ip׶+`LTUIfBɩ"ni zբ,`L 4>NU&oKhsRlφ 0&.Gqdf}Ec8Qi`L +cu(󑞛-e*Gd^ZILv< 0&B'>'o|&` ._#~TQT,fL 0&`7o@YFBXko 3?{aL 0&')Zc@g!en&`ZNWj# 0&`d6bL 0'*|s`LX%rL 0&EJ2CA.JBTd:Uh`2HL 0&|d@2=Nȅq$;!*ytAAABZm|Ƥc؝8&S!lielc.& ڭ(,, oZndp 7܀~XZnfHXRʘ#1& !1Er')WMF|nK4>*:v(7H믿ZuViz _-* ‰'b*K9?ꫯbXt)>bVuY曥pusU7#a覶0&pO1U̝VjDM0z{D{a_M9@.p4Z`DF!Mr-}roR21_+V/ʥiNNi8wڴi3ϔi(޼yGߋ lwy5Aѓ2h]n>mV@{R[yui9Lz?8{jGEpXDX?Z!@@pp}*++k׮*wIIIҋ%CñZyaKRÔ)SnGϙ qvyM71FX˪zkojroh/7k0zvb76L@cWg+!]==߷M6l[8TIFaƢCXt[jɤ-z\s5r.L8Md2M?% js(HRhj"&j{lTsRo̞W8Ր%iV I< R+!v0#Pe06 y=: lreL w^l" R$ifv*;U=^|*=NFPxh…r6$zaEUﭢB@9Eճ I:kvHȚ$u![%Z}tB2ᫎӳlRCWLwt* tWF+ D1-_!!WPܥ(@DŽ]esT R#(Z x*!hR[XT"n~ XWTX_ ztIkèA߀FDDhSSa[ڹDZԜM򯦭s/QM@qau!3&(BIÕʘ% *Ut2Zm!K5UFqxJ*H81 PajZ2q̑dGOj.Q^t8/[G~$HUoyXWKL,ݥx1@{- \2Pzzk-tu.ZH*.((w$0i?r,m|y]v"DÞu Ye_MD;U&KpRʠ jtCNֿPUYædb,6[t3TH *;aHyԐU鸑feI}xq]a6vC{Ul3&YUUg[5UTFÖ(:$gg Kns̑yRϓ-С/v >\KޚQza[ պ,tj)\ǹ Rd$4將հc^M˕E{ RJ)AXK̂t_qf(/l"c*fMSd7KDf@Ρ$䊩3W!7I aA&-9+$m+k֬hȖz>#LX˧9?.{{ձT)Vn:%CQ2a vS=k;Om%>g/jk.Uʭ]uS89o Mʔ&u W'f_iS}?/ꫯ0f̘.WzCnF/ z,tZKCYuXwCVC4])CRoT :Zd}Һ)WS<[+lnB(i,j }Ie4k P“VL^z饠}oJxR=hGKWi֥7,H#DE*yX"Њ: Ztu֗Хr ?6L4Zd z/i )?~dw*; 7T&F=X\-I~=GGcsEj~t#pd&[vdЪb]i 8{Viݔsm.U=\n%R53`,'*hS ĪU0by;mG*2]U.}y8bya]Uu). Ro~(j֭Y[VjOBW}qDF\l{$w$ >eԖumQmOW׌:=mO?ocǎqҮAdhW rrwI7.ݜ,,OYi;֭"#%lɦX֍7 [PBvq$U] IWWۡJ|MYL bmPT B-NJmն ta(ZH{ncgtg!Vo$Z@Eyd7$۷oObwLhG؇"NI\>mΖպjXw>{AZ (oV- G Sj.i{Z7՗Хg%'VMشm Y%} 7$<3׃W۾>J?ᢿXF}w%6;JlȐ!R(zMO[!bn~ V-0M֯_~IC{~GQ:=F!wI7a s 4ֽqj Rꉚ{V& ,DwBMkӥ4J;ZAuS:е K2Z2Պ篑$3 \SPE]2g*zCCϗT踤>(^~el`~k'!8j(F\p8qO|åtu8E UúJf h}"2ϕa]b7^]*.h֭vt)^ؖQZQ(ZkҜkٮM'uBիMl{U pdӎ!ukD6 DYݘƸq伦j UkׯЩ{ƌ:u*41BrͥnO|^oTЂsQZ!d4,,;,OgdcaZO.' 2_>W s=݈)Mh]M^zUi`h„ UZ: ~G$dm/0DQB0HYVQ盄)m=;_B0z[\)^(V"^)=[G'vmp/5IJS K,er KUvYXv Zak+,Cc惪$k &c[bw"iVX+WJWVVU"kڕ߿? ?8h1v.ڙH7Gz&} :}8;R(]d[ PU"oodD4""YV D^1q--s&H{u fM@PEGIyBQ[ VZaeR K3?'J2^ Òb!,9 Ku@tUUuh?sQ#L#C ?w|QHoJWq$PqTp}vR_T)>^,숍cE7kY#]*pP ҿ͘oN }P5/TT6BRT{?䐮Z{qrV1]Ov, Z'^N-bBQd61 5@*$'_6ay )IHK?,<(GKm/8t/$zaYPt?-TZ| U5(DAI9@HIFr޽{.] Z - $.?S2̬vP]Pݰy5}ufMXaV ޕGQd79 H pp$KEDEEqQt=pտ* \WQDP@D 9 !$__ujJz&{ߤ7իLf(՟:}D#/HL'P6T6#$(7ZTkh[ U*NY#,sEptљa1l7 &BLliE,ɧ#"Q"}m|OjעGrr+Cbw毭)&3XuFO+3/֓/ū/ȐyGK^A*N 4) -'?C*UD [o-ZpZj%g<,f`5SI,5ꮢe%Ah{ҵGc:q3^{5ɳI&Yԓn -[Fݻw8GAx o۴đ;O)ofvA8)4߭~~-_7ܯrP38=?ϼ=jݟII:N8rm~ ;pJNӺ#W#HR|K@MٴJ[|(2(D6U)b'ҪF 7T+$̵ U+_M,sYV(2AUcLJ*w*ƲY)w4 Ж] ?#@C jl۩hUӋG;}ϟ?};H|/! c^&N藷ܚl#\7D=K<9(a #R #L#TECzH-r,%.['HtѰjђHҏ`}u:2fBwԴXZ4A1% R= #'LDiFR8+Ha_ ?iIR( %Dbd ٰe9e'tqPXe/hBGdӠQxItGAX/"u6%lR~Bqq VxۺtZ  #kؙ{3m>FRMu!աR]igf9/Kl@BAymW L~\5kv]IhXE͛fY(FHEվBǷIcڢess w$)8ɩ6hA@*Ituh9BԎ͎vJLjԯPYj =a5ғ5Y쇨#UeDX{Ծ㸕ͪ-Օ\m^W!:te7tGSD MnۛجksMY;EP1E sH, ltE(@s샀"smgԺnZ#3C,Qxx#QsNC Y)" ~o2т8ˎ^k}GRFFPtt46S5kH_&FĠ;뮣x@57-DEEiBÄ09=14ۚJ3ӯ] 0U өOԋs4sUt⣴QeemT!d,JhJkX9wanĚ TjJL u[kAI0ukbR,,apzX71IIv2mtOЈx )$_e68 AWsW_SO=%:S~~<yh4}tAqT^O\X35qzѪ_ʁ,_;y@>)mT)kހs%RJD-yՆ"~ Zsc.&B["U0bӗ߿'sUeF8$ރh]G}Ǿ~ݠjy$P8y'G@A뒒,Xm:nC)u7bj"R_uM@ ~ϩiӦҊAKV*_dzGe7;4/"I>ݑ؋cSd&z@btHKɈQ NOWcMjJJI8_+bl[Mdg}myXc.VijL\zF%%Y0Ϩui({hr{ Qȑ#iYH!Ch۶mԹsgZz5 :ԧQhrE~i/(i޼9]Ryq34_v zeVDH#.6Z"5^ٓz4{yWc?V+ m=\P>"jˋ\LQS(E$9azM{Z!'"䦮ܾ}{k kAB3f111t {U$k䍰@۩IF"`5efӻv0z[HzwHTgr`#w׎nDmăx -5ܱ7H[US1g6D&RO:uт8A8a@;D28 g+k2ϗ>M`NuJan/a ٬ԿxDԁF5T ZӠx R:"}#bdLGRMA ܵ>͏CRSkox0a͛GpU^~e{w;<)--3gu(C,ix;^F@/}p'kF`1XizBu BccB[nNK;nLiFI-ӧz~8%K|O$/߰.UY9vdÆ M܃eV̷0" NcF>5FXb4=]Ban/֠F4(븺0r󺦑S t>5m]LY!Ǎ7Y/hUD7vZP#TJ )>.fdѡrϗ &yb$k׮)SHs~dyOJ>X/Թ±._GЈtQ/"Xڱ#խ޳Q4$ڿ5Vߜ&(deG)gwE7#TPa5p@駟d vIWD-m c1B]$;SH8dQ`ܨߍ&NpC}pklM8x:.RIebί44DZm©sϕ>s%tkSQjs|@17#H9h8rzB#R+Vy⋁LDf[9+^& 2[d 7hHm'j@arj鴾HA@3h5B9ψiJcL,)D L&Xp>t\y%&L+MjM~r`CQ6" So^Ս0TϜ@g(h Lǫ~iwo{یD {-u (jREW_}.RxB3ŜUk}2jL$(Czԧ&3Cy%֖$$w,~D & ɺYr*u(FDLRw?ωI4wc*$%QqO45J8F?=,!!\@ :t DBPg}VG=+drJZt#kJPhez#Mw*2WuVizDCs۝6guU͍vHKMKJځJp̸P h]H|뒒 'UP#MXN_Z1_z B:KG@ͿoN&ڿ/hCYF  sΑ>"@WFJ !|ԾeaVTJ*B4jHgwΙYNn Ncu+"]*KG|7锧~TJU w{$I%t\LyF젴dtYY.RVy"&$@DM2o}[,{hteUY@-[Ƞ y$@j"WUx  ոugF[ !iSͰㅃ6M62uhS|ʰm QosHOWE\U\U8~n ٔks3?C>Ձ,{9JNNxVZEwOQMI_вe$^7ݻ髯De>qzz#WH96tl_/Ewsw]6P{@7\nSjf2XF<ǜ8]+ܵOTRJ~T5'd,jsv^U?B${ˢ"?!򥧧TpZYf_9X0x`3gq,ս|'$qbYfR9YY|fAiy۶l+5Cihȑ`  8tY~C PZ*ʓiګ"WUx/\S_jFQNFKfZ*P9'a*o0 -Gh{';k`2|M"LScmtE;QZ_ AEFF}F,YB%뮻zI>ׄe6,GqƗΕ`5rE;mԵWTDH R]6HuAHπnzrj\PaӃ҉EI$Q+"6>g@Gڹ=7J+ >jȑ#pBk 8p]U gLaٟqoU~z4%YE4ß}4ƕ'⯹ne^P7X%i6gXMY.28p`MsZU\1]]OU=Oxvj4l|X[p @NTgR'v"-BS5o:?XkYV~sf wg.7f}4xDھ.hH$;/vp Uhg}\ӦMLYY$M$en },[ܦAJE1~a $%3O߼ӗkvs2GCE1^Fb* ohXz(CuikyiƋѣtlB=+RU%ZzaזiHFaHb3B5:"u Ib~O (pؗ޹q.9u.}>:\pR`6>ua Ff;3)~muxZKFjVuKz |;ahт`4\IDATT m9Ba~m ܹ}Qks\ Vo{V*aH:_8h"Ahx"-L5GXB GKoKX&,1jTUU@"1W6ouO1X+V ^CM{Ÿ/m8i5([slCw>1 ई5XMJLgX!QcǎR0yw4bgBtuLsHb+X)Qs;ҤUmUԸ_m ؚip[9c3 v"l(BrfcI\?$w-:`(e$faԹ\x TJB!V*1B3Փ\CͱH}eV%o7\ bۊ}:Q+9R,b.yEZ ԁ@#`_~eJ_"?Ublzržie9Lh- ` 4k{V_߅7 ae~ khݦmC c>``&L@Gjuܽ{ /WZd ;\|N1/ Td>\SSO;-F`jx"SL%+/DvFO97t~G+4J{\e;_m}1@=DK.yoMgϦFj+b=o"v̢=Qr|#,GlT0`I[ТZLFc $ #`5E*s% #*/)"6Bӄ*W*>F2O, zL#0@@6乽w %"^n'8w}*?QIQ"DNOIo96UDs|'#3DUDi{Ŵh"'1#RoNsnC2Tik߉Rqm[[B$jS`mFY~w:3~ Ef[R(juoG^AU9?bC)IH0#P@+V 1c>mmQ,_s~ԣi)>!ͻ/zq͡ Tp,#0ux'''#<"oe턐d)5ϾE#Q E2ܗ7n0#P'֭ "Q^^N2!{&ՙ$\,A4*СS-F`BVZ<@w۷.5"JB0#P=z45JŻaÆvO,`rnj#>eN)B2#,ľ#0@ 6% (?VH;)_M`aF` Ӕd˫" 5E-y.F`F@"`(YWs}4iH+4jeF`F@ 6H};$P\ #j8_F`FDS|'AQҪ0R#0#C%%o2#0 .)LPyu_L>]E^\XZ***?dcd=wJ۷_СCSOт (// D&Lq6< ͚5Kn_uUtɓ#iJ2*ʡ4 FBn*]ڡCzשw޴~z{'O?D&MZx1?;=zr7ڵKo׮]-%w'R' |׌@ 0uT:qP-䰮zI>̙CEoAwql6lЦ^rj_JN [q0uNIVg:x}F ??.\Hwu8qM6o{9zI&hܹRKӧEDDз~[{c$6t|"#`:tӀBo-BHDcǎkt0+p*((`,DKJ XҳgOӞUoYj9￟,0#y$܆UTdY9$E6)2s#` 4m4F%%%TE/)..O?]Cی ?\C m`E bՒ%GSo.B:?Fk_x.~q -r>|6j?:0𒓓wq HA#Gp&ߩq4o<{?;v$8A=*KES#`) z6-^}5f^Y\$mYj|E`"M>,>|_%8: t^iQ>C4{lڱc4bg^\,..N^矧+Wz>7`$$[dٹS I*-%x2PVX!G[l!8]vek͘1RSSe`kftRG \{1t~2o0@0IIVI'Kdg rK ӟz_GE[F#FȨA:C<\|tKP(lvk;A!LڶlْV^-͸XYFfDN:qz{|_:o"k5=r*l~.q*wi'&0ABM Ou,#PsRoNΌ AU4s Ag A #0@x#g\Z0gXI&B"JOCWkx?.|#0@%%YF$WV~G)"0y*,dFk\R-nIEΆFX9#0#Pp̮`F`FmJ2,AqA*q1#0V d㌏w׷?>M480#0@S Ty~QGEEED׋; M0cΘ2#`mN:5MID~:X@,QqT̷Vy2k{eիW`3);cLS۷[֩iJ2{D*zb l/@a6TZ'N;@^DGG3ՇLU25d4MIE졹8T&P|EE$d$N1eF`7dRᆏYiCH^[BU8@i2q`F=E*s% l)ٴ/=1uuYiN@zSo1#0dY+icT_Nk{~ZTR;dF`"dΌ|BJFͩELsjXM6Ȓ<c&7`F \Rup=bN(B$>T(w@lX 70#A$%Yޕgo^R##d h{5o0#0a@TZZ浔dhvTJOTg/;F`F ,0MIGd^کmF`F ࠩa3#^4yg( F`F!`+((<9%hl-g}@JH_`̈́o / ߄$@$@$@$@$@@FFF#ә.ҹV]Rzz0w<ؚ#kR&E2vʵIVx>[y:t(^/|>? 4i=w~wM$@$@$@$@@ oSfH~__7vn"-N'غlW|qq1vڅm۲VZchݺ55qjͪ _ʶĺclچ3< %%%(7iMa~WuT:r͘7odԨQҥKuSHHHHH#t-@٤ ~2AvмC4` c+hIW֭[qiړh*m#b+S˭tR.e%$$eЦM/_mV]&Xmeq8QVVfmB{TPBkf͚eMoF|wf"(E     @sӷN&_-ޗ zVc,]~p+"|y($jklEsh!<Fɧn2I$2~衇0sIꈴHYնlpOe_KUզIDr!w؉͛QTTdWť܂U?[+SRxn37]_7pQ2Apm.$@$@$@$@$@?kdR-dJ,M6/+hOL~"hJLFSb #||z[wZ[LuspB,[>}ӢHN:vhU^ulމ]BW&Ȓ vٛRٓobo@t۬*cAgw^æM(3W?KJg?{u @] ki6LħMwc-leru`X+&qH^&q'O%W}ڱzU:ǚKa^m۶K$\ʲʯeF{yu&Mp1`6l'Uo>c;k2]n1۹3ǿ6!WwAz[̟?;w6˻Ǟ={0vX]Y^/6OMŹ`HHHHH&Wӌ#M&WSVtgz\\m>xz@;7mOE?OBmgٿk|[K%$T3GS=?ǎF+o߮Y|8餓pW?h^$#[G"P)eUn-M=z&;wZŢaJRHB*0-ЬYzѱ`?O?q[zh ^yL3hZ~%9U     @@H˺g/}˼uk8PîV݌֚弒} 7.o,o<+qIpBh+O97]j,;^yj3[5mԒw&ѯmyjwrr2>lkܻwoʷ~Yf_ʋ~Umk̢_.<۰k2auq6sw-/^lȠ:uڲeUީSGc[MɎy     \ݲiyULe6ң3mg`)}|SIOa_Vbv'94/^w O}{㶕+,\2I$7IR\&֑:y*N05L$rN:(t ;bYѯmX&̿/p '{h׮аKZvy?NII1WͲny,6Ohÿzw̹d,I<+{Yz?eJ &@t:2 +Ҳ[&zEZ^$[2R'ͷ{U7| '~qj[$ $ =[C7W>u"-1gqdl{uthR$We+WrUZ\G2i^VLH$ٗrHKihRrܙm]E[ꝛ%zz˖.џ4i=\O6D}?$n;7iD$@$@$@$@$PY':\W_Lggn폦)WN߈m7gBDiyxfi:,}Ԓdr'I'֎eUR˖-ڢj~]jMuS1yb>[~~UmhK|,{k/U-ڴiysd+9H3||qWolP֏MVyFHeY, tYgo~roJD$@$@$@$@$P' 'Ήt`&~kT[3q"ɧdSϳ]./؍EfYotkICؗLDe)Ocңs*ehg'zmkNh$nܺ5k۲]3uV|gV¼E ^rgμum9տ`3s+e*$@$@$@$@$@@ҋ/h1aޞEe;WX9umYuCC~;c>O?q p p p p p c WSRRb*(SHHHHHH20&b.#l{̖痲/I;v0HHHHHHH>cK缌^WqqULy֫=$Ҽ}0r-}bرc%0;HRuEJrVΧ`YhUl֯X?Tb۾={6nKQޓ3% q;/HڟX7w\=ʟ:rӟ7i1ղhmkREJj=N-~En> r|ϯ'RRCwc?UGuo$)ݗTǺ#xLa>&HLtS$I򋰍}rD8۾NS*6xSV-`ہ2%62|:j{e;p߇jSEOO/DOpIK*?+9Ҽ۾AtJ)PVhԍ;cƭY֕Z\ SFp.@ָU:T1TMFn;Nj,1R>GJi̻Oܺu"UI5{?RR̻I&9}-QekZ6~<(iCW-Rc9x=Ƣ72I131R~  2?7gJqqSYYUξlB-+'U:bM­Ik>ă3?K? ݟNjn,eՉ_sm_L2Fg=r1*ipK1$B&*#צ:RV g^+Kڷ;~mT~>gs~(6U夲*UGl' 9l1|} 46l.ʴHg*Y'!&WNGɠK_*';UG6~WGw,>x`3^~z&v6:{Zr.в;ilu׫W}w,ǿs &7^CS]:Sj*ΙwFL;'5p)IA6I*=hԨZ@RRl XSeV&̇8' ּs0:UWV3оSxW-Úǣ_#i֕d'y0TޟKRiOI%:^n㳢zMIݟ=`{k(멭ЧKcϮo,^I,.,~K)?r<Jw|߽ ҮζMLj (5Eۊm?aE/׸UjH2׼[JNF@n" =/lgjxttme5n\ˤ:ϭkۓ}+{*pm=gEucaB.+KȔ .>!ퟻ?wL5=~nw_ 2~x4n>QrRK]:Wv-Uߎ3t뭀59{^԰$7GR=JZ&nlI$~mkɘ}דJϜ%^Vw3<rSy.%v9zW?VۧSiǿv_P,v5뾞"z:t0[6bpY2պq!,gNv{M3[ilRebTZou8|(ɺqt1LU{$` xF6< T5ji9ր;u['ZɻSjaʺpt+o5kajTɇį~e0۞}o})t8 .G k/R&)Oѓ;'ߗV p_0$%jOjywv_.ANޚi V^=v(--Նm=Ƨǰ;);jOFm }^seʻۋ>d,EVȏW_cT;UFmw-ݶKcM1~a}Q2j5?[ܜW,f$k?ٿ篖_v/1YL\$b.&wwoܙ羲zcԶ}U]:Qe*c]{0_ۊT{5c`KQyL|}0cQ)SwwܙWHI1=b_߯FQ>>`Ld\{%v>@*^NV2lEJҼ=C.ڛmŸ$ɾOqhzvq0V;8KZ/en0jJrk>[?Ŗ{E*wqWb?cV< ZfQZ7h?^\Kߟk8˾*R9ZfUejKꩴOzRK.]P:~g9waOzu{hu?0.q~@џ_{_&UUe_$;u--#1V:gT߀Mw k_k[j{VvTZ6G%I~-Ob˙_bpi̩4FC3VG;C983~k|~Y#sZxqQ GnM'K| wNeɺ2mMta 0LU@Y˺tVL$3k_zozб[w$x{RR:[zwusnen/"IgpsG濴O^8}M8GڏY:UxDtKtK*ۄLڅKݻec¥8p47|ԯvTJ{gmOT\p•}}E%gYK,ل%8]Q۫-zw'gR'mLz W=n}-W鮏r-hA0fgVdɾw5<1jJgůTkJw$_b3ܓ+7WUKcTO.LtҒ Wf)~4s*b jkJ70N]evT:uڊ}Q;*"oVآ۩y+a]u H[^ex_RԲ^/UGzA1?/įW*etK2r~-5ƯX>m:Zm:iםw~U\>\ǁc.-/_ofN'cɾrJjqrv.}#/ܶ"_$")##ZXrw^r~:?~^]\~xWn.t2>:v~N*[ن(ɡ)i!ͪZvμs䧯5ذy_OI|Ie?\5GX|6S&qS_~<s,Xp")E8AgBdž*y=*3b1K۾JG}["\Z-6Ûx'c֫!ۊ5a JKZ[&hi@-׭]V#ViW ;'vꩴq}u%Bl5L+R_J4n;G*wDqW)|H*օx\:8dLeɕu*-j[}Ǽ{0FƭRQRa5FJzܐƭ g>E3w{_uUJ3?}5ּmX _5V֙W[ʴ:RJi̇تF>_#n4.?/zZAU#q//߅ྒྷV%ƴwqXUFAcU)j|Hj#V lHrMR{jT۷k׮E6mnL[!s.I0kk>5/P8ss`\lU[5e=лC7tWz|unֿo5 k/Pݓ`\rE>?icn+:nխwڗZ]{?)Þ&ix{R>mU,ni')GgupiZ?GS+6~)ɭ_2j4<[p+-opW[aG~,=KM]hjee_Jޭ^l8S4}w}%P&Ѩx(3QڻkU4}wWY}X|*45)}ƭSUW|Trj_$~Ӗcc+Sw%w׻ۻSٕ&o#'3;X;}Ց:͋Tڳil^3\Ɨފ7߁[b^}H y-Ӷ"%il%wlݝ=JkhҼ9R򳑵j'ŎڈdOV}.6ZyA%NmZ:RyՏV/m_5FL|z~䙧N'5BӦMѨ0[ m+![%95񋽃_n;m[s.kmVUqnюoz}iʤNK콊ZRjzlEjo[㋔įD2}+h&oxr<Եn#&_SGKҶ^}SmEJrǣ6u\mۨ-[k]$)mN{n6ڏ;JqΙsAmmWe_V5>wI^R:ge:˃>85sp?w|Reҋ}GMR߃Oq+zUwWl|p9TOtiYyNmL_/nNs>29&[SGYTm5ݟ_iJwpZ]_{v[|y.PRcBlk^㒿%Lv?ϊ:ͫQ,bc+w҇3:RuI(@cNI˰uHζW)j|+~K꩔zgr:;4  vo3|M]͋~￞w*cy.yM濑BMsViS@߾}+e h׭wh% D$n_]JaMޡ,Rؓ[+9s7}0Ŋ+0`XCLc? ȔLcO 9N4boLcO 9N4bo\Md:Lc-- @&`^){3w`ݺ#iF-׾Vsw>/̳:}x=i^vG0}h$Lt ne&?"mU1Jbj^'=1^Tgn0q){ע>X @;nzmǹi>4m&{WuJ#Kv'-ZYmkcK3]Eۀ9X;x}Jsj|Õm[%xd_y G˷_ǜwbd/? ߮Ɂwzc|+Eazpv慸sW8Q?Nmg&景%[zf,[0z3jݍo Gq0wB:yx{?8laQ(Ԧ^:W_09vH$@$@$@$@$$v2صzdd{D`(1BT5e$^u<ƒ\ӏ72Y_[tH; /5&퍴?γ'yKƝpNA30+L׾_i^87, _2-0dxX2I5gO` 0'wvY4\ }n,393O+cX65WL;O/>s? &mW}LS./L܂+6t 4a?ͻJU3nS^8kڐ,K?ɼx,94iJNx$}t;:5ǘ2_MkS\u2<ۋ0QfrO!~ˆ߳I 1e(O g&"t^&ީ =/n_{܊IX{{njjw(ÿhw#aǡ}eӂxጣp1#ix OaLۡj&m[KZUd^|,tlޜ@nNj_\v. 3pGI^/B"|v<d^FeH$f|=HLWX>O.u>x:'՛/317ƹ;Vgؗ:40QK9,\sLHKj0KW5TGW6? ׌x[}V2HHHHH J&ӵb 7z“hYlT]L^uVHw\?w>q6LRRU{w`)$ ^ZkbOa!JKKQRǴϓCZEF#1>xo=4x,^>b 6lÜr/bEؐ|0HDY,,o+^Vn0-‹OK, Ju T@t^b< {#o/FyJtջL zR6o,ƺ2/>zʺZ.ŽyFV J|Gk?kkfo.}~9e,ٓX6i2Ю>g|؅{PRP3.|h]QKcOVB#Wn5bx…suiZZ[NM)ލ&~nۍ`WǗXXGnx$]#hN9`z{HQ 4 TWi c2Q'S2=[8%ES2=[8x<f+fZy~)R^S)m.{hrIHOẁkгLi0 2pN:2U:$@$@$@$@$]d@$@$@$@$@$@$@$CiӦ,!C @8p`Ֆy3V3gNoxbi ")ƞ@-ri ")ƞ@-rIIHHHHHH{ta6]-/_;P؀ԙ2)^)ڻYxg{xl$ڴՁfi1xots7/^Z5}+^J.2 nje$@$@$@$@G iIk7-M~<~?WȨ|ň Faa :7:V5Wο a- Ǐü_;vϙ^6a{9qRs xø/Cː}J+|HN_yd(iE\#   _!WMz?3fOh{>*_JyFgSx\azJk;R:h35yN; t?O_<CeZ堫70~.xc+t^.>m9]UEUd]    8&2\^uaú(,kӍ5qcSҐbuSE7^WmVv@zb k,r qU>Y5LE4do߼ N< ?EL#0c1 @<LJqо[ૹ5G<8x8soPm݀yNMk,|pXjT;' 48֓ ɴ?_>Z/7L[+kFgpVZoChŻcZ@NS|>~&w&^kZitt    a'ӹ_ƳGk+-9|t,B^R[Ł&H",,[g'<#B c8a&Do2B$@$@$@$@D d2پ-β4۲3&,?CkyzcoN-k~RۀOfRSNcqdͭ6E{x#{YbˏZd?#$   2c>\0A8y.P0K+w;.r7f 6R:f腮 /"~, Hs gƼ=N_' *HHHH@/f?_XB؄ސrĀ@ q b,    O c]A|` @һv1O3U@.iD4    !LM HHHHHHjH3mڴZ{Ր!Cj '0pWy-~ͼy~)R^4f#c̙p[\bisdJ'{d{qJ'{d{X[4)777" 4`a.ۆ+Ŋem(4`u$/^IJEJj1Jf0жwwe(}uOi/t+oB8GS \;xro{ 37`d;H?/ZWl\|z/ڞs_؇g;eLrH0h    0Lqڴ1i |7a־.40Xth&ͲuE#qjJr|XX y@ęx(u3nW#o?SW^)ܙl~=HryM$@$@$@$@K 2RfoúuϰD& #O&7=O¥APW>،yϝ I(2ǭW gl,g1'P tEgːϯJᙱHHHH . Lek)Soˋ=8/Ky\9AoĀvJO>}׮1c#aiPHsۺH[Ǜs)dȈT4~<:teFr    8$v2/܃ۯ#_?>Sjw|>5K}!L>LfL lj]f7z๻1y(83F37 jJ JB}yx0vjtI$@$@$@$@@ɴ@1hw;p)vZObmƹM|we[q1>~(r>qƞ M $3j ȦY&ha?gD:NI#8 HHHH @ d2)˶%@IDATú?`cN.r6wWd[ʩ-XgFYJk%f߫e{jPsF3#9L@ qmcD]SNc2fR?+mL#bc @y:mO GPD\h<c jP_lZf腮m;^Due3{OZNn,\nA8"3 @8ٛ,iؿ?f49)KMY_8 9JBMljV0%H=q )ѡCو -aܶ,4F7'72$@$@$@$@E d)+MyX\xEgI3۰LBz.^_H-M$@$@$@$@G d2m!𕡴3HHHHHH*<ӦM2*3dȐRHHHHHH~vh7[<})/N3fOsbo8-XLc|4@92%ES2=[8%ES2=[q{oiHHHHHH0L.;/:f4 2S+ սv;jxSGRqӔ0ya9agVx1{p>4ԧA<ïŝ;2 aHHHH T:޻xz6 <vwu\ 'v*(B wxh0<M/$]2?wϙ^6a{9qRpX&Dc{Tث\;M $&    "N=?&@F 4DdTcۖ~o WKpœ/rpY73yv5fs1uuh殟@A7~PGܛS~L`!   { $[|s.ŝʑ\p.T ^cp1ﹳ"o5]1 ⴝr,up*tzA𬚍=2B݊#EL3 @3â׽bRAijrKq6ӎK|UuFB^0gN }>yv &lCp"mY:/7ST٘m40{\sXMQQHHHH ~L?y<蔼/2rl5iQb`Qimo8vbe/:e~ÌcH-i‹Ⱥαl.姛6WWQO̒ 5tEMpp/7 >)bL *2yql;Ov蜞lW^љP:똋L u- _OṰHHHH DL{a WڠKě˓޵)v4v,iHHHHp>^@IHHHHHHL6W[=2L. Ĝ'fo|1,)R^4f#c̙p[\bisdJ'{d{qJ'{d{X[4)777" 4`a.ߛ;v`G`AS &Mnշ<rŔQGc^)xfiy<7Vn~^Y8 6sQ!S )OlZ.?܉co 0 {x-KQ=:譡(݆a G#1ˇ̻wϙ^6a{9qRV8%ce^Y    &v֬yS~(.-כO~yU? \sO! QSK'˞;.<} ]˺s7sd+k3E fkCc,+H$XL$@$@$@$.{`l/ODbb99k`ccrw[{HO,-o3(^N3UZtQïv@zb ?iQ    I d<^YZ>郮>ӷcXh4Ul>x8#m݀yNXMG i @%v2~]1c~fH)F/c҆KDlإ$';߱\f121:6$   hxNvfbݺu=FيE_W#9 /rm}凨 />/=.@{rrcd^g'<##j@LkMHHHH*02]{ Qs~Ŋ=U˛GW}]\nrC}S덽9YʲYǝ<8~:6K E1I(>GodZ}#   8܏2ݗ"gx>Ʒ z]Ga[!NI᧖WtทJ>rrf wWqGáy闻1kpKf腮 /"~Mf+#1LCHHHH > L7 Ofixots753[9i4f'   a@V}< @捰7cno5*?C%ދ܇#َbygYKܩ7]pvcewϙ^6a{9qRk'v*(ݯDhHHHH L Z/FrJ`ovJ!7sw?sy2Stmƽ?4xټ-230tQ.f&ݮFϑ1~.̅#549z2 `HHHH ,.ڌ,3)7?o=6d#Z-1 1(X5>l2+km8m'&PQ.^N3U\@r\k `3=w6PL#3c @LobA<)<[X0-T*;8,dȈT4~<:te̅ Dڊ8d8+;٘}ڱxϰH( & ȴ2p#   3!FU(ϰ0c <Ή340\E~om_<-:j"v7W*#1V mx-Fs?swcPpVƎu$@$@$@$@E d2ݲ.ݛcݺuxX?t+JSCmr0?gt𛓀 /4$3H=;1wE<-ϸ? ?wNب8cOId+HHHH@dkjl.*A{b؊3Z}pg76K'E1CPVL5"<8~z'|X)=#031sN6?2$@$@$@$@qH&umw~>f+q߉m+5FzOZN酮v~k.累S:jf7ە^DuBY@1Zw!-2$@$@$@$@qF d2'cb'5EؼuW90n[vy[C@}. -|;_$So&L:-k^~lo5` Rcs +vOe5h~RfQ{ 37`d;H?/ZWxiDe>|t$F^ 28IHHH3N݋өhQN}LhHkPvƍh?fT_J\rK!O_<Cnfjb묉w@x9;-/h;ˑ8B2 !    %`^$N_T4I,GAY"Ǡܭ| -t+i0w,τYef:8x: xVryS43=y0x.} ڋ6F`b    x$f2m>r>Yaғ@ƶ\pwml6=9,;k]}oǰh«.m݀yN`MGd1(uJOU422֐ iXf/ǵv[/׊;:8wo6RL<=|^Qd<вcZ@NS|>~&w&^kZitt    'ӛ?| kq7@~@a'Q-|Ջ{}f&7A:aIkN{vƒ!8PF#1lpyO=Fz    8"vږ{>6}vqy?a{FL<8},ERrs9ȵ5fY.?"HXN$@$@$@$<(/#y`w\OL jk=!JWvRW ? v^Z+N&f腮ttI^Du\BoÈ\h<5y{OHHHH bv̘qY/;k-oamYov{o{Ӽ:cM퉫?/m(Li҃uE `^pr"%#ڧ9NdIHHH⍀`X9tsu@Zt_$wbf&m:Kd +HHHH@{&zJ$@$@$@$@$@$@5 j/l.Iej֑ N4@&ky~)R^_ا>;폟B )PUAyXPSD ]XPX@) y@$@$@$@$@$@$;uiFsr)6ҵh1K&5ڼa: Ւ"ݫ :1 lWҽq2k><&     _0ayiwx<`*JtTY!V# ֙HHHHHJ_~hijh,s  :th|e:4R"8o:Hn VHHHHHH>uL& !/I)mxiThG֦!      #PG-)˜TbI=+W3 @0LTȯ&ICk|Ba(Y$@$@$@$@$@$@$U,T}6uMdxM&4       LWEv-:ӕ" R* } @e:P?&a--N@$@$@$@$@$@$@$p@eZ*!%''38A ##C` " s Sk" s5wSSSF *=V@Gާev?lўxn/}z%ofJ$@$@hѢlܸmmmے 60Yerr/>Y+R]ny:TĈu%       JM)]$+kKf-!}9yO^rCig쨰ȇ$@$@$@$@$@$@$4wuAJTXֻPs͚GJv)XQRa12HHHHHHHaP#ӵUҤBեFhuT!ZMԍ^ IHHHHHH0S4.IS wuDanR7>ϐ @0UK%''[JQ|ɗrrIj;VgKk;muN@$@$@$@$@$@$@H@)k!,f#_Kr:qެD6{Sw:k\ $@$@$@$@$@$@$VM9Qu @Adi*#^}OFKiXciQ!ңqK$@$@$@$@$@$@AG@)ei$NC-/vb4 z@P#RNE =zT:$1zG$@$@$P4իW7 r$,;C}d r9СC{ƍ[\={dܹj*ٲe*&<<\L"׿r5kLKWղtRꪫ$""+e0S[(Ҷm۠++iӦ?.:IIII#Rl ը.yҥK_ȱvZy?$8쭷ޒI&Iqq1i1H,xe K j#bWۥ x6z) 1c$,L0KH邇wo. >}ȷ~+M65pʙg)W_}bŰ   p?T|oDUwۿ.gZdHJJؚYU#SK;>a,+"7o\;h"1h.a cJnn_-嚟Xx+zQF{ァmݴi9ReĈ|ri몼O?;*y曦S2d֚1Sy|mX?j>\sۭ֬qH hJ*k;:mnj5wMZZR<FQy6OOOWyhBL紆\]uN6]3y%k/ *w޽sW3-WyjsMp_UȆUSnj~I}GSmETTTq\hk5dJ(ZGu ۂXXuנ Cמ^p5h)~}g3em9mVsWO?i:δ2XsuיwZ*k\pמO7rS\}.>O7퓨}bOSHiC4oݥ̕]vALS0wZWiO6i^V;[&:C֭4/δ;3@},y!`̆&NLK znACor8qZOs@L[l#֎icXOzf6g/75e  pcT:m,G#GȕW^izK^"gDg+vו(c:p?U]1&x˄#vô 6ցs1~#ھ}l*ԎP:xГn0JGS hwyE^Gg<  E&09:|c )հv2uw_$]#%Gl̹E%#'_k *,.J,+:~ѻ1w0x_|9S2b ] ,Ϛs7tuaYN?UFÛ4ibv]Oȫs-Y* 24Xٲ2kaiD/+&.ӺD[Gp;'"&عIxtE2{kyDJ,,FOJuyo/7G>{{xg9@C$0m4CJ1裏)ՓO> o8zG/7֠Լx L#}2^X#?VEk^՚X /R_zkzT (Ƙ=n8N/`Nc3g(h{Tk(G'X^G #FP/R֡#@6ydF^~9O?`]k0 nfe5i$y뭷T++V#q&`i%Ku|P)Ӟ,ej#w_1yK9-V[:2IHHHHHH (IT,/Zϕ{g*mHpHHHHHH zk}pL_{,=xH dxHHHHHHaUK%D0/9+q?hэ% vIi6Y28Y&ڑ J_HfoӢH$ˢnD}#Lm\ZV뙄v2HHHHHH (emeNTE+262qќ|[LII/<#      J.K')6*"WJT#O<E]$'OVz-YdTVV… cǎ6 @00\y@嗲f9t޽[֭['~+2uڒ 8D ljLh4Haaao>֭M6ȑ# $Ǐ[-[kHWXX(qqqv @~|Y\uրh>|Xڶmk4\Ǽoٲ$%% 7ѣG{v/Jt̘1r{'ݻwW/ҷo_Sr12wBBj]UTT뗸% "VW7537J`MMh2My&1"##d %x{LN47p$''W_}U͏m0=jҤ~h\IOOP-"HHH m|AAPSX  ]gZW%%9Y֝&~!0GKVqT5N.UK>փiƤ(JDDGV\)FjJiͬHHHF1 2ٿƾB$(hRU2aJV/yp{4k&uj!Z.xӴ?1YuF'JhhK/$ٸqTO4<{3 @FFݻWuvc>sMސVjX(/FRAg+$@Ptγ/Y3dqXDWu_Y6*s#GbM6 eX0l0T)z><򈔕IuV֣pK$@$@$#`YjlذA-Je|\wurW:=<,+RϥLv9JJ&T 7 (e:4tR)L,9{XjJd,M]\nprw2vXց5 o ^P_hLJ)))jYm۶)ZC _~Y:, [V^%X~7"+Vha  oPO\ɕruPmQVH%{ZUUj$vΎEdwg_|Q9|P*   ͛7+G={˗ d[+ksAywΓ[nE) (gVS0_ݚ6ŭ1aHH[̺lhZ1_=)Yɷ,?N^ [v&Q) aN?tСTb|rUWIBK$@$@$*~MΝ+v8;)Sse;|VX!W"0e@(!@v4ᗠ NL]FRXB[H~|n>;Q޲e 4H Ss̗]3%  0"[oe졇>''G)_}8GJ槸op*R W#8k}`Y 5i?ȟ@2]/9yZC%#'_c%6J2~]%"cE~[UqiQij   p/wq84<ܶ0O BL| :`8`r@? @J_HfodY4;Yڍ(c;J_hDJitlc< 0OSNc#]HIHHpF9k֬,e+LH~gӹ+>|hNGFI<^' VM9QTd5rR9q k*"+pa8 WNU[:$R =z0]?O%kKc-,\P0HHHϟ/wjuFҬixW:tIYch02wbz7_uL;%/aH]S'm.Ν;ղ]t{LM.'&&ŋcC]+=pP>|\s5jyuɷ~+2uTTL)2 vSO=Upd 7 P,X #GFÔsM+F[ x!` oV9UW #GP;EIH^SSSȴ+}8b"d.&c|04̙޳gep$°4D 4}|jizr)r7|L[{jICcݷo_ShZR+LpATYY˜SyҤIztlZT{%O ܶm[T _/-R^)L16xwSrød2 $@'w_ۦ@taÆW_-zsΒT缻'P7,4,}[GwM&F !?x滉hòJNјQرcȾ}v{ 퓅?\ͿGV\)FRkN'xxyr /bF_5'd)))ʯMGˤIO} +8XyQAaU6HR@IDAT&ok4ԴH:c<AltdI[w(fLJdi }g۫"!_~)O=_`c@1ƍ'p`%2nLO$@NGRy73TKaZ TeBI; *Y<[yM&cM_g~ƴ[?93mX*3uBP1P&LI8iARˌ~pȥN3#G]?~饗 O>b^lĺGo* QdbI&d4tCT/J@M;Ͼ\2f͐aeH쓏>FZ5kKڔ(NOˡo}RI eѷ'ː(^, /PjqhRO"RX$Rӗ- ̗u//{.}]"FY ,zLza   hXxe6d9}^9̗Fum`DFT\^BL@)+RYpX kiϷkv55kȣ>*6l0r 3)SM !  XSfgqiFz:+t뭷*O<ΊAGL:[2TFKgH%`f]GFdERP% 9fiCe?{ K_xji3f('bǎSkM>]9мig1> o >(\}̥2 ;y+kuZKagLRSS|k=^ttRQBdr[K4Lt1Y߬rMˋ+gVa""* IH!0o<5k̙.wHSsr5Ν;}CSKu۽$==]Йn)^xct:IFر>|X:v)̇H2m92LÀaYYojI&j3=(45eU e:&&F5Nz4 V3\ըǶ92]XXFhteNh>|~8~4F~q@5T[=eS1^2|^]nIH  9nLR\AۄtikۜSry]m6My=wڥ1 HU_g.c߄2@C%zj x*AE#ZTTi׺uk[rJ5j=lժ[ |‚ՀQmG>FxapLG$`<fb m3Ye믗E 7`uCtzcjFum:2U Atb0CAA6ʨ qNu߭,? x=zWbi*#820{ァM[Nƍ'xfpFq% iWӻR&Ӑ Zywsڛaڴi<W_}`뀩]III֧M x@M CH)c?섇K\\`:cccU; +,#Ƀ S3JH]hìͧ=NS;mn gd0G/ ݻeʁ-^uJk8Ka:k!06JNg54F[ y&L $9fs$'KRɝ&֮Z/Y%Rs܊(DRϬ^=u抴~N[  ?ttwo!gyMSNqHГ͑ΤRXYIY_118p@P_A9eзb].c LmX*3أ($Jqܪdgx䎤=%Wϓ$@$@$@'rw'N@qRM(0c6\i`$@$oJn}y1k,(!14'J95&*Ļ쁁'z˟IHHCf{ߔG ù;B#pc0ȫ#HG@)ӡI=hKhӄCW3]Z:szdhJEޙݭ OxtW'   8 4i 2DN?teULˡ7o00"12Me  z (e W 2V\͙DH|btK[Q}t^=}$*!  p}Hg!mڴ޽{YloVJ*gjÈ4Y9BqHH2][MMZj:_*s\'R.f*Il'h} vi   %11Q} D_6XSWHV,;{^=7lj Ν+K,QF.\(;vW^$  .ٳg{䎑`  &PLKr^v94_2r%.:Vb#r0,AbsUkUpJ)[n^{MJSE%oVeԩs' /D֑s&#y2N=}%.=x@VVl;F\+j[ ;#> # %VM9QU<  *Ř1RXV)c%QOx,**RKlexĈc}娨kj덗,^\UCߺ^6sLezw^ٳRxЛ=Ť_ֻew"@}zȺH'ЩS'-޼y2?~Ou嗫u/9Oյ^+*p8AaߑE @ի"rnI.U&^j'M֬qƩ0z-eb ϗ D)OF:ex2޿3ݶm[df#X)]vecCЉuA΄ңs3IWRdgΗFǞ"O;ED^̃HE~ѣ"ŋ2E/6>04w.o7nSE1  (FPNVL;S믿Vhvtd5<<퓕)iy;@+c+ddc&H.oauK2G}T9O1c(5sEZKEZ'- 4 XN # O Sl>Y~fp@$@~!`6iJJr$Uӭ;uM R/{w,m5&ͤe&Z[O9S:N]z饪4}   %0d)P9 ^*nr<ǔ9 ҙ6,?QVE S%?dW#pM/NN޾jpBecӧ˚5kL ͈1S _~)k׮ݻwKiii:' bs&`.0ILLzp(-[47eζ 4d'o"|IJV.ɗM)̃ThdK\t岣\вF26Uo?ҬFۣzS6L0+Uv6mRkSCi4h?n1za /4Ȭښ`47:<)^8:;zh|O5z*`HfSUoyp %/|֕{|\)iH ࿏nNB75 &cF0'ZKFsndIH(2vޚ=ɲhv=Qvs"Ͼ*?b=WuT2J\cڴir+$=8۷~*8*Ո`nrؔeh(H/|ةvm-,@X$$$kWj}duؕSF方Zw0VG4E:s20|"}B!GAA-,sZ$}ݾ}{<a OtpWAo_?t萡DfgdL $@$l22'r"(C-Wޓ5e%!=9,_{g$ji)FjB7֛ӧrdsNٶmRڠle78@hzΒwP] H>w Z6ӑ G'qɅ^nrcj   L;5( Jjkg9̝;Wnv2{VsQE`q`&CXCAʕ+s>Drj1?\e|\ r'2 _H#gy$%%I=Tǘy8(׉nϕ)\ϝ4l32٧HFWH'QPʴ'km7FN㙽_].K.uiPvi'8 C7̺ٛH8j@ZwһZ.ӑ 8O@NarCLT.w=uM#ԉd 옌`%#;`,NJj36 4<8N lK;vG}%EںhGyD3. @%uֆ[9 \\iذaBYyHʴPJTͽ=+d/^|1qȐ!}vRi`e$@$`()C  ۛ&}6T[nu$ W R8 v1ysc=i|zhS^   z!觟~*mڴQ~R=fAv$"/#H8M]fs$'KR5ݺSD/THVJ 6ڒEO_+#`捥| NH:vSG$8$@$@$@Ϙ1c/0ewNXs9VgڵKOֽjLP9E%hz%]RAmS:sц2=zUe”D;(~W^\t}rVjVxC#Ԛ @QLBxWjk=(\pApC=$_޸CO@vqjvݱ̗=hla +TС!d#˝g_.fh2qn4yT(j)\0b )S(I/A,ig+>rLHF$0fpi#+nݺ[57m]zz4o\͗P>BXRJM)]T4!R'^D+I$u^w*BHt)rHc$'|R=D*4i a-YDpBeBn ) @핽'S*I^{MyWkx_x2c BokPTT$tMu/jgqKe6'7n(o|G)n8SU_~E;lݲsNٶm:v+c&&& &6m:'=:8O EG::)9H m+-?ӂv?::Zx0`.!J.ȕ\)JVL%RM+S,EJxX.8, !BaK[ÌkaoVq> `J9PtV^'`"q?Wk kq 3$Gj]9~W{+-ddd(FH?QK0KO5RNݻI'BXXzIe]$0Et\\\C@p.j2Y6ΗWì"l7oެ#4?~|bLL^I4L(Fg΢EI&/0qAzG(0%f/lٲE]Q֏w<\[8TLЏ]e¤jur%ʒKll]\PQQLuD|;uYfA@>uaUa.>߻cYSݪU+R;ĽxGhwE1,^` `?+2FnQ &(Snx yAsu-m+J7FIrۊ9Er˜*aJGϚIQW\;-  [ϸ+ǷAx@~ ŸRb.#S$s#`-,sIu;LqTTxX{Lf0J<@WKj//g}Mi>T oQꦷPvN=Tճ=j(9|23yls((!z^;3- xG:eDU# Aq?(X°ъ+"gI\r`CXެ^Zyw::u:_t3ms /PЖ# mm(:þ a=/ܟrM&ɃH2Y +ɹ?#Rvf_u{݇"}תi;F⩔VM9QrUdRK7G* L8:@ =|jtw)? "0?̻PCy 7N,³?Ow`'GM F?c.ӬYL1 ӧeLC0JK;r 7ȳ>o!@rW |`y,61b[1 [l%@0J0LFd#舂2m2}E9I>V@;4=Q472]ORHԨ@,Znj0܏Z FCt#sx0 'ͼ3 ϛX!AwH_b\/v1$@$@VsSn>o).2YfR1<~ /0:t'M/BFWtF~[p@0a!I /X^@$@$@90gF *r0)wn,̝̝i]~T@$@$=+dg-RW #ޒ 0Cjҥ*|ۊsXfޔ>q2FbTF@"v? -@qh1=C_UV˳Z(/ @]P/_._~ok 82o?x#[uCGF9~xz%VEx7t0 $*)ɒTM5Q.HHQؕ&y!aбto?~mC=X(<ʽޫL W9Y8 Ν+E̖~"eU۾ڵ= OYXi%ωWC@E("ʄ)w|)dGX4); ,(/~'1cS*~X0 x>\.]ZC aF$@~' qAirʘ)o-Qi\ %;^nx-yI]KK-%~`) xFػw$9 ;ɾ/\#֖b~ym)   _@(rۊ4X1b\z饒*  @RCzJ֖Vєe3]Z[cm\Y_%C>Os(L5{% `=|7ҪU+&ӧO+WuNׯ_/wu ǜl[lfƓ$C;g?H@$@D!Cdni&5k?jM2db ໊W2S/Pf\.l^8Z:}|[$b%BʭkQ0R@gy)={ȅ^X<ӦM,#G nIJ[pfb/lٲE]*))cǎ~l/ 5r#p%deep9KHrE@~,~WϠ0j޼&GKu9~-P[n8XV/Zh!.\ѣӤIY<_m]ҸL?ch}a~\+HltرӳgO<묳O>#BGgMmsLDHWRٓ-`)r `ğ&-UkL(Wv|H~F.O]}2_?BXdzĈG}$2ծO&1^f`5F1'e:,GZsyu7WӻN]ߺ-W/[Wi|ĵiFVmp*}K$ )cNeE[3[=u&lz0p̼e޽GұcGj[oכ7y7VJ͛'~yz]{nכ)/뱗緿ṹ(ɂǎ H P)uE-?(R {.a6? vgȩuLbb2džRutK.Qiv$ɇ~(}Rcbb藞 Fl](==B s(FCl^gP1w)(:'g3eA]1j_l.{殜q%!~u4Pm>8uUB=@ F+/`zw%voajx?߯BhRU!3 \g _?T{:޼a6i$߿BryE58)1)Ju}9>n&#Jm45]}3B]Yr q 8 yk|^J5B%#'_c%.4V`Ęm|= VΈ,-Ne$K*|LJN:)eчz7oެ<7̿0B=j({@O ÃW"2j}=5לYRMSCG´x6kϫg/-L1cMk/**?\n&=;-A1-Λ<ӲqF…y\Nݟ={ەu]ynceN;*:O6Ulj,]ڷorL"@eړd˫R{?|䯣'Φ Ijv5@o* djJ_HfoJ f&ˢnD$?Rye*SC{*ߎX€7_td^68Y9 Ζ;C0J[cǂq)g@F"EWhw Lh y':^D?c Tl(wE`J"|e]Tȁ 1JЭA_G5˴ӗ>Ds~3F)ӭn.s,͜*2ȁBx<3J))\IH9&:a?lwܩ.]c=&p&^ŋˊ+2l*h nms$@$lR!Kj9#(zR+$̟?_uXB=ܣLW_U/_έ[*ݻwW9FM6=*" w:7:1GiwNLTD!p9d߾}jJ;r`.6d1Je2m_~9|CL3]lI߫_*_U}bʼò//T#[HNvYvy4hΘ7+x9۵kz? =!)< +<{СCJ2eZ|Rpiɣ>*r1qW}ݧF #t"@a0a@s'x„ }Ja7]N&n'9giC{F^6_xDd4y8ÉѹQZ*_Vhk`wTT[Bls:\{מ,Hy½RY\dBXڑg:7u3o\Oze*uŵ?S(꫒̓a4$FYL_jLsdw@hH#y$Btp>v|[n0, h!̗p^\' M qAqOQY aBL}@/C3IB|lрƠByt4u< S~i>dc ADݣ G`kˌ:%f:`_f͔zWsKkoX2 ]u!#Alx:q8Sw_(..VZib/{X?:ϫr0sOt"7?FrjP&&lA[S߳~B$@PthRO颍:5 ?SHK&e [VKt`Fg̘!( Ī8H;Xw#6:rJW#ilq7<=oMg9zku4ylUTI"F0u|ysqxKOOHgGPl<,|:JP,Wv7-Z>HE"WupJ~U >&&FY$ % l#g7XwFoVIe6T߆)N/;/_Sa%{ kssdd[uD̉C`û3xrW:ġeU۾\2q4PiwSJB$`Tf*&I"dKe_7^ojqb)o ʖPwy.!DP~q^g% G{r|aa:O?lܸQu ޠa  o0SmQsL:^&3!9" GeѭO134g<*7&YzPA kW,Zr/vb]DD@P$%yϲY6&fy6{vΜ93ٙoI6mva8CC'd} d,;A!珺~нuc;̲4c_UWjiB)-0lX 6 WHj'WΫvP{6+یn$mF9׸-V)Hi^&afX4.2j]w]w|*L0: :t AޡʉP(Nл@MHII)oԨV\MB׎̓ʫLA[Jsnʨ" UycйF CNBSQ^/tY5JzvesA=1cxq{lԋE" " "l@IDATstMxꩧnS-ҹ~W qK(,6T7H<-[kע]vQ'LttkƄFnZ;<8q8u.}' 86׬''tR`9.E:XR'" " C ;;C _ . s 0EA孉L 8X {ʺrVGbi2pq\v" A*ӻ@j^:.$'l=['ȭd>T/b"ݻw`%jIIjRRŐJ۶m2Zi:"MѰr_ն:'`iOU?<~Wy&|WՎR-(Ҥ{/TUo20 BQXhxn3gF} ;udӐ@(,Y$Ũ C 33O 󞖖>خ>5Ye٤a]д:Zܾ۰aTe4f}AhU: C kai)SBVnDD@D@BEG**˩pw?.|זŋzj'YCw=b8ʯLTn:pQQZʴIyE@DweeeTc> ɓqADUI/_s>CMmӦ 8y駟ڐRWSqq1譚H W\饺YfQ i&DNp.Bb |j-KWo@mE+Vq~#<7xPM#@ԩSU `x!oM۷oX}\s-N^Z ΋@x \y+1z. \y_>d${ [pmWZ}yg;~aذa{wDe8v>e9o[֯3: ̴In]Yf@' 5?lSN8`q4xM2_}Í3U8 ,ϪqR3a>{ֿ۪8gmozsPUϡi$Jߣݻw5½0hl'-`ֻ<*e9I*q-[؁k49@e* 'hEIV[m!hS'Ecܢeb|$&jF7RSwy\nd0k& O_t\ L^ vGZfP \iv_V߁w!ga'VՆxRzDj !@E/ dȐ!X0ۘ8q>窚:UTH*&\h.9 U)Dn^{TLNO@i繱+hڢ>&+w'SB!Z'Gu.\h0 Z v!,EuPzV!t,ZAU:/#GZ/ִr}'8p >hkU׿5䕈թ,FbT1rDw)ڝ˫,z\C1ʣn ]{F&Ko;55< Fɬ}`dܹ:t Y xOP!A @5@unSO=e0n4O<֭k?O4&N?a1 #ھKV(\VΚ&@a#`H34ת8’"W𝇭vN{m Wx\(Z.jT1cjZY+[jUuT+!sUYNu 0qЦw_tM;`9 e,zǠhZ:MRIA"" " E& SŗDD@D@"MĽan͘O.Эi:x1Ly,2g{_WNlME-7o{JzWϯ5," " !t Yq Eز~f޶zhYo=uIa)WZU@'Y"" " 5Iw&Rw!sԩ[ ) ]ǚl%" " "N;4%K!q{Su$" "I܃‚HWregg9眃ntk}v\uU83mc c,CĢ<8CйsgW_}]Z`A=cg'\;Ta4]vaҥ6dz'H8aF -.3++ Gq7QQS=X۶'>s\xᅁ3Gqɓ7K.Z]9sX/ٙw}ӧOǖ-[p]wXNEO͛Rj]],YRq]va/뮻=%:99_ uh#F/~˗ kNEJMO:I?xw@E&I$y=#rIN89sN?y7jz8IF+VE]~ک Bك>> v褓NB:uyu@;ć~-Zgv>wQHDK혇FCs CFmp.*j)Sظ*3bӴiS^:M7W"M㏏6Y*?o™͵kbv8ԃpsl9-8nٲ%8UΓO>/"VPkݣGZӖH7$Uo2[Л7T4yรA p 9SH(~mk崌<8ا\pVQ)eI$y=WiǨ,fͲy. ða|5N%SNݻ~do1%գ>ڮR3ܑGֱW^k|?zOd=N wiw}tW3-ύ_=P;1 0RmS,wGRRRl֭[ggikM|rVƍTgj^3\ E)1'c6mڄ[ ;vjrC:t9+ 3~x}I&NE@* 0n8pՊZuK/W_mMT9?ӝSz?V$Tj#!\;-T222@cH"Me[nsF@\߁sƍLÆ Å[.MkNRD47ݮprԎpㄚ ?ۦMy=裏nD;&Ց~n4otb-"v}/ӱ>c+ܻآ=nll܎V{%(,8sw7pŢpMkF ;pf? 9c(Sb^C*4s-g@X[a[o{c廢z>4fB _Ei)Wl.ru"TtEs}'=RT}|BR?6ﲯOH֭U\iCE#( fԿkLŇ[{IF4v^{]yru&ς34pEhnsk׮^-۸M\hÅH~-)E ѕN~yx򕯑'_B6?LƌMׇ0Iwm0- EӞz)#8O4dv7WiNW\43ÇVgބ8#v5+h?Mg852꺫<~r25e M{Cٿw@Q(Gs1v lhlI^Tpc *F֭[[3b?sh;=)y0۾ȇf\(S 3"lIPGz|)nm۶N5k."D:IJp5슇GBJd`<~/&^pnHگ ./MDӤSp.0ҳgOIڒiCY? dh{ @u[^~=:묘ZYgs8r$&&y޽{U[v[ot~Y)*R0m4PUC#t#}?>qziI?eM"ŋ}CI1nk0jZe :}7jJ2 -"ňu*Ǹ"L?*tF;۶mfW±7hıI"f}%Rύ<gNpnr +SxO@n^I)Obrz#{8%u}`ɯq߮F5/!=M"$Ě2X3m hGn\r&*#_د?h'8yoRA7'Uҟ~ pwӹ?R\B\^QnݻwFd$bD⤃puؿִQ$ u thn.UD޻kyeyeL킧(Ј{TH'} 43 [rssHGƢY?Xo>OVhB*1uJ =4uTBJZ(-#P=[f+Ҽ>@(b:w ne]#Y^ bG!gݖU%@ R"" " F*Ysĸ8liFw )U(MD@D@D@D@D@D@j+!sUy`-rMf%֝EDlނmauk@`NϞ=a۟C0&DD@D@jwyٌiv*%a3^I=.MӁ믿n=43+Mh/hrE@D@D\N0a}hl\4wʜHM^:MD@D@D@D ^{5tM3fLL )" "\pg"]NM/RW 6ؕiz@H" " " "O ^ ƍ@4p͜93꣺@XdI'nvڅ=׿/ .Btm{u)))+AD@D@H ka;eʔBcƖ-[pN:SqմB۶mCvv68xر~9HUAq=zDOKJJZTXk֬_^GmE@D@D ~bVV_o]5hڴ)4h<ۨ[6?Sʲ[P2N9fͲ\`Tw/r6N ,c(멲D@O@~~>{9̙3}>/\Kj#F~ΐ7ݻヒ x+"GyXEHl]Sڠwf#}Cڍzh`Nk?xG)z O< o2tP'H|0FN:)dwz嗑/8deV&M>-\ 6J1FD P4zQ^[U/?|)wҥxqwO>N~ /`v0[nbD@b˕~`hy}ؼ/n~2=;WQݻO[[EF/v6 6 ?} R2d]fAX.P M9' 11j\p~P6UeD IIIQR#U& |9ҢE Ls8+m."  $5슇G2'`0h3MqG9 N&m3^0%7*nEEE{ԩk&e8+Gv܉vպQF8#1|pdd8묳@7\ҥ z,Z:os_εg<КmQelS:'lW֙^Y ,6mڎ:([_V _!g}r;蠃=xbмsϵ7Φo޼[%y:ܹe=_j heS<\sMKNp\""P; s=xg?U!%n:\wu֯-x~Ww}v՛38&Mf5j^z%?'_yJ 7o*|gX龋 N:G}ht0h nW\qV\iX׿pa?@f3f̰uhժ.䒀;pǃ?P\ fmD0KKISS7 /k LCoJݜ[*{VZr,j^UP9ĉmG=T2$sQQfrgqh}vL6v{ x=CVm֬YŚ3Վb\{y灝5oǵ^kPq5{-ﲀ)˩e]fxv~7#K)MO?tˉhĔC=Ԟs3/ES6ޯ"ȕW^ij'So^_Sks9vElE?#ݻ[}_q}Ԣ`,_GqLoI_/VZ-9'rr 07nepu/K8ͲN8\.;OK.*_}2*ۿs@#, E]d'!n[;s|o-NulVyQmٳ$^ղvc&!3f{O3iEYwq6xB~6{؝la&fV5+4cy1^=fb)<\T+0+ NE\fbc0nQX*wQ%rITQT};(QYc\c=fU&dfcks7>Lx*7XC|s'nٳg{+;N1[ifQc&3IӜ̤cb{3#7SJ|e?٦M8 'ׯ/z 9ID T7=`^יuyj^m̫y5+{$g{xaf*}P=RaF1Y1נ|EN(ͧл7g~9+;ʕTZDpeW8L)p ŕWfo޾; KaH._ s-YY̯0)/M.eqwo16iE5:Rn]u] ߯*3zk@h"GbVTZ~~͑Ncǎ ^ Y;V7J`kٲ';ydkF7]㘀[w Q^enUEXzZQ8~ql 6s[,'li0򒓓 ?DD`/澉qs3q<أ1m7@< %_Y(܃+W+㔒Uq$M|{JXYJ}4 V*[V۶mKvR=Q4Vܸkq :ϧ:ײ.L/48 `VI`V^ABWe%==ݚ+s rQ<'c8anVvL^(8 ε+Ch_iܸ>{>h,c `V`8n&JȜginn&.߁"ebo49N(={c@J%*5n 0\W!1#TܸϘ -͝; 2zQ# ᅿgv?3gᾦ@Ҙ9saWʖřd۶m+2/zDFeż:ϧ:ײN:4@$@ƌfW8aJTVhB @}G$V"!8Hg6B1Xe/Ieu&}@?(OZU$U J=\HLX6cS^8A"hLt&*eaw/:`X,*D/lܸѾ3N$qƱkB%j,WbLgf3̌kΖ3־MĂP{r@'&@;3֫9zF7{*{ys0M{`/Lw*B:Z:E* ڍ'}v&ihWZZ0'|eU oDG|U|:ͼCI)ɿ}(M i X6Bq6eJO"`tIC]9`2zy'iTȾy:8 X S(ftESîX=8e|ɠ5}Gȍ|ř}Tj_o>\yVẟy&( UDN$r{"ƚ$SԚ.vG*8g'^g}MKZl 3u饗&9cG.ˊglFn~\@w6v9]*>x$;MOKc8RE`/j3MibpGK[*nfox N1/WQShEeN؉r/4<8%T1M9HyOߢ3.PL00YfWL gq$#oY:ńZSDžF*PD "hF*#lS&p`#RI4*p}7љ'l*={Bh~؏3&A?/ܫrB@:VG8!D?14%C4NNYùc }~kn SE@& |eљ*`E+ΌmHE҄{43c !WѹA 5| iޛ9ډ+*v43f̰H {M7dXvlu>,ϽތM34Ƶ$sNdL2ޞaJmnfbKsp-~_4&Zڡz&on+\}t ':裏ep"-d&tУ>jNNscKsp6c9_^[nX^c1)8jپיp6>prӧۉx'_zL ~*(IYp%ց!xRZ{)xe>T+r[Д+UGBQq6M٩r/89B]3pVβ'ʼo؍ yO<ۨZFKrֲE9ܣPm?r瞳T|ᥗ^=e:s/o;1pz/s2|4f[=a֭T}cއ[#`Q}_>@,JoLw=T{y-]\9 8d([er"a>U aRYa,*͜v=TҹϰU B}h.NE2M\@e 8N+{K *t>I3Z.}vu]ghb9s[150R`0T'_ RhA8K ee>jpr]b@8}g$" CJqʹBMGiduW+"^TiR}Sh :" 'p_ɓ r4PיeD@D@Db.fNp.BbNTw63+C:u*r@l#Rb[{voӨҜ{-T\9Ie!q葔$" 7hG 4thCOތmBZ(" "P].WJ-nr}qlvSo5L^Vh\pZ1NmcD71bDtW wN:RuRb|ITB|\} HH,jeύR rb~FS+WLlgGOnmv"m+[KD@D@D@D |،Q |s{r'i: UD%F; uJHMsmڄH%-X O,nz&?hAӹpKQQL'dKaK7WQ" " "P!<ۓϽh*&'} 43{t{%^~]$ɳょpAS2+,\D@D@D@D衛wȑ'>i:\dGyneӧR~2oܜEᅙ?AqMo#nǷ>TPD@D@D@#O?&ޣF\|6bśi7pM[x1?JD@D@DXe:kxe*t6.u[Pg QPp LҍD@D@D oVA߿MO?8E^z8ñtRo^@Mp%dø^-;[B}Um@c%6_{;!" " "?nU}f*˹8Jx@ 7fӼԥQ=' l~0ͫ޶m6oތ֭I5k}?'--5I.OA&,֐}Yq Ҍq8ٽ ƃM"sC& B " " " "P}=z@ݺuq]wᩧJ5Ow={ހN0QGMׁܙH-g9glQy<۰P^k" " "ڷoI&Yݓ'O6Ug̘aR ӟyؘ1cn0q+.? ԩS ܟ囊7$]D@D@jk̙5v3HD@D@%{jFK}bh׮]țлwoH^x4n8)>ύB0eʔP2D@D@D ,/Wܻ\"E~" "ﻲF7 [X0+64x<6?,mcS1 =ЖXdjh"yiZؿKm{Z,ML4B_e~Np.Bb !Fl-m$#AGU4_1}+V}q\ @TLCO %{z]=[oy}ؼ/n~2={a}[gq3\YG DIr4}1NܣAF$ nSE@D@D@D@D@D@D:g{xaf*}PA↹N%co`[F|8W䉝)9k77=#mp:AsJ|$64iT8" " " " " " +!sUI|r\hӻ/;T<1f<ƫwbBw3=4[*ܢ(" " " " " " F$o͘=ԥ5݌ի6{ ;yE7Y" " " " " " "W\N0a}]q EwLc-K.33"5%" " " " " " כwm&" " " " " " !&/bc=6<T={>`5˼v6󝟙5x`z2e z%Ki)NL4B_bz/QS1 =З縉@K ԕڪD\l[^v:gl{w[Gה6hg #cK<FJ0^$Br!j15MD@D@D@D@D@D@!r \y_>d$?wť斈@p5슇GBJd} V/~8m}$4ij4y?u[T:ؙWb0wꔸʽ%t#$,MSg4CRzl4&Q"" " " " " " IO!r4޽h*&'} 43{^H؈ǿh35v:M\" " " " " " "w,z/LE~?t<&LF߾Ą." " " " " " qG*Ys+3Wtyw!{1OE:k0@" " " " " " "p%døsu 0qd̅6[$lX4W2Rec96_tJ&$BxfLRԥUw77f7@D@D@D@D@D@D@≀i=d6l4+"I|.w!^34N܁ [ɯ.3.3zW$%&=8&+ MęXñ⊳)_|1lK{l\@T#E@D@D@D@D@D@j={>`Zۼ(lym3/:;?3}k=2e#qK,?1 1PSi D}O4B_bz/QS1 =З++++U" " " " " " "P =yXzNl]SڠOcUb4kVBu}rPD@D@D@D@D@D@⇀˕~`[5OFM3&%u"]}q ^צ!%\ủt?;M.m}Z*" " " " " " $.2MDDf@ފ-ؒa a/&i7AG" " " " " " "GN==03b>( ^{4<4a&6\ld%["" " " " " " HzΚ&@a#`H[F8!tp;[u[%X^TMDD@D@D@D@D@D@⑀+!sU`-rM ʃ}_^-MLx$6=͘=ԥ5ߍ1לun<%x@D@D@D@D@D@D@≀i&LO 6A뷷_=nnL!Y"m@>W(AD@D@D@D@D@D@⃀ LnlbdvN:HvdeYgD@D@D@D@D@D@D XdӃ$O<]lܸEEIbZete^(e 122/xEL8Ul?FYΙ2^=^pww}d}8 *jv(.,x^LX3ܶ`~AB;1_=q58 &c杄:%nrt 6)4 s ڃfeߝ&U"" " " " " " FO!r4۽h*&'} 4Qz]]f4'Lyޏ 3o^w3t΢T8׻XQS 9"`yg}fxGc_݅gtu0orcG|1RkE@D@D@D@D@D@DWB <a„!`PФxm\;v> " " " " " " Fw&Re7;h֤jtلtFD@D@D@D@D@D xy[Mv?@a6&?bfYD@D@DJJJn:deeU}֭[~zuqE5s̸j[ x'|rФ$?8?RիqI'JŇٳgOƼyпPO| ?|/89x0qD|㏑kOs19r$N?toYfSNw}c=֛p>pWe.K,] `k233Ѯ]@Iw~RLLL>}kKT{=\p[nw]=0x`15^_r޳@IDATU/ ׯ?WU.QGݻqEEWZ *OŋuԱ!99[ĉ'MpJA8뮲G )SX)ex#Xe^z駟l_Csud82+;0vX\Sܹ3.]j gy&}&]xzfFGUPWCSIxWиqcp~v؁~*T^xvmصkWtZZz쉎;7@JJ 6mڄ_ė_~o*dlͷT8 r!K1zh޽s_ 5) jk,+K(UNJc=l0f۷Uvj!C !!\2?~<}]\|&1`\r%v 5% j#" 5Iࢋ.*{x֪;nrњke61^୷B.]9sЩS'JUY \oA1zl2kU쯾<ߎ>h\xxgph+(83,ŏ?%k7"H΍XG|Rغ>@ P1 l `ԩv34->smǍ: 7ow܉J6Ͳ4*׿fKӌʂ;̚wСT.̚qYW BTY;rZpk3pֻ@l6-[죧#8¦" 8c9ȢE 7`Wuw6kNh>`Tx|UWy`AcN_d-bVvp*h]qvs|rr/Ma_ljlǯIY$=cfqNWw[8s1M)[x Қs,}j_Tg_4+`s?@VI2_Oggc7y7<+W,|>n̂''߯s39/e2GjN1&ttGc:7Yyc2olٿMlzjjM7gDgV= $<_cVZyL1+k̫cV½i<0M7{mqa?uo>R1M7ȼf"ὂ3טUrO^^2Bo,/cf#3a%@{3@ Wzu[5}Q<9cVw=g˖-4^þ(40Ԗ~¾b&=m۶-՗;,HJ0JQucy5cmEbVN=fEl1P۲ϥcL=f/EFq_'2c! gyAX޽{{%zcnuWzܚ4i1<,՛8362>?tPk T7םuy]j^g1uy1&Uטy'NFQ 5 ojN4K?aY>9h"O?:Ӣ)҄+3z.\͘|4SM\M0;KsfagX9}UNIW_[Czަp 8JՋ뜙H8WV8{G8SLYv}ld$" " M\9拦hŽ>mQA'StٲeKogӌ{0tzw' Zq1Wy#\1e n=hUFStGhL+)Ue\0ﴌ1-hon`ZUm:)c̳~Yx3`/ oٌbgM Xщ+|su+Oh1㜮WlhN sI׻ B^4>}(@Sǚ{4 9.vn+UT;^nYThnF2*4 {cfK1v 4-gigXsqi/THy4'ca /lvQu&b,ؤ"68]g}uV+X^N8." "{F^_ܛK2GrW؏c{ =I?`A_8O3 H-|AFdCle 'i:ͽ wq' n*`88;9?)AoMٌ>8zsRYq{H0ɧw*>g{xe*Wu'*c`MB{I~mϙ;^v]׉@{茂P!^c*4w\9ΎDs1ο|W9[˕`3wu30Ta@%7ƳsiN;y|W4wk3y,'rʨ sE@D@5AԖ}񧝽9ݷ_ܶmǹy=NYy2W*JŌ*½)tE*T*}T}};'iqhJ'8rp_hP 1FYώa`Wr}r."`ᬹob t6h4Hs9 ߥڣ/) K{߱;:zJ@!Y7Y.͡l{7QFNOf55WJ3qQ#,)Mz!k(#1yo޹ľnF+~P^[ :;P'e:}iރUJhE1{o˕N+.ĄyVfA-`ڬmG1Jٝ)K`ڊuXd9LQw+euE{|MNC /=Nj#ˎwp~ *XO=W 9>ܻęp*8;X gf}8^3&MϿ\NSQ{ÁQ{p" :%XV`7x^ :-*goqT}Qm# ,}n)dסK I fLl3`9])v]>~4Fy_K? l^$XqhJF(vn/6ͥh\-vsQd\y+gRyrV1V (cL|7avPW#M'eobRS싟rAln FsM" ;C]qƚ1TFUVAYy." "'r,C?'ɒ%KlKQ>lLNkW6-:!㖮&+6g Wu1e-޻,V2*se~r@g/sVfMZqAqeq$ w}5CghZUWڒ8֙3gpQ3F4'@8pqr\3:Nr-ֿMyes]?']"P%+3ݠÆcSMȃBn{Ι! HO"`Q1!8?m) {,xj<Q<8c_f:.=i -ax7Jx Nrt(}=颟b{[Ä_99x? ں-,r0{<Ɯc a PaF*Rj㬰1N+'Tb e~6=ԥ eİM?/2˸T`~!8Gro͛m+v: c1&>lItK^ I.Q=fc/8rn8 +5 ezq b&?<{X=qyzqTf7#z6oyU)3ZI*o^JBl2V &|V$$‚BPv/(g %"  n>|8S뛇i#Ԯ]̾~/2fJe\,P9\ +G::P vW2ʧ46,\Z}x/۴Jj2=Pן*3 `8S`YqŜ^o:>s|Uk\^ SZJo5xyы"bA:.6J 0I RʟIʫ2*˴`8Q{:){ҁX 'b ΋ TW{z)MD@D P!PH{/ӾiW4\\8NރPֵ#Ёk(273Oi"P KD@D@D pߦ$4hY}hjRD@D@D4p.:A )V" " "PBTt%-$f] #3[]5 QyD:+ZɧC.WJmkC7׼>l?Ϸ{{xa*Z߼/C{SE ᑣ0aR rb~F> ŗ4kLxzӏG^ RCE@D@D@D@D@D@D4cmbHʽ%t#$ӖIv <{qFl k%" " " " " " "g)Dn^m{TLNO@ikFn3o/DAF3j@0ɱ{S(|gz& 3^|0ɎBD@D@D@D@D@D@D 嬹ob t6hu[`ת=}Yxv$7ۊ'59i]_Z WB0e嬴^i޵qF/\~oD@D@D@D@D@D@bQwbob>ߍշq/ 46 uɆyxo68+qxI5}[ZN9oƍÙgu駟=cq?qͧ#իWVZCaRE3*lmd6t.z96L7i/!\̾Vs6ev| M2c#ϗᙋGСCmVcƌ X'|M?#[oYso9bсѿwaI/\r =\$&T ཨBkpBRC;j(kRVc՗m䤡$6eyӑZTX^h* -뱸0Y}T,o `e;Eܛ?t6dȐ',EƑ" " qJ>JhOX gyڕmv#55+VҥK1h p 5jTlPel^4C;!gX+B22sیғjLxn.(.EÃ)jJ{W~'uB$#WMؑ.㜺ip*rw:%^fp6mȑx'q-#@-tKpXh.r0 G}ddF(OK/٭XW_}U“;O=3Wb msoƺԯ@b@Qd2Տ:*n<=:cmi۟`QVt#J4/򠘑< fRH.Ƈnݺ\J" " " U"?W_ŀw}v͚5UoEa3gVH}seta(L{rwAw_p?#=g':Kfak+ X؟iYx16m~ٻs*Ɔkʕ~볳_G'D@D JJJ$&,4=XdxfQi;`9 e,zǠѾpGhu,G&M*{@)Xi7ao{g<<K{_WNlMEyٱcOF:uP^WJ5:#ٳgoe]V= lt O'E@D@D /b׮]&,P1.ڂ֞[67ό۶#U-b-뀏' )@AD@i|h)<@,OybA|"6@^ MQAZL$@BB wلd9ܹsνS0VׯU¨zԾ C01m s2ӑsU|-̼h TtQYlRv2аP c%ϵ{nm۶OҴi$M4 "))).R'sX`F0!}3x kڵ[a5;.!5g|nUԠAPANg2"r%aafMes:jr Sf01#N(m9K4s[Dt&BPoF _JF={Pv&\}H:z)֭,ƍ)""&L@{T=z4effҐ!ChĉUUF`F@#ʴ 2}KN"DBbFe:11QB3S0HF<%%%rC%bPvjxG2jY;P-TSF"~G?Y{-hjժ*l9O?Ie eVV4OKK{wV\ISLÇVƑ h(xcqOxȑ#r  D{A("o۶ dddP\\so 7F͕}_f܅PANG2b\gF^v$D1\ʃ"zA0֋бBuF8>Ei[ݪU+zgeR_W^iÆ Ni{ W?l<`Д+&L(1:1Aςh\|W5hmРAԿB?|t6mք< jU]Çl!ANQ'ǷubKXZ-GoQ+3}7iȑ0c9{=wsPʱ} "XQo֋/(1(::Z_ߕR־}Ew"A̠EMQ4<<_ ʕ0@0"$1Va֬Y4nܸʇ1;˼+@{)d; h).IѻEDRӄthF.ϡԌTPf1uT@y2W$8]t4ƾGry6t䠼["G[)iX3@֒ôuDb`C`ҤIxtEIK+R.[ǏUy,#1dzՎ*BΧ9:K8Q#zc)V(!OQ>jT0_ 4VA< /0m,Xi[Ξ={ʒ\G"8ـO(Z*N*L#0#2⻼4vX+ v4` D@(?-Y7L h4/?2 2-,jFuA;[kP~ QP#ɡCܲeKiR)c:2bc͚54c ާOu&B Jur`j_0h{X@l!&R01#0t fQH.]vbvԬ؟-P_. EFF]搳RV :}.]h޼yL؟#0#HU }>Y;q͌#0H4}JB='%G脨Ʃ-LJuݺuOof5´&VFcF`G`Ok׮ԴiSܹL{wF`F@O2M]ѴN(VZ`)m"nj^L>̻jc̙# M<l`F`G`׮]2n bvU9`$>ApAJ݀Փ:T酟'0#0WWz޼kd9{-g!=_<^//ϧ,=z(uy>0#0A\Xd3| T(]/Z{9x]RV'F ZUZ wϡ'O к1T4RsmB:E|0- 2))f2O?5٭[szA^y啊s"+ 0#`6,WxMK~zJVw^BZ5kA'OO>ʇ.g;u%;K4OW!L* 0#k&&mȠ8m*T o];*u'2}TXX(2`Ft[2!5U ӁGXe]F{<* 8p4sL3ttyy~J4ƍk($X)GPzVU1N޽s|,PA@oiӦIlLF׮VZU>l/''L ]`dmTXjj}%l2<@ #ӑEGo`hETOϝ;&>A5kMMPĝ}nj]cJF&MPG?hRj+U8#:III1k:NSq9Ǐݘ4wuda]dr@ߍTc|\W;vL4+hٝi; :wlL.椉䩔j46Q=ke9NY'fjvAkj"akMzIE\bbb)c A3Rx~~T*۷oﬨCo;PJDhʀQZ'54ܮ6b)w_4h "## ŻjF`I&ɾxtE#-ZHU]c3lR /PSN2TY rrfY<.bWY$,1LSœOi%‹X=kͧM3ߡ,!T EC,/^u ]"#|rۤi.Lѩ4kLbuƍ4`G1 4J_MCI ެ3BU1#`*! z;Anڴ[X(byIkp8QJ,9ZhҙO LGShd0)uҼd,tx}79p^E/У_'ڄt~>F/Bc?C+VW\q @vwRJJ 4c Uqq1k1:^<:c zgbF>0}jT0}_~UE }% +}K-YFsai}BI.$:q֏0iճ*irHۣF` _P=vU\#0O>{ȬZ`u0#E| iJK,SRԫ~Jy('r"mQ==ߙ`F`A`׮]2'bv͞cC+RD_iU-0#`22m-(ڡչ?f;MXBi2-lm өEsNه"k[jӭsaF`F97dF`CRC;RDmMmp )K'"jM~"ZstE+@ FP>0#0!E5uTTu#0@uXBN).wtl4E-ɩA!gj(e5V7eQ=gF`}x뭷hϞ=4yd:]Inn.}' /вe˨gϞ._[UA=UTu?_S,# 9YF_s!矚-ehsɓ"G0Qh]E)T~>: 'PR}?MweF`s͙3G!C5\CqqqbbЙAUVK/D{˗S=4(ɤ+%30RFa+HKI.{^ czz!3<B-5E%a%%KRH ;J3||`F`G|A0`tʕEر#iFXЦMl;z g2/V,1HsΕFfF?g0'MDKFLjӡ;3!C)KD.Cڶ]aCNLӱc(%%E=ZY.]>U_MUiMuj#??_Po߾y***b%Y+B4hЀbmrXJ֊};2FFFJ5+ (ف EMk VѰҭ糯 \ #`K@ ޵kWi=!&F`F2O s>up /SD=+?v3[2p^]5tI]On5}Ê͘1֭[g0tr/͛˙BK.v!͗%LFjUZNh Iqq@Ac:F `Wrr2Jtڵ)""Z~RV-3!LJl(YLGShd01(,uҼd,t8Q/;FPDG>DOͤC'2GmIթSG6ßyt]w9)pxxMQUofaX!ڸqL>0VHkW AL#=W\qލ=}tiдEX`ff 9w-O\iݿyi!u ) o>.B.4JɥKrq5#b w:/ ka8.km'`eiX?cC|'O,+=aK3g#0њԪr}@0"YotI乫0Qk5Nl!95Y 9QM!RYB@*H E˪xsg,qM_RP#eUwH^"=s;DĭOѭ~*0Rohԩn+:^{M>beZ͛'ͽ31#0o@Ya25J<|oXC̬+;Ϭ"JAN-d 1&ieZ A&1T iJK,B3z 4g8oZZsbQ8Qz|P'̤!Ԛ5k)ʭjڭHۣF` =#oֳgO͍]05 4dBq2xXANdTw#Vn<2m-(ڡչ?f;MXBi2]jPqh- izkhsho2.T9GIСC`F` ̳GܝAuVy 2H Y &YF]0ȩJ4NK?d TXBr(qQhߜI-S9s޹ D;)7]`!F`F? N#/H)^f+ 29AɧMG˺'B6ØXBN)Yb-jQv^>X*80-x#M<*9w0#0_.,jw\_,O_eFz,ehsɓ" CK(%=WA~;II./ oQKJ{論I3#0#h3v*7%| )//8c u)jذ!5ЬEHCZZG=R!o!av9?:=ױ2x R]-D+}ԴiS'ES{G6 +SRR⋮ܼL;iKeqhݞJE8]a9 JKHœ4;[D.1MMfTz.2S0jDD>ώ;&&FvBҲeKMZJ*6mJL0 Pnaʴ}n GK<_\ٴWӿy6l-YV؜%\={hƌtmَF` ]#|J)SXx"*AX;F9oW=~t'LOτ* V@(4H>7oޜƎ[aE1::8se>OM4;-kXE;iV6nРwŢGX[$0#`&Dudϔ71rkI :P۶mPq?͛4=S/8=>,x2$\rɓ'{Hoٲ~GΖ{>IHHXJF`\D*,5Wm~`rNп.m1\/R)BBԲ2J[6tiO\G1߈H&4FYot&L {7&pXҴk׎V1#'VD?(dyzĈ죏>*}\eZ$U^U~2(+n9{/\˹=z4%&&:pرnWx>Apꆫ+Qb}AN'@lLc2\79˨+*}W_}E>U iPdRDDShu:l=E5 Dё*Q(oy€">hA7>0Y}jC駟RJJT4a}'2'x9E4FXkJ pJ5R>6U l"ЦM93Q8&xFvA˗/ 6VǎK/i/UUAi~:w^)^@Q+))Ga>Ch4xg/}ȏC ɓ%,w)ښD }#é5=&7w44(24L@)ZQ7KFN`35 H"{7m"uN %BQ3O>l&> }Gr܈dr]v?.QQk%Q̱XBzQFѭZ46)8An{E"ped xVXSSn2#a-ZQ\Έw(}ګ4W=٫U2_0# [Ztx HL2s_ԦvTTaoV ~fKL椉|j46Q3Ú)=5ա1(~@eΜ92c=&(PQ^^?`޻woodY+0 ի 5V)*h R 9qRhE0Sz*ԩS2g;&h޽F69ƾBjmb׎*Az$g+a,+ZzE!<<\N]-C |U\LeQ}ΊV8HEZ<"pfUxh ̳Pi,$6='xv-f1AL  A8.Q8 .4͕?>?x4o\וu`K"b<^+Hw_!x3r2蘆Nq $=R g2f0#PR"0&C K03inHvL-c1 "D][aeZѪU~B&JiqenqFz:]-eش$ K%EˊԥΩ͇F"#5;zӦMm9'L@H0@ ";1Kee+h""$zNA-K ) 9L߼?GZS=?7h 1cTt1."[ d{z韅{-..}qnW.BMkңNgI3[ Y6$DDEI5kмyߖ>k_CuE fbr^^(ӾXUw,eF`捴;w?Zly=Se4o'jՒJ?#/A4`FHeZPDC)suv<Ҏ e.QJYjS2*=7%/1//BGjk`"\'#*ŅRBjа3`8\b)8?m3 1T&WyâmܸqԣG_HoFVJJ{o=vRC6PΣѾ9E[(a[5<|8PZ\sSRC@J8q:D[0+Z ammcDO Ϸ^31* Å>BQ-[I+^{yr W3gʀiEBx1bSOI+yu+^ui1^ 5=ZZabkzԾ ؘ6e@\LGJIvNT R#+jׇ[g >lMJEqbJKhQJh*Z[їI^ٔ9i;/+!3"{#A&`G LOѹZKTv$+ZKV7j?裴dqB GT)?˹]ˤE'0It1`XAYU4KLseRy}u__GM0jQџa!ƬfnKEVlƇPXy?-VKJ mT~͔%4rJoRށ&b'Oqк1T4Rs% MRY+"jl Dy'iӦI~0˼pB Ѿ]`* ߜ HcRڸFEVo³m6cǎ;v-^ޯpo'{7j׮2VH1&,񜛍^rUANȅ 1o#hi+V Fm2ܿ?իP o)~Tn]RW-gw?P@XN%b 5,GoZM)e3,۵kGAȼk`|^hX={R1jҢ@4qb$OG<,O>υ^(s}ݔN zH`;Rb (.OW'\h9" 11g`B4f$e,7onx foKhFM|uJLa oi]N~PW\鲉u'Cn5]t>ۈVL#0#MKrC{p]#hb0KHY%}:9ƍK3L@M6u?wYY0ƀ"c Ot)2HCx-yyyTvm/jK!GoISѣ)33 B'N/ R#Ͽᛐ`tA`ԳgOj۶-=4m4y&M&-[F))).R$Vq(fT1LC<3eq &.IѻEDRӄthFPV~ERIMCTϹ2e a֭ >Щx#0;@믿2}WО={`;ϝj]*#.5b!]R5JjOTa21<%Y),OGSP~>Syv]3!$m ^zF8p mذ2rUB[bG,Պ37V%՞ώmJi;wJ4i/ XCM~veg>QQlk0ss悧N W|z.ׅcU ywdg{ 4|AZhAUViLH1 rÇhf,9hFC B(?-Y7LLкci^~2e eZ(͇O' "|/wݩSi#^ 8\BAvzu:wvrƽuꠡ'7o #o7'Ϗώr%x@DiiiNYyLjE$%&oz2`e 缠я3LPaf%%9hw`ڎQKNSmin`w%!tèq^X6?A)V+NuU#T4(ҘMW32Fnܿz7iȑTcZ`͝;sP} 2`et2SeZ`E$E*EHFB,!e9(EoN$JVo00#0 sFrr[Uŭ 0#0#P ;(PKMp"?3t7_O 8qڷoO1"mڴ3gu'=|vLGZڶmkZnM3f0,# ޽[?PJ;v찱56!MłVLAoᅁ@,$nf_!@jGҊ++"1vLN4޽{e: *q_}܋ʕ+ xck߾}W(]w.yq F0m۶l v\\ڵKя(%+PPگN&;wLT>sw6F~zyS٘o1{v /Bk֬?&OL| -YƏ/)0|q9 z_sOŢXT8JʘF?#!w\=z\=cl`6yM&vC Xͥ;,4i"'fX;bGQ "jT5j$ǵO8nf5kT").BuV>B\j W@#L`=H0r.I] mJHJJ>!i-ۖڛml:*r9v|@EtDdMYo߾_J)xM>]R33aU>FZaD`DZ"r'~2E<]_+QݎƎZ3u8V0̭8B3Pu5+??U`` g0Rҽ{wm+>S!VJR 3N"#&l\`ücXE02ܞfKL> ̼UL֢^G䁽etfذ\Qj:`I/I" rŖsf8^$Cޕ%T9y,9"{Pjy:'b/Qat@9'XxI׏ 4:bl{F`F0}3QÙF`@@@y*c:{D,fܚ&ΓrO&F`F`GQSSS4+w`Fprn1]R,+gE^bVbF`F@o@~2oF`w^ڝ\`F0۶m3 DFFMF  .8G6mPV9F` Go:t..\PzRc"GYYYԢE 5̵Crss)''08qB>_m۶ |_"pdӺ2D{ڵkk֬Y4n8 #0#G_ѣO?T ԯ_Ԯ]+V7۷oG-򖙔VF?J9wu=wqn_0eQK>.F I&ѩSh?ovΆk&#pq7^ݖJoq0N6mҸf`\AB9i"zw]J5bPͨ]̿iwJDRSlmW2O>I?'ӆ }ê>O?T4> ثW/z饗8-𜜜,H}wFC@(%T&ɴ{z ڎI+pBH#8'hU9}OUV~ZT(J6Wqm|&Fxb{Hlb^lAlMVOla厎]4a^;[c-a*+V֜Q)n{(FޙE~5Ugx#iOƍޘٳ'޽VRaU{Qb +Xn֬ܫrX!%=W]&΢ZՎ۾ ǫn]XaGT[Ê"=gWy^ s89,Mxs-9ȏy&F0KП8Ji)* H-$a9Y'T]n6 XnSj1#8Fւ"*JQӨkӄ)v,zշRQh{7RqlZpϳ^gjܳVkA^b5An0=h"B(Pbbb0|J fL#PYWmOnժ!LI1 =|KW8~ lCLO跻u5mڴB5*r)A?SΝϕqu+3҇j&M01w.y>\ Nڵ\#b"Me;Ҵ` jf}3fty8poР9r>ڕ:xacOԼys8:`GRC;RDmMm偉#-Qʦب._>OCCK)UoЖr+U ~Ph_~X=FP/(ѝ:u` ~FƍS$*A|o(ϕb8 r;Ɗ'V+aeUr.VEexeǼʿ]޹HUy4M]JČiYt!!`t\G61IƸq\T\Z#0l'!1eNpYqfny5MCM?l6}%sUu=$?Ƽ;OwUf^h P8sÙq-%hDQ(:l( Ig#G4_+EgUUUg*=:b.5Fk]͔2ǻ3u6gZEY_9DY&Âcˬm2tݬŶx\8F &Ȕ ^!X:t_?k.SI&+${ J 9YoU0Dq*3ogg*qT.YXULZr)#F+2ޚ˦T^w.I@c… f@/2?qG 긪YfEN]3gi^Nxᜭ<*/nѤD}brMEwNٿ\/[W[}l?<ޥ0RݹjP {LqC vyq֥fΜmJ"nJ) <3YnLIVD٦r:5kJ (OQUjinRɕ^JYI>hYXH(l{h_mLQ9e6 pi̻Ѫ5Y* NN?f΂,JZNsus k|v5,nPVJom ,yuhpQ e:;[~Dol)h5Λ7 dtR&Rz-Sv)2-D|} Zu'^ԩS/U3oZf蚡׷~kz,^+2\OL+o93f+4V*#-\;2Xs7 [ d٩ZáZ=~CKk>v\S@iYW^K%1坖< ̓kܞRz;wno!"裏͛} 0Yܹӛˍ'nנM >D ׆rkbMrMV'B/~+ŅClA/O?ڥ>Jҥ c*+WtOur e!>H ;`$  "NT+HS Ò5'|oGVU҅ͬ. @EB@A 3TiL+# |t_mM'\3Rgz~.an{{KqDzbgE{ !m6(j--->j'Oz){' 7 @Sۦ}bOtO[O7کِ'Nz%s B! x7ڻ' rѶe˖ /`~i>@}@ɉlkkƤlф >6Jm}?S[%D @@>sϔH;,!͛7۾}v@@T0\>۹xomz)ҍN.:7G @ڵ+ȷv[ӦM!C}A6 @y 1g6)N# @@qhll sҬMMM6u0> Y@rL |phٚvKYl2gc/}抵N|^p;vX^ @|ȑ#6j(_rIKN OL [mwՇZ+장= v&Yf#J7泏@@R{'lɒ%^ql„ immm㏻8. ـ @2bq/HܻR)K7wZ.d  L`ѶvZmݺu&Sn)~Vs:tRS౗_~+1w @%LXv;윤@ f6nhTf̘Se?[ a H~Gyk @;zKW|?La?k{ s̉?zEZ]o*j"-w 6E6QfmH @ P2:W[S~>i7'n*q؊i? ;?e ?agv[~A @D 5acRUhhR.  @ @oHTy]Q>;sΜ>عAw>} @ ; rfH'Ͷ7u-y=h֓VwNvԉQb]9u]B@ @@&l>}}8tٚ k)kw9Mj?m ?I @ b"⌝6w5dV=֑IS{ @ "!L{\| i4f @ @(rÍ9n @ +V,IB @z ~zp-r-nٳguRUUeW\5ر100@5=i⯑)L'|Oa?kirEksXk;=p;)w qP s˕n얁nQ,,A@ @ @ Hq>nr"iF;( fOL@4l](--~n[s( @ @ H>,3o)ҋflRNHuEZjeA@ @ @ f~ڭ-=Y{:L :SuL&(@ @K ƚL50Cμ@ ):M @ PPkɜh L3LeZ 阴o :@ @ L~jM0k2- X"-eZ4ʴ@ @@A14E ttvǽJtU8sFeA @ @` e:sZqs(k|wfVZ@ @(d^Yv7(Tk;X{\nZ6@ @(dAѰ=s:\ضIENDB`././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/bar.py0000644000000000000000000000237700000000000013450 0ustar00from openpyxl import Workbook from openpyxl.chart import BarChart, Series, Reference wb = Workbook(write_only=True) ws = wb.create_sheet() rows = [ ('Number', 'Batch 1', 'Batch 2'), (2, 10, 30), (3, 40, 60), (4, 50, 70), (5, 20, 10), (6, 10, 40), (7, 50, 30), ] for row in rows: ws.append(row) chart1 = BarChart() chart1.type = "col" chart1.style = 10 chart1.title = "Bar Chart" chart1.y_axis.title = 'Test number' chart1.x_axis.title = 'Sample length (mm)' data = Reference(ws, min_col=2, min_row=1, max_row=7, max_col=3) cats = Reference(ws, min_col=1, min_row=2, max_row=7) chart1.add_data(data, titles_from_data=True) chart1.set_categories(cats) chart1.shape = 4 ws.add_chart(chart1, "A10") from copy import deepcopy chart2 = deepcopy(chart1) chart2.style = 11 chart2.type = "bar" chart2.title = "Horizontal Bar Chart" ws.add_chart(chart2, "G10") chart3 = deepcopy(chart1) chart3.type = "col" chart3.style = 12 chart3.grouping = "stacked" chart3.overlap = 100 chart3.title = 'Stacked Chart' ws.add_chart(chart3, "A27") chart4 = deepcopy(chart1) chart4.type = "bar" chart4.style = 13 chart4.grouping = "percentStacked" chart4.overlap = 100 chart4.title = 'Percent Stacked Chart' ws.add_chart(chart4, "G27") wb.save("bar.xlsx") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/bar.rst0000644000000000000000000000152400000000000013621 0ustar00Bar and Column Charts ===================== In bar charts values are plotted as either horizontal bars or vertical columns. Vertical, Horizontal and Stacked Bar Charts ------------------------------------------- .. note:: The following settings affect the different chart types. Switch between vertical and horizontal bar charts by setting `type` to `col` or `bar` respectively. When using stacked charts the `overlap` needs to be set to 100. If bars are horizontal, x and y axes are reversed. .. image:: bar.png :alt: "Sample bar charts" .. literalinclude:: bar.py This will produce four charts illustrating the various possibilities. 3D Bar Charts ------------- You can also create 3D bar charts .. literalinclude:: bar3d.py This produces a simple 3D bar chart .. image:: bar3D.png :alt: "Sample 3D bar chart" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/bar3D.png0000644000000000000000000006716000000000000013774 0ustar00PNG  IHDR( =sRGB@IDATx |E !r99uV[tUVWWXQ迷L]Qy|!mߋuq|V9Wy[l\wK/u\7glM:la{Ll͒䏯b~=XVV5Ġ^SZ>n V.Ҷ_2;fՑMEg||6w`bY)hZrpzQ[mv5ҊѯdD[K6|']&Rgʭ]>:Qg*iwA-Pq Ni&OL?FyVTNQ^Hv~Oj쿪qGW_Ig"K-* <Wv{{G*/^oSڮ>Q냃ݐ٤øY(8U,fT=_KO¤]nZn^/ -S򶑃"Pzu&SU檪LŞ]/uFX[?ZL~ȎƤ;uj[]qUT*Qc\Uؓ|07bӱbOyB j̾(wx6}Y;> r4ƺXbK*'qpQZ(;z@M-=*yc\_ؓ|Ե_abڸTPvXbO(9{w翱QW(>ݫ}vC+}m6/cp翕_]F[\U]1mTI^7_OdCݘXy+y)PoV/$H~+_}dup4Xb3T=ɫ7oceO*JUWUU^SqhҬJ mNYǣu^.ުveE\՞y *]\.2mȧPdlF~ῳxeU[3CmiWZH>mbߝ-hle6+X%v,_n _Gb߿r~[1evޭ[k_~WNx槟&/}|[ŪL+U7:J}+m.˗߉ rK0Mrj6T\+;ojq [n؇L;}T>@iR*nH9C S]u㚜[ߧ7ڶɶSeLBǗXW_b_Uj⿲]-> E%8$kOdžfys|J^ʸrj9^}W43l#2cteQJK;qA0E<8_JbGpzl! ʜO)UHZlM˵y7僞aWɨ26Ι?Ғcbf]|6F}6_ڀڴRaRtXeeNW*vu<=Jt:Vu%VAɱn Wt%6)c}}ǿ/h7ĺk/oNs)_O%^ux=PF}~Kߧ䘨2k~6m玟*{'Sk7*6mƴ;%X"?[o--*6 W)}Jt:/1V7DmuCKsWbeʓ]'qhL)ՕW`dmqJ樿~/k|Y;:Dko_ʔ]21(OF] EyF^nF\U9b{jsiKJm6Pd^-8t}*,6}G>-Tυou'<穼>_eYomy9XJe\U9֕?V7q~A\zL{~~Vh磈xcCț_ XWm)UZcU_ŞTo(T__Ү3N.c0Wx89FTb=ϥ.{YS9e㊷o)[q8QB˶V_7ۣt\f9ʤk_l'ׂ&'rh pę;Gc|mPyJˌƴ'iw"S%ؿO ƈ+ E]QxH]lyOɩXrv'/ra .Wyu]>]R\zH&&*8v;]}bݧj>eGFISJYKvS~s)][@-oLլտ*r_Wb|lvvvSr*<{ۇTUQ1\d_^qTuvU,ҮD[]15%OQPB%mTÌntǫ<>&KZif(*VyNr"u:Ty@Tŗծ1m<.޾߀?.כh~]?Ǘ!#BҞf?\5dT,2ƴ:]7~׏`hRq 6.ŏg>*J%SW1mY]Yq_ٕ߯@;oU]jSU 8|Ufcڕ_5r_H[ϖABrl)Ph]\2]\_;OTۥNCSQKk ;ӘVh\T_X 1jPOd9W/צTg*ST2u%S:bⰚ 1Ob%sT]*,2HjvgomRy./.u2Ș6Z_+*Հ|U5.WyLX#)#WAш;yQ_z"Iq42R\f?*~_ e>Nl(>}&o7S'-9f^7۵:"_9*_{楿sPE E(+<\We}-7ꗹ3֗?K}sup+Sɦ1cʏzk~i?\znߓ>Q?Py3TՓ.7)]K0{]^f{Z?u4Fkueaמ#z'}'ys4c.cTfy~O<ɛˍu%]a`Ɵ7FTY!`Oxoo7TWm{7*iK% H,/uVI[J^>UTlGXXYޫri71cbbvK'}'yss={7;$;L {ޑt9>G}{­~{YrQ>U1oon_/3MϿج1q<9! B=zc,>{ZNDBf^y1ެ/Fj^v 6ge碙fWuκjWyW:yo' Ψ3K=DNLɘcJ+JgI|[72\[(^kP՝+J+>ږj_T(tH˘Vy\+op؟syF1ٰ+uҐxh7rT+ߔc/w-b$9*S{*NsTVُ]e [PXշ뺔=|mU$ԭ[I{#+l/ƴͺ|uܱO[Am.T;os<巊}Sz*7%-ROe*|c 7ۑ*SW}kθR_15YP$ŶBz"KͿ`Sch,Ga*XkێI_n/JHHHjHj14r wl\T t6wiZBۙ2$[5[YFBehHYt7x=M)voe    O88Dĵi'sf`Gū0˾=uX)xk4ې}oVI|-S4q<9w]0F<17J f"`-XE%3E&   !8HZᅯ'=8RbNqɝq=@1a7Gx(3*u΁)/޷0L{Qj6E|6X32bҦ;D9ҳ}e&S$@$@$@$.0mPK-qxԲxtxhs"wI-Ҏy'`u+0A8b/8'J(PLM6*Le<$   #+2c.>0#fx/#P[w01 U%;߂ }_q_sM$5JNˀ1ufy! $@$@$@$@\ya;wtѮG̋;#4-|uZ^- jԜi$@$@$@p ԝnGE=Z+UOgIHHH vmvWj߅~#N[GB6HX4(+&fj:ǣI&A\}wvG $@$@Vp38؄4/+¸VJ 8T%pp+S_qC[CD-ܜUk3:ޏ7> t1Ne$BJJJaÆ9¬YPTT $@$`=ח`famڑ⮙1 u2m/.ZpQR] %͚8g1As.IJK%&o,I ={W,i= j  #O RcQ̦Pg8]s(qnFB}pP^^zKwcU  =UM*{Dżc{4T lm^ñq I^bby,ƪw.Dxo_qGJ3XQJM(o?|gc;Lu5(,m' ĵmG/ai;$;(~* 'i 2PT>c  k T\ W ܋nѸS1罶V:{'wsX}'6D^}O^WO_c ? 8f-x+ҿev4ɧ_x[6&#@F[`Xʽ۾)n3x.oku5G챃@rBgK$'y@q HPe XN`ӇjF(Z Z-Mks=1:,ĒGPS&M 7,bZːP֎f~}e(pҹeGĉ'h92Vθz^W<9w]0F<1oI/r."1_U| $@$?J㥻㴻zco1S p->>jͬζ#EQ=p@{ JgnK[&ZW[p(faκ~^z5b5;Klw o M0܅z(KLο"v ^>߿Kujj \,X/)$L AW2gFq[Z+|#{}~6"aU\m{_F+v'hV[Įa` ^%NSBRlX{/z]>N.9[6JKϼ{:?՞FiN 5"Ҧ;6?CzdBzXV!7o[f̘TZS:x@$@$P#A{%fΖ@<4[I-3~>!O+'LH-2=9OVM]H1h"KyK@Wbo뉜jTCY &A*,Ц U -n[_[ߌGiJ'|o}7?* #>!;>XhW+J&GAL8Xj+ӆ:4}tTQFzٔ @̔)S*N?]Pe   PKʠ@!D28ӧz 4H8Sl2|w`@k+ A⸸HH B OvՎ[999 Skٓ8~uyh:~= V0oVc ^RŊ+ ]F|87Z'ع  t…]RS[}lP>[ 3O@--'6FGEӝM"j, x_;\?橸!K#lU/]qUW-k<o>tQ_T|r`$@LAi&g/b>0cIG оX#ҡ!2BB&N3ݻwkwj{] =E+<.\D妏۬ Ν<iiMѩLt+z Ѹ3'[mu\˞.c64.2|/Sl?ÑZmzhߌw1ȁAm W  dffaÆ9#%IH&\~OZţIBm/DۭG1(݊yS>[.C M|D|4}ڭ=h+! 1#7#gh<+&uIZz+^>Vd܌MrƴU-1xى8qmHF8GC}jkm-&ibJw4T^X?.)HDa0k/D"zsׇfm6$p xfqj]D{HHH  8 t:1>eMvbC dh MiVg=^8l"Ԥm'k%دT-Daa#]ҁ1mZ 0x/Wj" $ԁYcjw&g מTԞ@1Ԑ@^q~Bp=1 MjHHH mȓhe)lY'>w}AĖp:@*y 0h/G9n^GCq|$kÅ-xmWL\w=;1魻ˆjF1ð%&NǛ> [j]=2䞢4m 9m0~Ƿ8ܬ/ v&7`Dz xpt6ȶAґlp[Xtm tWވxLWɬ~.~U”t#.iIC*sE˘16OOņk\ FϠk5vٸeީړ8   pCyp BMhSx qwn>i +u m1P *!kL~RR,6\Ks{4T_/!Sκ\#1^>t<>Y2H mhiGz~_l %6uIޙ1)hnm9B B$@$@$.\e'#+;vѓx}9b@Ԧ#    "A0hxt}.m3ĺ=xD lHHHH#3eʔO?: D}ZQ׮`24ZS)ZOzaC> L$,|oٍܮˏٺVlاNNG͊atvgK:`+E#/݄M_\ j'݇P8°/qOi 2 @ecL]{m/DV I^~kol݋nGv оiVv~ͺImpX>o4'Wŗ,uO{pCwOjX7_Eá7hc³q!A+D }G~A{EtNH8('b[jHOk D_?oA\{b$nauBV#"cXK>ÏXs.=;1魻ˆj9k0# ;k'؟ ,OB=#̴TjD\ږqXDjHHH b ؓ xeś8G'hᴷى8r$ވyh=fѦ_TMֹJI@Ok!D3:3 ~őb$f6E~ެKM$@$@$|B%# x ƚLv5#PlN5 DQ. @M رjja=#]vi2IXpH@4U! 1SL8ӽ ;wӍIHHvl۶ GE<?9ڵGA xO ''d=/o$Jɐo滴^H_ M7݄'|y ?222,:u*ի;v vK/^xp;ɻ;xw#v?^PJll`'*`@nݺ5 ~ɓvZ̙3a;?qȑ#X jDS}pP#D$@$@$2*** Ν;?BǙg/#Fp.s._=*HիѾ}{:J;_RS1c`W[f 8 t ,@ݺujSN9^z)}Yw}`$JJJ K v(oTF$@$@$@LL fϞ߭WwEAoԨBqq1|M2diveeeN>HYYY81}tF.ӕdLu꫱~U~@ :>xPy*^ltDO>D9;a+V$OdH ppDIHH 2EaÆ~\}َ|ON8;vĺu<,߷odJѣC?F>}PTT{G'A^9r>I XQB;?y:ҪU+Wzލ7ިO;2 4s=W'$2XhC{ux"O0ڵk 2gl)m#  #6l˅qc/ބ~A\={`EuW/Jĉwf͚$O?-YD&$/H?[|yAd| qU]y!+ټyuDʓ@ZFIHH pμ$$r{uaƍ>5(o^y"55 E2@ 䎽A:TwF=rB Hd,*ˉE;8Ȓ2_V_ O]yqjO!99Y'/NI-ZСCUVP 0>9Ρi$@$@$/#Ҥ7AE|M][oU+A^VA rw^hl۶ 2_^(v"@(P B$@$@5$ ?|yyd/Y5Hƥ>2￯OG2`,6-ك@&ɞ 2`MoڑuE ~.*U)OfDzG<ݜe'QFKAvoS{W-*4˲guO!C B$@$@ew߭?-mᩧrdJC򎁬/+ɓoc= }ykرc^,)F",2 С䝄+Wﲼ<5fbҤIfcj1El;|zj [aݡeC4WAVkb P'=n[Bΰ/''G_9qc"Skō)1@mi,r^ h)|^ddWk.}\{ڒ'WV@Ԟc9 XM@Ie]Q5xDD  /2-HРA&"௽B8 }p w%@mdJNl"w)HHH T xs-d0x2h"Sky- ; ?8zK 4"ְ|#o(M$@Aӈ"DiD~&hpQbґtH%iDޒ xOӈgE&rrrB0L42%S X1//) &F4g 2/UF/VbHk<(sA!yxs-vyעGL2h#Sk[bmj7lf#IuB7קVHIH?VN#$av́;wBtauw4ic3F  VFd;v%f4Ӗ'jܸX+xB$@$P{ϟ)S 662-hQӈX^S dgkOBp (<-p R @EE&L/111߿?;<}Muf٦fVNKre3HHBHAYYoߎxU>VZUkq@J$@$88~$@QDn!OnO DS{1++/B IH Ć4HMc͚5_0c lذ!d IH $ AHv " D}2.$!33iD$ƝIH Z &Zio @ѳgO;EEE޽;ڴicq+CH$rTH$@aE.K$y)Y9SFg}& 88pͅ$@$R,Y IH pp]HHHwj5"6I  E\({6 @ W#M$@$'999ahzhLӘl@*U @ZJȦ9 djOD$Sy[BFd!L" 0%)9Υ$@$-HjS3)GN`Gnء-Mɟ&M@'LHBFԴiSto H r4>>h|_zz>,% Z%b 1aL_6m>lGԓ`jDjZ7IsEyN ;[{r^@GY3987" ѣ6oެꫯƙgm/((׭/$Z% &Ax';ߎ^z IIIn˲x[%Yv)G$@$P{88=lH&dΝ#+Q^Dwpq`P-n @ ⺔ D"S; kFAod_<~EAk XGXR @qq1-[ݻDRiDDd{^4J X88t6DBTE$@ eȋɁ FH{֢5ŪP=-8 *JJ! ÕZIH2ڵo>"Hj4~F|S^PAѡAi K$@$4"6I YG0FWk60Fe. D("c TGӈeF$ rQ.\%f @4[N#~W$l '''F|{dj})ZO:yyyi^Y4T4>5gS:ܤSf$\K4:L)Zdj=rZQ PCHݥ\r0<)$@ӊ|!JY CV#Fnnn$jkGnء}ФI88)5 @HPO d5"+F}! !"vD98[j& KO?~ @d(--Ÿq0gdeeaذaQ^=E|AAdWe" V<}  ǖIHo֭)|l۶ gFLL[LvU74YHƒOH J ƍnݺx''!+Qt"yO4". /·h9 @HIIA˖-#nܸWF.]} m>jMl6+hײ9$@$@ppIH6 oBYYwwOaSZӾX,/-£h,*tA$@ pp%HH4l{/nl߾C6m,G \H=-X)r{]), @ ppPsvI$@A!0h 8HJJM~W[n;#| 4 Y(sªMژFTQRgL$@$Ǫ$@$1HXLx+k_Pt`v& $AHv " 4f w '''9.!S2u򐝝mi 4O~؄ u7j N#rf# 7R@6a'Sx&2'ZϳzjiDs!C ,T:ؽw+ͧ. \rZQԜtH Z iD7|%dе#7F;]fnC*h@PO-nݺ(i16J$@$ynm۶ EIbR˗;'~":6Oly-6G^~ace GZZ/Ӏ޽{̭YvڹiIKY uou[aUVa?0-著+$^|E뎼3g_#A0(  ! ,^Q{Xd 3&f2nVV1tuӈ|V $@$C˖-qݧvz!|(vv8p ә4i^yV/5 Kp_Q@t/e:_?-40Rݻ'|>?t"Yf7@pp(K$@7nڗiNj4 ._Kd/%L$ :7vyV3fwٳQNԫWGu9rK/CŀpYgA :J,Npp`1P# @HHHZ]Fd&i3=lE#D[IH1oyIM$@4#jV쭷җZeN8^N \i~,M,PA S? 0pF$hAP FH—}0zhC_H0`}l9<  DjQ8ojiDxf'qqq^;$y]OA}p %@mdJNlPmiiDחl@C %gy $@$ iufuR XL@6y+U-@XB֭Hw*.wp[7 `U=kI r3?ʹ%/t k@ uXHH y?ޫIAAAlFdŁ'Iy " %Av 'G pgz)]v\ȫiDVMK j =& 9rDe˖9s&dͯJEjj*dL#UOuIHG5[" n<^GJcn>)RՍlb$@صv-Pc2ڵGӓN^aA&I$RRRp%讗GE~"6I ( *'0 0p,Ł7Dqq0%X 8oNV%jOmi끺k=98$ @ A3 TiDұU{!N%pO %,,),.mS( GoiSqcpj*L82ET|ԟ/Z?8O?;ϡ_DRRƌȓW_Ç[,r90! D78@QaT 9wd0 ~);%KKR?C{d_~%$]RRIVT, @FEI t9M2H1qCOd|IȂӱm6}N:ǒ߽{wlܸ 6D1yd8%@mdJNc^^^ӈH$Pۉ% A1dC ]ysZ%z +V 6m3"0a6;묳pٲɒoA`OMdj-O2^5jDM64"kR N HJ mIȦGF=п59kpwbԨQ8pƎ4w'a͐Eƍ]z)yKr$@$ՈD32q!GdRI$"@Er l2w JKKY1h TTTTrĈ9cbܸqÀ98(^*'  ̜9ӦM!ѾFhV#M$rsjdL 3n߁ s kB}p``s9f"<& "PPPg}}>85k0bwLw$jD$!{CǑrd7~˔h;)>omT@$ppH0& &0 qT(?K -6BFhqK$@N#2@a'jOiDGJ$@::,# %XIZb[srPF, A?* #504pбӈB/h XI@X4dji@dj=4!;;:iDEjOQpd- |ᣜFpl Zxs-dx2h"Sky<˵$C=ȦfF8Sc%Ai@ӊ"4$@N@͙3C Aƍ! 38b6rYe61lsp]GI3o;$_q9r׮iD7|uT2˷Wh::-|Z6Q-_o߶q w h kqp8L$@~8z(&OE!66}ŠAQӈ䮬\"ۗhO$ ʬ)"GߎoѪVwg޳'tǾ@  D1|HH)ݻ~AA~˲iD20FQ|"u !At5%G)))hѢn9'$@H7tzk6( 8(( B;h 8X`{=ox7—^z rEGFdH! 0%Av&{.;g\((   pp`9R*$ " ӈ$-$@$@Fi0M$@QF@M#j(GwIH pR:D$@jDq D>9ަ$@$jD< HH999ʙ_CdZCpT#j԰LkE崢0TK$d丸8pXH ~{s®id( p&o>uYX~s#5Ȫݎ>c˷WhYQV/wמjhy->gXl~޼9gΝ;6:t耴 ppNIŠ5kp-@k%ȅ/p7-)nE./i'k㚂5eYMFD[< ~={I'u)hnn.ƍj A -[0}t\pAAA~˒PAO>HE@S1c  8KmE4h`@M#=@9  ̛7O_ nРAV> (" p% /祦OAPSfv H’<:u*znݺh4cf  N# \pIEFT{98=lHBFO= ]7)g{"eq뚚x]1SIEͼ`(QDW-~ ?6 ~%baB7$xMT% [s~<zfvf}`gsg^g=#bR66 # \\@';"Ay2lG@0(33c!bw4FY6q*WS* SL +ʕ+n%Ʀ$}.^(x}d} ?ACB?t}cQ+5L[Z4O@TIԿ?P%j~aDzd~zPIricML&߁p0 z-Ñy}ʰ"$È>8RQ@.]$$8GNHi;wZ>}\dnnnTܦ[nQKf@ 1hlˠ <@AAeggۖ-[h/ժU+bFd@0(9?Yo5 sְaCwnON:)gٳ]@@x & #c$@˗I&E6nخ]V{'[v|]7t~[A{#Ku,+++`~8R  _UTv~~5jԨOZje 2ϠP|~?>d] ( 0!9Z1#qh۶kVQGHvڦR_5Q$quTz|IR  ;cGׯ۔)Sx;FC ;0%F)vyyN1 891@N`РAn%Q Go4@"Tk @ԬY3A΄@9ε{C@@ (Ȋ  @u 8ε{CHIOyfJw41{ς//~=U~Mlo{=ꫯ>+;[lذlbGL__~zjk׮cPH>{뭷{u(*W{!PI0SVTI\vC,՝ׯ_o?=6{lkذ͛7Ο?n/p=/#GMڟiZt0c7ntW_}Um^on2դ[haq95sL-6kf ~mNz[b(((0=Eή^j7uT:t{>ydkҤ=v=Wԇ֭[۷~Ǐe˖٭[C.hfƌ'&M#FN֭G-a(@Rj<|M[v?5Ր/mϞ=6k,׳p9zlΜ9ߺ!:J73V\TgvSN7wR^œz WVnn]pm…|r\ ۷Ϲ!//~7w}צOn?z>+G~k\2U裏9}Uv4x`۷]x^{5:u}Oh5}dvrTB ɕ@c@pK.5 Pݻ]#(4b}!W`ZZ=scCjjرÆ f!s S={K¶ml̘16w\SNs[ߢ 4XWwU$2d$hP=`8 4_l7onK,ѯ_[˖-m֭nz Ǝkj w*&iW~zk44HP`1=55[Wڵ]N /h?>=Sֽ{;)P6GPozի&;ozrZsU+'!4nܸWN6mlݺu/lQWDhRUs 4CIs4H &UOƭWjFP^*=JUngEAI  '(+M2Xjk~z3v g'8@G5,Xp_]H ?ˠ$L TI]F~K~iFQ4HWO5u=*{ op5zIa->W˳ӕkVk֬7na0O}vMPV]IV KUy p S?agŞ(@p{FX@ s{Y*UMhH w+u;C@WN C !Z8)@@/@ps  @B $dpR  _ @@pw+I~00ԿTFF) @aR.8H$=_YLz4Lj" ,}:\$@ӦM-''ǎ;4 '+>1_b_oZU^+IaȃDhٲ1ԩS-LF4Z1lmӧOڅ @jղZT3b*tFLCSΈih*[wR D@@ 98k@@ x'@@@S 9덳F@@wR D@@ 98k@@ x'@@@S 9덳F@@wR D@@ 98k@@ 䙈KIENDB`././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/bar3d.py0000644000000000000000000000107500000000000013671 0ustar00from openpyxl import Workbook from openpyxl.chart import ( Reference, Series, BarChart3D, ) wb = Workbook() ws = wb.active rows = [ (None, 2013, 2014), ("Apples", 5, 4), ("Oranges", 6, 2), ("Pears", 8, 3) ] for row in rows: ws.append(row) data = Reference(ws, min_col=2, min_row=1, max_col=3, max_row=4) titles = Reference(ws, min_col=1, min_row=2, max_row=4) chart = BarChart3D() chart.title = "3D Bar Chart" chart.add_data(data=data, titles_from_data=True) chart.set_categories(titles) ws.add_chart(chart, "E5") wb.save("bar3d.xlsx") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/bubble.png0000644000000000000000000016411100000000000014266 0ustar00PNG  IHDR-  iCCPICC ProfileHPiǿɉ40dr,Yr(* a00Wp tDU (,*Du1 **1]ս7W@`1w'zXx@gx~~oS?f} qvL hv+HxtP<.7DžKWqq8#<@D V2q.۱l^2g֎9q63Z8ɌZI%17#9IHskF*1K蕾as#xYifx- 1qg9錠EǤ 0V 9XE\@ga/j ט\Ґ䱤-L*st'L^?&]XO>|`['\7rA00ǬOŧCgpY&Ff̝hZ:nHR͢3w.ԑ;RPC`" eP@fl ɀցM``8J1pTFЩ-tݎBO`(a00"L%s3biX-Mna[alq8&.;;Í>Ixe E+>(~ F X| l^IB3.a0C'jmA6b1xD"H$)TL:GE"}!KuH|J~D@P4)J:erY*b al)iy+Ju]#)Z$zAALSY)ET؀ؔ8UXW>|X] ||i/`)#6t AOm!!!!ӡ.aa˅s›"p!S\W\5iٿZk՝k$Vt-s(LThoL_fs*]=rfba; 111cqq'8Μλc ӉgBQɗDn{R^/7jz0uůLV5K"FK-!ʰ(.d݅6nصa4-荬mT6m4qshKj[sdgUm#nK{QvAۛssrwy'Ow:G;vQ~Qݬݷ6={=̂> y=Y!!bV_ԩLlWGk)?8r ͊'^ 9/ՕrOqO VTW[TWV8Ԍk\ݼϸ"=Jzq'YO1O=+z?/ u|d5eo#9(FGLZ{^z=ff"O?j_]a#f ۦJ43Ys/_CάV]{OgggyL>s ccx J8T7E|@ ~񂇞sf0g M[8&$r0i& HW~@|!N3+hB ǃ<-;,`w@IDATx} `UŵI !$@i@HTDk JD+bx"U/RPA+W!1P" H 5{s9vLA߾79|2Iԑi\s5*}رK\}˲2\p999`} ٺukpXe?:tl`Aff&.];FaETVVzѢY¢[n1b楝GVX:SuL#h4@CƬm*GZ?lvT$rXRNV"&4 :uR;]Ye4lqNqIك V[-~)ZJ ?HGnj1cDq 3F@#h49>9"a>).qm qM¼{.b3P==Llo?e3 ƪϗWBx衇*W>_6[> US=7>5JK/>O%WٺlZOoHC?8Dd”|w7i+-ϵ5])v\wŋb]UccY_]Է>wn)S_}DNM镮ϗ^1?Z=^3,Ávd8?TUqqrZ kܠrđ|Q@oxvn"[Qg^!2ϜFa?:GEB1`Y#Z뮫>vW~bWM#;8zF|kǯzڮ_c# u<8swH@wDtCuo.R mR[-ӭq괧t4Ӑj~@*rJB9>v.Wl\9B_[*!W#A[Tԗ~bP.dctAy2]˟</ ˳dϯ&m!Ҭ}O4vj+.}n.Cd |kR_e!K~CO ?v/FJB9WƮϗ_PѶ:6mk|;/[\sWyZr/>[u[|fkS[~[(i5|Jc\yYjK䚝>ۂI`t~nrZжm[82!_Lu~^{}8zDZ a  r6q,yX+lSc,"5V5e05 ^"k_3f5Ha9L1D.Q vm ~~ϝ Ҥjs}m>ʂBbؤV!ԣ|4 '5R[mRw5M>%~4KK^KCo3eM#ѽ cf> djڄ#۱\Up ukbO]F}UYw(DhMםnҤnZg".mn 3mKoi쑲 U'8ގ/؊>]6=OY, ;,< , Q?rZ8epɔ=R(3 @Zjpzi_{oyd4S7Uk13`4uKu#Q evkmgW)ic^BnyY4S M~ѓ*Ԛf哸[=ɘhg{͉pR-V[e9PVYujߨ?zH$ѕ(r~' u eNk^Rw m܀Z' H--WG\^K>;ʣhʷWlbj5n/Vmx֊*]@)Mש7F )/M4о8VZA`ՙԒ~#5moO ńɳ0:.4%S8` ?gϛ !_ǽcJh/ikָ9~E߁cGEwgIP_췗TF8SgYvàfZoY2֦Y#O_|FBL96mKǏ2v Glla>{hzN:D= *}|w;I">UTj^^KΡ'\θ!6%B }mZ!0S0 yWM!z[}9]fgީvi?rrrCrTg%?_l{Tlel_ufM p?ny9HF'c^sߞu VF|mhH6?bu;&>5X 5XQ\GC_"|Bqq=Z?~mŮ]G>-PYFC,C+ ֭/ǾuGZNN<{݆' A"U9V 7T]v}P_|o-o{l&o]GI9JH)$[>N4Svņzoa.aW唲4 z/mm b^5qV3,ƁgZ=*S I1%b/Z:8RKPRFHS Ҡ|-er:Pm`f Ňva/=qݍ.؞~1]7Vj_1Y1!Ŭ IY\n*M,r݄b|)}隟Ϙ/FUޔ8Wdg~(0_=[ al)6n ~ /2*KqaOo~e5@;yUjZAOZ +pӀ.l#`q\gAleAtgʁ `Iq_Q**2u%5w(y&N}hUCE7_o C=jw:~m㨤ME80U5 q6g$^_)ӂK)aWtS-x=%hF|}WG=Ol<5gՕpy[y%NY Eaƞ ,z}*~F5הHc.%NP_9B-%2|WOgX$Me4*|BE\/i2)PԽMEF 00]tV28ɇYq bPNƅJ22q+)(5 _~Rk/@-XfgǍ8;i 5yvxLL/y5@;B=pKxؾS%Wmn{B,{`oaYXK\=Alt.+i"G(XRF KP{OVWe%(.wғ|JVy/4#ԮU5ll绫Cx8OL9pݒL.e`ǥ~3t`۾l^^r|jMˑkik︟nw=5W! NmUOF U:(kS>؃,I9B5^MwU5~?@ơ#nE=Vd iJFVoS5ݓ~wz*/Bur]p6GG{IB9]]~wZ$y5bg0Ǜ*YZCxx:v 㢘P{~M 2x5*m%npa?{;rp~ß΂+`}bPkZ5H[Hkh-w)W W(ƕ?5|"(D[_R^njW+ZkUҦj:{I`[q؉ԓ\Ұc]ݜaS-9q{Ioyv^wBVKއ}h{$v|9N!?YkbPγƭ [LyV~Mw[w*KXta9F0|N{: [(ƫI?d^S`~+M}ζ~QG k~^Z1 B (ZҟmHPζm[~_w+-WDU(Sqݗ|Q1), ywum*[~-W(g[6z_*[ :N4U(YR]ՇWT_o6穪@\x @DDHiW!:QyzŔ=4lxk+~;f y!OiC@Rpǽ5U_{}^&`k篹F3<~/{ZJ]%`Bu,)j"_~駂!k.qD˗/~{_z->;(vCCT_rAf=^.VƼg.V.c~9XjJP3H|'9{Ig=^ޮ=S} koϷx sףk(z?˗k+XC]귖ׯGK ]/yV9S_)Z|L>2],U)QDڵIֆo-0ąڍ?Ȝ)1`ec/pLʋ?/dr=yJmwᘔwƹNǞo>R֓=F-oᓔoH/zy\J$.2 Y $gϡ"Cʊ]v{PN8SG~=Q{y85\%Oen!!Wx".:/8T3K'HCv~)TJɾۗ .%qӔ>[7x39wD]_,Klb5Ox#q*O#vyR)[ʣB1;o߮4 `籧K뎒CΈ8,"N1.M J+kGicH' kNbP_KPr?t!3yθ4F` ~b*qicsno%6aVR2Z*21|dXޚjɭUp|Z svBuz~~fئ5kfMi^5pǁm>U(Ir6#$ c =oȨcM;'WcIGG;s|$"o0~Ƣx_} osXb\pNaMw=bqSv?El}W 3Ϭ7.œq(Y9Yغ S&#Kc5@;\ٮV_H_{ιiSwQ[Xp GǼRK/T?7o|rR[HļypZ^`e\Y߈WLq絎i4F@#h bI w`oc+ P y9~g @Gǡ0;YQXrvGψrdAdP%N!l>|ow/h< J wqWI6}g[a @زt>CS۶c6.ٛSa6pI:X2wh1tۺGl/,D'نo0Y[vvpw"J[_,PPN*VXV8]z!&CmرP} iU6o&Х@Jv9˜ev(trg2aC;- ,Hf^:,8]ozƮvey0j:Tk"y 5wmav&4b۞28{q >T>^n;1gJlǢW0g=Ց{cىjPԞǰu..k0}}֮F@#h>gZE:#e޻YйX1732d$g|pqYÂ=4 4(q4rLaoخXkyx"CiTGMȘO2Sl_=1b-/*<}"1/bGH!طS !Q~J׷~7c8T0=n'q XidoJFPX$&AנQئ?ˬwrǹH u;c3~lc} 0-a9K-J[8]c}1<.ݦ~6M<<;&q]J~b/ X3<.JL@lן"+<µQ-XY@<V6OۃkFLPwG"Y[OX|qşQANob‘-Yq-³-G%[3M}0o85j2056/A- iuF]w\F@#h(n_V2W\+~۞1/ŶNy">@)c & _2g`rYC޶xϯ>Jd/ka`gDS08,JWdo@SM0u iOW><2cJ6j%(q 4(Lˣ-2*\eK ݳ\clĔcEXu=؜LR*;K0\GF=(emi:~^ ő~|öKS4j^'Y;BEc6 SpLJ 7 Om:%!bIt|y*ƘmGz˱Į1=dųSq_ՂogC-gkvݛ!aᜮ?gzIJrM] f#^rbc ˅@bշ*>}L`l>F]/L11Ӗ}M3Q>F4hp*ӗͽ-Ks2FӁt7qv`[ZrX+;B>cdrX81u[!)cqzmX@jjQӖBPtCF݉Gi]8m Sl׾?oF@#h4W:-[ؠX\,&IaO ttt\wDuM/ mw(4yd/reYlȶ(ݤ((.Fyy9>qVT5s^}&? qc/=a0F&K`8?yŢ8?hk&Ż0gG;ZK'tT(0fyrvΥztO0JEh]@N\,k(]1r"$ĥ+hQOCm.!,;fW}4p ?M#},غ C5t,M%!x6&.PNmMmUX -:ژNVaj^;?ptF129_c1uS's\ҕ~uBF믿FϞ==z`ͪ?M4 0a=0lقÇ~|Mu];p13{I8p ^{5h4F Q_UXuy5-7y#zs:BOy!dZ?kRURlt$NM@^4L&̀"(^;~cxNCY͖&+2Al*(̣'7fb52`2RWAmprbuj塡@4[hv'JE=q 0k?֓Zu91k'IxRcX: X^Ys7b|x0|H:l̙[1cQ%u %ש~1T'#!"wl㲎mRߤ`&7l]B&n`KN⫈45%;DtRӮ~a2S2fc0.$}ǂY?ĞW$U%ӌu036}Bi -,-N9<71C1F;rsDjC'ax`QZNك v*IcɨO7}~^'Ǐ+oʕ+ѷo_,Zbܸqo~u֩hvHn>|_|6n܈]vaxV}=߿}нTF@#4~&;$zt nRsYxg}~E׋/,}ϒ Q0ۀҋIr"o9Wy9Jo wk(e`4t ݻQg~栠mC;#b4[N89r1'TB\x='WgWPTM_d;9 VSߒk1%ԯ ][p/P#5j37ժ5Wa<l u&B_ZHMMU `IC=9s '|/a^z `%<ϴj =J馛".. tx umJKKSI(((gkF@#=ŀ'N %%G!Abt^/чPOIK}u UzHe]zy.S ;\?*CHfѱ#HСէSNܹse`r#]v* ,ȑ#rY#NNTTXFKYYYʌ]sВiIp4ퟘv\|:-A#h sgGE0ҥr$#눓gNe ރ2x`?9x2$!99N;<|F@#`k|ꟛh4/bxyox:w%&&PPüe&:XZZ6m,:#׏)_^Mk ^fTR~GN])zڹ2|Oż,dۣNw4ʚmM\ dm@YؐV߳)K1+yQnUKaQ$?p,ĶПR|5m!2h3G8̲lV m,`Eu۪"{꿳gZe^urA갈J^IcjuXdXu\#;*ťbo.j~8v㻜V8t>ߗoWd׋2rs6g_T|פ94E+ E[l0_iWk{;uc-*7 2~"WcN~tٞ6;&nm:<<$ArʰL܉bлizaC L%(ZbckI'leyqһfr{aŠdk!b:{kӻ1՝x}2zOUBWL?]F@#hRJ*EQ)o66t9ΗY*:cʁIaI%W!Hp];GŨ4-NK˯Q3sg_aOm|a ⊚gQ09+q]xkʝ)(UkIcЉxi)((Β($-yґ ,6LGo>ױz}^ZMS:10scqhy<'Ʀ[[)bb;<^F@#i{`lXI vX D1f#>cJPv1W;(hE!Z>B˅8x <zе}- +jK S%֍٫j5b>zZlvUX3If? Gޣf6&nai"/Y,X>Om#Q{['qPl^Fb=q#7WyU[[cG-%.+W--]#4K *oƛ, R)@^^yH퉱:<"GS@sFRUbcqrYD䦯{DL<:4ʭivjX /C1b,vg2B;hUowЬT e*,+Ў C@`ڭAw,ʭYmKE\? yMn :#l\h]F[[bsX- }Vm23NSk"j:\jqOƬ=f hKoNG+SQ sFz_!-ɘ޼ 9xD]5k4 8"~{_t'Dmg_I=.fc.RIcC5/_6\k;:KF!u\vzrXج)X]J*#nzomİY}JG j1ynB|嘴"Ag]l o?y4(/!*" '1x?%k?# cB0e&0|"ܿi "J20'~ʖ^1α#)y>~:^ݏًNF@#^#NKځxuZŋWҙ#.ЋĪS$mrd엄=r{;CUx܃i>B`l*CvVQ4;|irLtcz^c :h}yWS%ӆomƴh8NzP!%iv***U|: uuB|??>( q*0y,c!{~ĜX# Xc)c6"WZ[n5Q_ zAXƴ$NИBTF#NB~A13k02\m086tq:=6%NT&|;0/qD&K|ߑzS$Zj<4 @cOsssZW-O#h4JӆCi>{lJ2%߀BbQn!Ӛ]}@ ;ʼnwQӰ!#ߑW҇ah4 hvnNjԠָ#_|ƻYmuq 8;0-,GQI)E_@Br_,Z [z^\h^66Am +z੄>zP5s3 +u& yJgq?rRqX {$s%"!n~eKfB$ƭ:Hmۛ؋cNŒ6!a2Q, x >sMj7@5]CSRR0|p?ƒ%K~ҤIDŽ P\l<ڲeiO?aԛo wq;O<kF}*L˹ 40uQ.~śyBgjĝef&=_*;pw;aQעSpk`}~{tTsSyO?]ΒB8s:f !^i~1 PHdIBP' rl+p~رd?>|y؞Q0U"`b ?B@Dl̩;1Axk`*6MEnKc] l9"^W8 j:(<{PoéHCx`ONm@IDATNJ<ͷ6 *(55U$0\vN ?;v#<˗>@~~>N? øq0tP[!پ};>Xlvڅ O<$_3gV4~A\{h׮[斘]Ko[@hI\m[x| Z-^qecaefLo;% 7ǵ'ּ+6=|@JM ]wSw òѣGJ5Zu3 }e{8O<5i)G!=E=x~%<=іP/K!Lx#%؃X$4$Fj)<dߔlFmKAPL/h_c=Ak^!Z!^lAZ:7bw`7Ksk\<<"-SF.Ėh?9@֖7h)<7~ϿT8}4=؆.] 88vZ5{³+IᧄԩCu9wx%t>yH:r\VRex㍈\x`*5Wz${-4VS|y;iqUIX_+82\G,^E2@Ō=,KUޔfWzp5>]jOC5^ԉ#MK>!'mt)+Wrzah#ɤ~ ye^{>Ħ<,~x?}s+%%Ä%:?HkV!BM|t\<'ĵ~O*FdMk-hUCx5d{={6;wƞ={"XSHQQԥK^0szI U\ [u@P j{U!TpF):p4ϡRAi>{nEQ).S.7 Gy8)J{^XnhP{H?_ȡxtk Ko>64,  4`j?BijGzYHy!%M8Z.ʡa7 ̫\'yG zH9}ycɩ\$izݻ7 Ԇ`Vg:x[oU˻8LALLJ(޳9-y>}UqIzi: eq!p@ DŽ(v4߈K|C(چ֦oAu-0cTol,ڎ4q"J20'~.Z{{c:kJ}="=N_@ KpG?{ ԷVIHǂ_CnMN4Lmg O0?}C1/-* 0[v *?fYxw߭'|6lP'-^'OFsϩM|*س>P  o9i 9ya)Ò2Of{ԈX?>Gʔ$=nGp–JS6s8OH!ε3Wc4q ;+^3Wcx:iɵB7ܳRVV6mڨ7PK} BxP3sL:s:oxUp>ztΜhh%5-q  7+s0[U*>̓NLNPw䯟H!׆.G*ݴâ`_ NK`/-f:=mPq'zs,2OB{brLUe@H-,{e%\6}DԠp;-!<}5\:HUTa8ЅręVW$#w$j<;>Xr#,n4+qN3$.q;_L3>> *8ӑF@Rcǎmu]EZEպs%ZҘ6N|ž~ӆq>CsxzjH~3'<Y~ \nB---?WG,<+B_ga*s 8*%I,5'BCکmIIM5EƧMh4F@#РCql$FyY'1 "TEPK|;I)ܿ_~"mo੫A,،^zp,,J+\uv#8,W uʭ{vTiKjoJ'jR%8yŒ5A7O6 y,l,ciЛ[N(9 F72)K1+y{ϦiY5ʐ?ɆkVr`:CfQ-O5 #r:R{/9e찘XU<5nrc 8/}}K8iŎ ; ڵCkÑ0٦Z3Q>(>e,x{xig.N[=LE5W;-Y;EKa;ݖk\f*\pg,>(휁u1gW}%bQ!Xw\ddax*F:Uހxu1;1>Ĺr, vC !f0kAܸX(Y05!l(MxSL:4 <祐}NV;U(y)ǙBUYBY*oR)ng8sémag_ )Bָ7[&TffSwtDǰqRe65rZlŲ' ]ڻj\(w,E#;#E0m('6C0G{=pcIH$-Mxk@pp=⎜˙Vd1ˁMG0 xu11ffn\=#5qZ= 3뮃7hgMiQ2&nGٚu pD fXs> tt{n=rV-6"wO1fLݲDKqQc.nXqؼx Kr<āLD8H_js9w PkY?PIG,sjƁ~' g[qQ<vmhy9QNI9 uc9xƩMgC:!KGU_pp^VӌMNK>^>n)fV 0E-@[!v:! pK-Ff yX(̋Μmڔ2??@r8fSS#vb~$AFᄀ@Yn)*QuѬ !ݤ&rq>ИH3h4u@sŃ{_)8S'By/qɯFI19cm)Pu "L,00Pzt {DC/5m1{Kó/Beɘ|T aqx03:GvBǎB 0NK֏No 8wV,Flܧ4^b8w+M)+C3ݬxz4 W"y ?u3U ͚ /NEk:9#yC85n*Η%VWY_ 'g=qM|2/b%K^;;ki<9-PDřmXapˍ3=\掀v5AaV :^6̏Vd bG,ٜ5ã_Ǹ . `h+`#s6bϋ\l~6.CZbsX- ]7b (#G(7t ٘HZ!VLA?W e3ҏ`@ocƪBIG7Y梉'DA#,"?Ko Mns)n@7ˀ^z& t{# |Y2Ƴ/|}mKPXYp,R2:meD?m:#K + rIzt:-݆?? P7?2|L{89fF!=0/^SCby20$QbB)Z`˽6(İ(fqr*"hd5G܋o`ӔA(\X~-i ɋp)( ul~:Bi4YsQYjvj́⩖&eq0rXjyf}GiqQ.b q*x;/^$gC#z2W^^¥ >zB&uA!8mqʼW2[Q5mIxuZ.k2cMaM@jKj5I@l8[smQJfog3#U}*j}=4{65[GUd&-IEC{_ "Kg0oT41fhj"Ӓ$1JzrX8SZӬqk>{ ު2?ྡ :c .\G)2񧸸X9-y@i¦OLg/eAaE>"O{3Si#^WhΜK۟>rWyBQwHS^<2Q-aa `QXs$_x'9Vmr Mttvm패07c,4QQ }aC}?ԆSӻ7o?;\iiijp4ydW^XhJ۲e ^~e{XoS{ V\h5jVY.:I ݏJl$R}nR; X; <;|b#딳˾S 4dhYMZ8-8s x/WDE F?p#\:4$ӆDemݺ;v@ΝyW9+bܸqo~u֩'?n>|_|6~]vaxV}߿}qԡ# 2j,oJP{Dσ~7#)$ȓH L:zk''9yt/ceyY+174fBVH՚5 Cg}-{TP( B77Ҭq¢$Ng)Iߢ>Gyla7KV;v ?{Fjtn騳\˙4˩|c$9A0]42aB@wQ?yȤ?NJ}ik,6B2a6Mvxdcˢiz,ڴl7%m4c_FL[Ɇ52Gݘ{QPh4?K1-N:lgM2 GW1ar`}dJX?s )-x tf\Nhv?MQ8_حq9K"1z*V58UqK2 15"SGAPDsx`zމ9g5&z{ =%DXhƓ2H́wmذA,sd:u*|A1dF²eH޴u::d +E5&-Bp4a)$Un&k^.8uYjyaDY @#(iӕzy+~ݪ;TRUwsKJ7Όבc!%OoEX4qh89L4XM}Z* ^ 8 !/!Wc[{g8ONĆbj.1I3;yW1ٔzJE AW#)˭S[v* 7ni,ŘJ1_Wn<%7ZU &ё H/ki|(w|{ĸ+&"na q VEaogzhtr٪]oߍuZk BD駷:a!&Z9QrYԓ8wD,! h^ʩOFPL!|R4Bk F 'f GoŚDrOmτQ@6"%zoIOC¸4< <ҩP3L EwA$L4x "%ÄE"dDz:8Mz-}HFK@"(i- (Z^y#g_[nк%k'#q4U{_VcL<fw ,@gDCubUHݍEEy{[ ,,WM%Te%jS& a9JU7(YsEyvvj+Qw BQ%`Эٽ0Hfd d`"чiCƒ/2݅xË~HGaby.N_/%)ͱ8jFơSwk܏{TIO0d}C~8Vv*P(vgNL.&vk:9.ƢA=[EZUA@"iF X.|?M3h^% ,<4j>P̩-Vv/< Uikfu#y(LD̻Z7[ ,ű<16s}\,x7G.I_+Vp_y6Zd\wa7A5i&EEahPJU3u@Q(n($ia~Jgt)H+K}҉h:X']N`(rHDlW V@˞btVBDAv btF*XmzVB*P(&.DIC({8Y&'ƚRA6O9Y]ﱟgk{SVW4@ iiOJ.}ѱ$ZҪyޡ_3֐S^w %O m Boozᱛb< BI9'8F98 de@_Cy0'=6:dO+sW\c>$/l24d9% @`^ļУG [ \ܳupcL9h̐0L`؉ vyC`tG.X) TVEZ4O@[@@K.6t6JV4o2_v_[/0"0\A nBTB@!h-(-UUU|ǏСs\ؽm]ҽ1KWAʰ"/?C___A^W4@"iՠʦcR+ B@I %CM}hoeZ"ŷ'2?ځ ?BZPt0袯?e:z#7* kUB508pິW_]vnF G4fggF>U*Lx$F5r;e ð:%ouwnb$,Q4@KͥL3fhk߱cFyzB(Lx4GLa(֡0ǵމ/תDWąI /b+HqwmbW(&tuL+N5y<0 =n!abX݅57K ",N["RSS~~vEW( B@! [Zس[_, h<.E܁bpּ\TT_FW_?t~=''a]E}&)gF6{XaigZP\-MBspL&t>:_mB@!P( ! &.lab(//\GuuN>-)LHq]&>7/ @ yb?L%0yxhP=2;B@!P(&.bdCf{x8mLX<|q-@AA$!BhT}&,b+?C/V<T8kޫ BQf͚=p!")) Fll}'xQPPk?ooߎ`r ?|}Ṕ$,x[ZX<)g~EEi>eg2ː *a)BE%yd`oNӣ3{vAHP7xuL[~7p$-/ m?pΔ r+n򬺁!SCW(&~ k6l +"::/#VO2w}7Ξ=> DZb /o~q1B=u(#K-0}+2pyRtw}t|my1=HNNVQv> {i<'_}|9g#Je 3:ỜNUkK8]b% 2ߊ9VWᶾd}i>δ<<IK2r,^yJE TקB@!bxŋaa] zgRpѣ._zEгgO/]W%/rd`]L r7W'u#=&%|}3*bƇij h4I6M ɹq{* -=-@w`p %%oAJ7TP( Ua˻2#,(LT+[Bd(++x,y<VUޛǞG$a4tP'w ;ɝNcwp܆-2eTN8|CmnmEZaTvVGyzkPxd/ۛ4/H pl^TT"u?AӱN廨ZP( +E|=vOI[w!H [< i/&9 Y9vh0AAAq O˱3&HX4b$,\VX;$QZio% NgTr{V@sK~Wּ-봵wB895Be) @+ /U駟Xv!۶mذpB3aK͓O>σ=q`b=p5˄gر"]P(qOG}v&#z1F`$! 1 `O<7z\S, Tg,ޅKDqG9~ȸزR BXh]/}.ċړaԩxŤ2x Ȳep%q,˛nZGWR!h9XVQv&ADO$Z$"Β4.Jm[mxс奈yhpyo"\"g)Y",ux2 B@!Ђ lF']W:\Si @ jƏ FXhqhi<\,ӘE?\.9ΌEJ R?}RA!p=hNTeĮUP( B@!09ea}+u.ˠH8R "I1JVzY^,EYHI@ !`:p@ 7vм(LO֦0U6?ͧ7ëOI!О`bp*_*2ZCAZ1Oƥ"ҸW|RCz夜BR3f8ӝB8`Mh_i" +EM+ *w8[X6aN$2^_-' FX]wzđ-J:/3Le;[]!s*Zj~jo( B@!pS||rDA縞)ՕAL>4O%{zՖ 5%-U8m&vSge}%ͅ@{ZJ r?~>~CnGPX|9yVcˢiI#h^*7'>FYr,1FpK؎i˖ Ŭߋڨar7.VT V].r #k)Q7 B@!p0iƁH JCZcYUc`=12Β.%CC?erERrW䤉,A}h^vyR| -Ɔo,:b҈ɕO J}Q `N$e=>a2<bդކR`˜p,:(b"#' LmBCXS?"+Nasx1Eb0'5Ikp`3""d$b;|cj=M2x#.) ?H&I!P0i/!=C4eDI).Rr#MRԐ +q6Ct]*.BiNlxedWY /x:`@ņ;jÂ]32L0!-x0JNMfb՚waQWl+J?; _􆙟NX4q;tےHG<$b51;O.Ġx\**DΗGQt* S_ܱAH>hHc'tt zrz=<7أ-^i}/ؿ?DԹEz[izً bd;u ? ,Zw ̴I[Z[ `wCa 'n]3< oa7!RؑvTLAC,=(} F9CQa!ҢWU G#'͸vA* U"]eqM,U\K6_vX0֠בqhnEw~Rd7Cɷ'HP)SwM1|#{abv_Wq##IyR0I1c^={`0eH"zj/~- ~Âp$~ȹqUFD1&/9LQYo <X婘6>iU0(`֓1.\$aR0KxEoav"ȥ6~BSy±_VSԨ2 B@!PL"lUոX֑&Z "< ))հ^ ke56)H5i5=ng12 RdkP2炬OVkHFdo8nv 2;xW0`ߣG# ÇsӧPk(..y8x L&Ξ= ???uoB}P.߫&TUEBlɻ"T`C̘d5?\53,IקbG:bs@9B:! F U*,tw$z9 ?l{u#(L PUI!PAw1ߵѤ;IKN(Ki!zhW1hh&qAV(޹ >R6iCRlƸ[;v~Ui1~'(8sZk[VAdo<4lVXѷw<чi+qx98}tdeeW^2={ŋiyX<==`وm44$ዹ3F \۩в$ogvAf* 5L[Vn3ZF${8歛ċob")1[]8gfxuy?& ZBd݊6*d'mW]UR(7<Lx?K1})@HQW2l:s[Bt)tP8եhI+e8KzgC 1{P0c\V5+ #ސ~v-X_qX i\ZڵK,///t @ߥ1 'ObΝ8uꔽn[4NZA\"m */+aS_,Vv/< [fƜWd!ʒ}薕l kSu.޸o2잳#${ [1I7cl @X1XSw!rI6bW?F֭m{>aԾ uB@!PEIR'L&.Ji,qG9N2"Diin(&#*c+Jv5 1q[4U}.o[D~H:֞o޼E. _KȜ1O?-lzxxǹXo3~EY<ඛQ64CBg:3>XGG Zw! cc2M 99;,h["8Q0[diqx`@$:мZn>j F?뾧c'#w>N&TP( kE'<ᬬAy:+5A)r.%m,BD5eRSL'bŽD/hD5jJxF|:J.ʒ(K؏JqQ +A1QN\!=CE0- }{ܕ&P(W@G:`¾b>ER[#&l5vy&1Lnȸ^21&,l3*cO H:9SoD2Z}z\Q2d}.Wx,.@ysUa`ԩScef̘aamFIKUI6RWpM"`E ]W|ɕt5M7ܫiN1yX*8 BԑUkj^,\@p]fR01Љ/~R.1kdң<wr4!bu:GCjDk5%~H)Pp4)}1EDv65tܹE[\q հB@!P47|`?~<س >DFFb֬Y F4o஻رc+MNzGW_}TP(ZiLAOcɗXJK{ZKWpSS.н )Rp-2""Or]dvKc\ԡ|Yet"*9&vv=oRyP6/Ma0m~Ocvv6öoߎaÆ!66VxywźgW>L?~8VX/P2>lĈ.{n7G ؓMrr R 5E?gԦ%4ފ^*F4h*SYtCiuR_3MRs'Db2J`􍮠 Y {vrMsp *H_Ny|-2Ύ Y4v1.m|h=ëBגXW?Ec^vLӿƬK!ۗOꎈqµaF-*@{ĴE؛\ȄF:DEcaPAdley(ZxٗY T-Vu6!e6uG~=h!%qƸmCY!)T%_>КFUx| C\n̗N2w_[/{}\-^FQҒ;ذe >+rO1KVņIqEW~CnŐ!C:Nnwr 4< uoF.uׯ}qgrybЙ-k#aMhDĝBA&)X0(9{~S82G9vCzYmx"2En,%gc' Ӷ;0;&l) 2޳rv(+a ߥ# NFńHDm3}Kҋ(t -:Yۤ_Ƹ,iL3˗zr1^Op@.|]DUq] F\lb&y/OS:] =?ۊg==ŮgqiObPccXv0QzSl/J| e(g#%$*}xl+p0w1Byu牗I@ tꊺL~n |r?J}CCJa^ x5۶mC׮]]D{]x#>TvyIǶvZ=Y A71㮛ܧX 亱=|vٌCP[8/wuqћz'"k\,թ]z{ҸLץ\%84юSZi.˖"GG$htotn9G724}Cv#2y"ff}>UIqQ0[#BȓOM[MO߉F 5LX?t)H? u80b"᳔B H k0^Ռ(݀Rnjh; 33RO|;y Vƥi4Hֽxy׆ />AdA^8qAF PQ?F&Lza|G;?0K *bmr#fYlĜǹ8Qm&#e9`%ݝDۆM3y(HZĻ-Dc@s@EyE>@0E6bPՐ^!`'k :(;0HXdeK#a1aWq!3x+.]HgyΕ '*4?O3q' ěcIe'K^<"A6b?gPA+mX/+R# |c TVX>\e9)k'N)vI VQxxxnt[)p<Z6}3XXLD"ex'?/m1^HqZa^FZbz7cqvӐ^Gqs7fn3>K=*Q!PodcL;QBlk{Gd/_Zx? ,S.WP9*gEHY>%t'ἌsLXOh+vVʤ 9.-%qDZS$k-:C&eLRZ|$] ]lq}=NiPV/p[ %%~_6fx7ES i:S~iWa@Jr:=$ L]CVuj6c4uN /%)m'Z(f~&$#(MUiY< > s)w91hPTdcOL2 _# R !Ą'y]l4Fu5MyrO*𣌝0BpXK1yE,4η;i2rPL E#}_xtbR$I: 1lgbm鿋8]f8U<'c)9פ Az]%sA=4V[uV>r.Vc{CQ ._5qL2-Op=g+[oJYfG i#!:OeҗnڗWX] ܭkga.c$" nìJir2 7yp_y6_5+#`Ɵ!߷xvYcZ&v16s}dڍoj$ A( aiL0 1npcϪEz* VC |J 1II1# >7\4"%1֥|8Khcyv:}7/c7oX+3+x\G#/.<:۷O?uNnS iNěqâi!Xܦ^;Ӆ6w=hCȜ(ڷ4Id; C>^}gwX bx` ĭ|W5^ٺ@H"z1õ] ջ3恘<7 LR: wD'lU9} O xdy_aHQv.DKLNt)^m|Hݻ#<e*OdeI]q]Oi&d7*HECF[i M<>i$v=_/˖*EGc.YJ4+ޮjzСC܆^y 0@d9\Ç9DDDm}hh(^{5;|@ vҖC,~BA%ZSޞt(,t%O,ٛO.ٳOVҵ3NP/N!X~i=R#&Z0BCgŽڲC2"L*tn)ed[II`vd&g~~>Ν+0O?4|I,\(**¼y\#F"955Lx]}KͥL3f̸\Ma^;76| 0m>^]:GNEVMh?y'ˠ=>XRԡJ2%yҘqiY`%5c#_ON'@DRL)dsUыߢ Kc\52$+K-}5 $TLZv ___֖A7!ttB<}??ԇ-.Ͻ~vWDȡ7s4hMY)9|1p9G\c/,|i4is^'?OwEZ׶L%N)t@e|$[8^[:hfݣ#`>Z0sR )M{aSq se"=kV8R 08謖4x[J݃t \L{HXA޷r> V58UqK2pK5"Sw&{\,oko@EtOdQKKSAP( &ʯF T3'B޻8t>보9;܉E'\2ږZEg)73C3Kyq}ԔŤG.1jť[#33і?jF2:RpT0ʅjuL0'uY#pYY%[$-a <7F? jn (y#Pl5 cx g|0$e,Nޘ[Rg<|3c05uXx#|~ *fM@01b"'1"<H{Pm.F(3/n{bcXv0QƙBȼĘo`Q{*1 g;% !vҫ p:34mK8O+:z³ kbp&j2OJxGd. <ǹI;/cogΗRgK8!׺Y]TSwaya O缦rNsOA4B˓vlɽ.|v{Wq,[\!5,YXA2sQDKc\52IR;a1}+1f @OKbFAe!9mr?,ƈL!2X,cӢ 8q{;Fd^Wv(`˓jlo]dFFFb֬Yӣ9|'`e뮻0vX)S0zh*pWxyD]JV"|&.&)i75_s9IIS|11^|q'b L:8]eqYA8ND,ߘDH/&]*' ZC!,XmMA7"nc?mܿM" |t40l܉MH i&DR 1cY'1'r)qDDa1sƩSJB! '|6 ov'1!0u`K2s#d]Nڍtɾ!=J˕ɺ0i }։//K#*H$)E5v Ac{RkI|OU0h(CElEK<;&u kވYEn׶C8n]3nm5ls+"Iu:e>ٽ5/Vi> K{ޟ|G0'm^"ouy9 3^QҬ*v84Ew.A<SWc5}Pm ȯ,sssq,]TtrڴiÇ'lsFDD ,|v[jwމzJtp>} /aae"CY&QJco,1jw;"'L}X,0b€ d 2#J{{I9KWA汬'T,_!%'Zhk"qGǪld==)_XK"- D^EFa7OZqk#14VI}Ow=Ⱥ"5݌ k-Hg_]t’c`2_e(++i,yGyB)޷E" ѻpQZZ* }u&&&?3:#o6\>i;N-v-h9dU$qiuq={",G{X¿r=OhuZj.e1cF!f 0mPWPDaz`5´@5s⪘B!$B9vqߝw80bC]Ηãyi?][eRoO2-dpI?3Q"Zn_^&NDr: Og OpBNq8OYnGuQI}V,'%WrwN{ߝc"L[7Vi B@!P(Z 9O{i(9s|{O<p+P%W!mh1 OyyI` v}>q1e|d'JEQeeZՑI8,:gLG/rHn֙0L *Գy&>sTg32uPu1jQZӏ`yXeqOEHUaCF+9ܿx9֟7wk{^v< :sw4byؾiDw$^+zñ.̏t=.:vӡb"T b UTˇ:hc0]KWgg,w<6kivy^< &LDJl6"-\ ck_|rcH\ϒhuyQ Ohω+{Fs.#9~?'&+xKk׷:%r(EE1E" {簣qA1ovs$XS vY̷‘UL5 KVźͿH<}h6^nM",+Nasx1Eb02lŮYtM*،򸥈ORwK "x"B`= pE ؟h$6ND~"(LMe(MD'O21d95.,e_>&WL{`;/z;rO4(BYAZD"Iy4GF/rDеc[I uHߐxv|qF78 %ra?z]g">>BG덹%%x֬ѯ#%BE 3j^OF\Njdƙmy Ge ]Px丠[oAl]a$I][ECZZcBkEANψ1z.)PLqgCWĮi?,صh-wZue$aGgno'uE͵W7 VƎ8R 1#`pbqqXF"- [=ڞ H`vr# >(6 S;B*P\ vV< ڟb"ӹ/tf_d $*Ld;ݦSs/L+K iHeC$m0µ`3RT^h,X;5 KW70k qF̉%kr}cEmax&~[~/sOK[UijH&R2驧j»-Dcu~Tu@_bY7سq bym(4 SgԽB@!# -Wu.Ky,*R)YGL0@"ʸn4qS}|4O=pa׭"͆?[|0i%pL0l\""J\83/"HK0QWZkR3&-|IJ=viFV0 Iߎg#tZ*$90TѦ!Px "qnN? ^$)p<}kR3meNdppUca2FZbyu7g:A9(YdhX/*4@^UX~GQC :*BGO 0CE@8LǥJVg%tf|M$Eeb,UnRNxk\zQDq+a,AIB y?f؁6Ŭ53kw$3@YyƖgh>)O6CS&gʵȒ`i+ ̨r (AIo3ŷǯ~;.܊킯+'t 6x [8[%7dIU\;ǚp|9K;u'~~ՏrL ,va{OGfﲁ.(g"le|7luqk=-Gq6+>[QhIq> 7W^'])RqVl.c3/݌˧5^9 _[/Y WzgfR_ӂ+0lh\7XW\=ϡx\^Bs',ĚOU}3ק~_Xg & ܇wn/BL+G 1CUec?~bD x_|\Wq&p]LPW}K Mؓ5_*0E0Vx~D1?k )^y7\pgE!3ò+TAqEHŌK1HY\2=6˽An3n#]7%hH@^n'y% ~wGsr| {Cv8YAfހ;(Lsi'+[;@qy5ĴIj}|5e/`',_Jhm*7nKs# AVc Vckb'6D )x@h,ٍvc(G!&!8]s$#7,pA߳zq\$fnD^"z) $FGQL;&"} MfH%V iѦsV<'<@ZŇ)~izsjn[ .i{=:#+pZΑhq i?Kq_W/1* 1 "p(X}QkB!ⷨbSe} ͵e#ڜ8sVI01\[T;<!vҘ>\lFnF@jܷorsOl~݋^}رcmݎΙ3[nE~~>.]jr{#G,Xx1Əo?xWҗ^z yZYTTYf ӦMC=N#e(ϕ n.qw~mI^ bXpGWF0H."U.8}64\eVˆ#e)$ ӓ419kH0={6(v\:t+O<V\3f`x"p7taxw[o>… /`ѢEv>|=hY(N!PyA@G8eЮ~rO2!_mA`@V+iKY !tj(XqCվ"keΰ\lJ4p ނPak+=}F(ٴ&t1Z]|NB3FWvX-^,s " @%-o0T+c!GgߗzB&W9)=P;5/܌Ksp~kAڵXb;.4Lݘ֪D 2WsspޭhIP8K۴`’~QRd%C0zs "=~x!PE@D@D@:EEDFFλdށ/w`+KYG aO43za9Hκt"iiBU3zf`~/rXd̳z-" " qM BMC!1_O/q޶} pWG݀={ZaFn.Kt," !tj   ?ᐮTndCm ꫪ,Mҵ0(q9?==݊Zo8$L%>JI D=z_V&5~ܴc4FAD@D@D PpskPtphWmmݸ[y XeLYneۮY]UeHjwchT#rklÐxĈ6֘?ƍ )ń^{ZZ&O懴9O}RBטJp' -%Q S qE@D,!@OE 2*@g-y1-" "mԷo_"''6m”)S:K:,d9-?>_Oleډk׮=-hdmb*'ۇUx5-^C}}=.";$ki" " FޥOVZ7/v\Ffity61.SEtk=چ _|p1p:4ypR," " C@x(@4D҄w'_1XK6\8).7Q" " " " " "Ж@h)ݴϯ+J>dN;/Տ됑pܹ$m:h-كbȉX4$]iw{Ӑ \^[UFHaҮxI#\X/<%!_lRo+m{[}_pRX ؈{<fϞXhIM7݄I&᷿IuO~f߿kկ~HN\xϷiӦ{MMMo6:ob?SN +a\s5=q駟Ƶ^k)~.Yq qh|?"mTY{ zrEΔbi{D@D@Z/j_ulʕfk.|믿nW*Zhhhshgy-ƍcǎmc R֯_w}c+7{C|'X ,_|MpB 1ػ{+x+/vlكwyoq,\Z#CD >F夠? /T E &Nh{q~y+ }7i;wV][oM=ԟ?|\f}4GEmz=PRRbsq޽1j(P@{!voaWj0ILLݻmom0yd>f|^5kc hhn9Cpm/PX" " g;aʲ2y9 )))xꩧ/c%$~䰽.]Z򞱟^sx !o\Cy0Xm9 sH؁ЫW@{쉃cy'\v>s"Ɵ?w3fd>gN0!v(]M50 (+@fZ&Һ6K$q6mbݸS0ec5Êsr”No˅S Z+4?d;+%٥{%`p8Ċƍb:~W?ӟPXXhErK1DKrLw4}h)mz\vevWo} 7xs-G7 %bi)ٸ K>8f,_ [eokxi3xgڦ" &fߘ6!pW/ ~D=v8 @ýܝ@ARi&;)Pc;\8~H^=֭[g_).sDh3冐zs.]jy"|u"NlRd=h g=,[2c_^i_eǰlv.ۃLR|7Twk@q>U8R)Xb‰^JNUUU/?i|ͳ??v6^:/wy'݋o~͍.Pl-0~x;/N8ȑ#kȣ5)CBA13k,лcɓ^)F8{9*!|3gδ=)D@g}ո+$ 1)ud-h=9!pi5c</ w);K~uݓ݈l,F& r:Bt ity61^+!.jzJ>}zXj2E2 e.T1.O&e 'kѓ9W爀DNROWV7o4T̙["??zP' #ܮɿ PʵHxWZzҡ߇z(>W" " 1C 屯eM*/EAA)"M:PrLW`&SL.8]:СC{Ykʕ+ X^o& \qk]pzc=-׽;v@_i5_WXt}X|IMjvt(" g{1a„@c6l؀~r-VC7nM[`ɓ'[/9cƌ]wecѣ>Yxq^.y9o;v^o<S/|ԟ7ۍօAc1gDl{IGBb,$ℌ!" 'p7`ʲ)\ [\vXd.`F(Rlw7(B$GZ`A- Vj+U؟M>d;m D@D@5kL JMM-8''Ǯ\8vG@Y/ӹ .n C޾}6sdD@D@D3 XZ|Kf}Fyk%ՄxeL-^6|K!L " "sn;+++b 3p̝;-63gW:'1ŋc޼yv?رccj@| ZB;%% YfKn)[}Eag(ED@D O%K!^+sˤIDߟ̟?uuu^陓9Ă눅 " " I D4TŒs>j,Wiȼ:,~ 8!۽'_f~: )|+KFN puk_D@D@E Dl\oqԹ`s >bqƆ9,E@D@D@D@D@L D 2e{P\&mX?{pTf6lt " " " " "=!d7tC=UÊT@D@D@D@D@D@@(,8׮]{Z.J % TLO z5rUD@D@D :]*qQnjhu\`ĈJ9i| =QLb9D1=%|!'sGe~xСX&" "'лwoY۶m(<"Ri4iS1>؈={FҠB&PU~/ 0I& %72S\BP*~Y 륗^z(4OF'kS1>׸k׮W1DnZĽ _ff<ms{1i+&K" " Q&ݻGֳ:1S1>ר4L;ђ=h,挜m>Ho I_2N n_C5֘i̛E@D@D@D@Dl&27-o0F*J92QWjѥK42(=z󟙮&$Rl^GۋtK2 a2F,[ Kn7-D%|ՍQPP²f\5j[!|aW/Ny'.~` M*lřf2[njNH " " " " " " - f6[َ*vlfԺ9-NDF ",̓h1D@D@D@D@D@NuG(\?x/NX'՚ }AAD@D@D@D@D 8 #ܘo qhD " " " " "NBk pℋ,-' +aK7 " " " " " "pANpq  -&4qVM8t.4pP:<`h`h1D@D@D@D@D@N[O 7 jt; <,lah1@D@D@D@D@D@B` uHƼ n&Bb " " " " " "`E#x;fZKq7s7Whp SY[1IENDB`././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/bubble.py0000644000000000000000000000223500000000000014130 0ustar00""" Sample bubble chart """ from openpyxl import Workbook from openpyxl.chart import Series, Reference, BubbleChart wb = Workbook() ws = wb.active rows = [ ("Number of Products", "Sales in USD", "Market share"), (14, 12200, 15), (20, 60000, 33), (18, 24400, 10), (22, 32000, 42), (), (12, 8200, 18), (15, 50000, 30), (19, 22400, 15), (25, 25000, 50), ] for row in rows: ws.append(row) chart = BubbleChart() chart.style = 18 # use a preset style # add the first series of data xvalues = Reference(ws, min_col=1, min_row=2, max_row=5) yvalues = Reference(ws, min_col=2, min_row=2, max_row=5) size = Reference(ws, min_col=3, min_row=2, max_row=5) series = Series(values=yvalues, xvalues=xvalues, zvalues=size, title="2013") chart.series.append(series) # add the second xvalues = Reference(ws, min_col=1, min_row=7, max_row=10) yvalues = Reference(ws, min_col=2, min_row=7, max_row=10) size = Reference(ws, min_col=3, min_row=7, max_row=10) series = Series(values=yvalues, xvalues=xvalues, zvalues=size, title="2014") chart.series.append(series) # place the chart starting in cell E1 ws.add_chart(chart, "E1") wb.save("bubble.xlsx") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/bubble.rst0000644000000000000000000000053200000000000014306 0ustar00Bubble Charts ============= Bubble charts are similar to scatter charts but use a third dimension to determine the size of the bubbles. Charts can include multiple series. .. literalinclude:: bubble.py This will produce a bubble chart with two series and should look something like this: .. image:: bubble.png :alt: "Sample bubble chart" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/chart_layout.png0000644000000000000000000023227500000000000015540 0ustar00PNG  IHDRjssRGB@IDATx \æ "(k RkVkvVZUi[\oYy,+3-\暤eh(( 0 0yy{޳r(6󬓸:8 0 4hJaV{lSgdt:nO$@$@$@$@$@$@$ UgmYA?3 @ P22      h@7ħ> T*#c      H tC|3 @ (S. 0.dTGdzHy`p%iߧdzS2u=XS>..%Ҟ:u OFDDKc%O F~N]ĉ0 um 65\ɔL]O5sZ59cbb\"dBxx8bcc]R+!  W î]1Uryr==Qv jraHHHHHH\D @      M t~ PvHVC$@$@$@$@$@$P Pϗ#     p*.jHHHHHH7*w$@$@$@$@$@$@."@E Y @&@~?_HHHHHHE@$!     @ޑ hd5$@$@$@$@$@$@~w#JA\5A!tQHHHHHs\"mrr2]R+!*8>twP$ F] #AJ$;n~8_Yt닍]W߻j/jn> VlccGdu-Ƽz _IP 2[ FR‚c;1Ax/tmH;>ˣ u̓՗pH~T'܉aގK_kJZeG&}}LLKHL&fJHJ d߇[ԱMUP' ߬sИqݸ :Y5kZπ"ֱXcaI-\r9(}r#)J=%1R8W W˜i><^Lq-\kEyV)棠G q溦JȒXt 9\h'a\կJ,+bO&};PL`"8Ev!6a9Xߋ3W2"UցKpX)\۸ef&nV>S p#E%x {K.1#v|Tl*1VOVt>~_-8lyS>>]fCK_WI,L!ɎR:v$nh9c򿾇-Gb⭏a*-ux<Ϊ'lǻO>E2yV?_\1f$,>]"%KkŴ[aipXq Vncm>ƒ^~oKJe++NX ~<(/Dfwy(j׀/?'aI*x-ӗ^G{&;>TT.O{2sIصkyΝ.@}[0,9I/Yǒ;*'ѣlyl>KҬ/)|*ٕEyyQk OK/%UoUץڜ?TyEr*2rj%+?=oIϘWxwٜ,/e-eVc*Vgp5ǏWZjt}@3I=gKTܯgiV~doFB]>e;d< ,85nRc(xG|AV[JjXޒ*c_N-eh=JdzpCϒ?+Rod @u}?w9wqjIg9ZʡsrZ(0tP%HtƫЮ:l7~21޻2k=4zy=-&(4iVA.{F絗NQ VIem53eN=߅盾(278Gk.J z\rz߄GJi+J}dF"@Bx^HK?@qlr$&:>>>.ak[VW 8z3! 9,o xxLGЖN.d>`Iqlį/Ͳ(G"aI{`ٶmS[eUvim5ZxqV)W9>nެ~u.:\)υ'ċ%jM,^c>-6U,5ôgޅx,˾YVYYNU}9IbPz,^dpl1^)mOsfh7`E}묲޴#yi,"ZdORu3oRo:c(w_}/^Y1еjȧ-{}"cd,Z8^]:Sx`ҟV!xLG x35-S$/-G!ld,> 7yH{y޼5>cuT,#$@$@F /^Ek' e=L`V55cf DZ+ۿ{,ʠ6>[,>M[}˕R.iX H H*8Xw/Q?n2{r(qI>zD7%yZ=MLj~2EzZ|(|M&}lI*ߠu͊w]fg,)g]]"+W ri&rP3xlGKL+ۧ2]% @uAzZz`]-^qSe>bp8[h>ђ1P(YeCK.~mmQz^ᖲ~ⲵfq]iϹunI7mcwVǎT%ʇ&UǗf`3)[~z_u)iyn)mv]iw,T/u\>7x#Pq_.t9CYA:+ZhJEݻwCUջ%9+ " tGpR+j2#%E{k ԇFRҳ l^ Yp.\֣o>p No~xUNMy'dۧ2J !!njQwB0Lv C:Q$csͥYW9 (jJtu23H?dm޼hʃXJmwbv*{f7挼?{91Ch"صeԳw];_3Z&/Gjy9YZ;-h 4/w6XJ?7wxVPR̵@qtBrNsU=@2IջLNNFxxx  @zfisʰZk @]p՘Wp9S $P@n 1I.b@Md2iK]R+!1'IY9iV\5cj[&M푀h O}u}*f 3RG&}.nx#:`    "o w]T%,LEϒҒ @-]K gϏғ *е͐ x6*О(= @-]K gϏғ *е͐ x6*О(= @-]K ghX YN#._=<v>3RK݌%dz=Rz      !Ѐ,x7͙.q._uEs FPR      O&swI]5RI|s:v o?D8ݪ N/OZ6OĮոvM&233R>SHHz=bbbX٫CUc^uڮoe~ܯo  *q_mJ4UT8~xW0eg @g mmCn'B*")) ͚5sO>5Y{:h]PQLܛɉ'={).%1ϥByhen?{(WM$@$:51]'T?^w8#NB$f.>]i >OmwޭkYEş{3 2)$@$@$@$@nE($#a~Dt#{?30$@$@$@$@$@$gaQhr Ƒm,}SV;~v=W$e{F" E#+mlSw=98*"!ph}'aVK7o8okr6Go nFt#wՠh *ɓ+|CѨ!eJHHHHH@`@br)40Rz?Yj=3Ѣ,m<3R a;֜^l܋G_z [r0tKc~-EsO|sg3oB. mOc>Ykig ҷ*< A$@$@$@$@$@U$]uD8c;ToD9u< 7Qѯ}X` QZ&*}%on>AE.bl}.$-X~Q+ [> E$@$@$@$@$@nH "QZSv&'qÊ+i^yLFU nSw'iי_> kBv,uwY[;ew?vGBHHHHHH _̸~OYeǦL80WY&f;qaEajFx|4X~{Z񃱇{NC{m@/zO9!ј1aPg @D<1rCYY2 kgqVޔJ5V*sr~aK%YS.:O/| 2(G,o0"oE- @%/<;"XgG=0Ch1~4vTOPbfUj,D-u C?$@$@$@$@$@$@$Pm@`gApxL˽Zsh휸TǛ g(ЉLE8n^n9n1 E]D/IpeY'myY~V;mDlQb-&]4" ?\5"I%IHH@M.&b2`k5#RU5(^ @7#zd4:#To5'*ˬt; }Z;ǖcR@g50HH j`.F}IɊHH2=c f}3K{o^ck.=x(|.s>Ξ=Lm q}p`ƹoza!/sQˤ;p8u~O\T3!    +M"uKWmD~h> 7 nl6 _>i*t+g*F5.Hvڥ%A9k/%))IkYEEe9o8SYa0VEt >~H:RL.MJJ 4ibq    7$1 b:/.̋OB ohkt 0Zc2$\s0Gg mm)[ZGt:vIZKVdF4.r(B܎3 t  FB]0q/w]pƉ$@$@$@$@ECh#R#բj}||9 UXw_X1lT3ѵͤ""ȡX,P@#   3@g}]V||] nmfƕ@ϭG{& ~ () 8#)ΧR8ҤQ zwDRNadaݶW0h%1HHHHܔg(A]0CBl2fW-Q'UV`o qGX3ęBO4+'6Lca' kWGnV PvN>8;F6bϞ84 RDg$mbճ`}qM @2"),[\+]~hۼ's"ģ-oĕΜe{F:

4K|:o-Ƕn4Fc1nDw zo_-nmw: ~M,.u$@$@$@$@$PuX7agm@Y­hMG̠Kŵv93 ؖa謗"xg[ 83gs\۞VW#K-%Rqej)|2p v<:?/Օ:hW۟z [D CMk@goU-J1F$wqG- %x#|{UBTP`W;M{`3i  @hqچB%r(U21k;~".{1O -gcT+h߾bZlMyQx`iv_l#zk^|;-` "\? XMȟ1ȩ$" ڿ;&ˆEsƓWœNTv.//džb}>bH P׷\Z6-$k@pFKaгPD_:lvywbPjW\kbq#$@$@$@$@$P^^ޢy LJɇp%۬Mi 'qÊ>H.B X4dݳO@p뵸gw/EO]hݯ-U]z&m>|QFɫw/ս܎fM@#MMv9| zZ" s~;u#y ~;#L XC4a]"՗-_\\o!    "P/+g\DMcw&+D[sa3ҎǸ0"0#ZEBK_ˤiaoL׀^CkhɠX"1`MFz(Њ?~đ8/B. 4Q[3$=Hb0ޣaD-o@FK qIЬʪqd9Rޣ5jHHHH@#,G0 e,c*!߰Py $?1BY +lEMYlYJR1s\wI]N+1#Y #R/8 -فʳSҺe0my 4n^~OB)Oi?ZnPH\KUckjeL4H(UyGM'>M$XBٳ+6@Ww*e #˵ YhסSUz LjuS^|BN󁏴heHu\5N"ϭ}%CIH܅@Mze}7KVYo&|'U6iݔXД]ıG,k%AAY/e,5in&)W7^8n{)Gۺ}mOt>i cih8eވo{zl3!N,tRsZYoC'`ov< kDy ؒl_ޑݮfaW1$@$@$@$@$@  T@naj]frGK/P6 ->4 [.Ev^OE=0gDioc 7.Y>n6î8e-$@$@$@$@$ xј g##jr}6emh)V<D v>s BCܼNhɰ$@$@$@$@! +ノ׽UO} 04:J DNX0I&u(&    P/Dz9Kpw%HI6`_>psCۡBB=ca_aP"= M"9qn O*w:rTJIYȇ;E^9(\tA炈HHHH@x-vc\\XM?=֝˗[rvƀXe}Һ={TEҠflݻwk3u)KpƵ8hzƸ:VtN_.\|3eh r5{*|]TQp,$;糒p>;-)f\yp/ϯꙋ$@$@$@$@OctfQls&&J9~>/}Ce|̾hwx,6aG(vY-&, ޽{UĦu{Y.|cDZ~|YmY5W?F~ oٯT3> QsvLߧ1E q']ʳcIJ$@$@$@$GuDzaN Bn= pNXTٿp^Hwc,2haϭG{& ~ pGE*elXn¤aȐׯEu(9(wdY8tQrUCp`8FhGoF$@$@$@$b@g㳏7"?;-nK,ѵ,.m~ p7~;Y_@ H;<#H|R3{Y¿ @ |2~mE;X~ #>G,ǐ)糒jY/.Go74n!-Tf $@$@$@$@E}hXCe]lg͆0DRC0r俞c@/<7P[]%{ ok3vBo9 [/'l,G{uj !jYFajO$@$@$@$@"ꢾf߆λ"H<0`\%3}+@A/tFl7 *`f}D(?ө/of/(Е jwp`K-{U#    p_Z*m:v ֞/C&a*,7hw8lڳC,KsZql?(˲$[3><HHHHꀀ>..%&''#<\sHeϼ,$8F an 94Wb܌<;mqOo셾4we$_eoy˧Wp㖲9]A9WyEwf jbĸd2AWߏ'+/!LQs<*=*NHzi$y眊f̃erp`cnivYt !1c:\_j  B&}^]\|G!L1֊3UiO3,fmaUn5K]Wi>)sFnCtE> cVVh[Pa_6CfN*d(fSnA GYF$@$@$@$@nKDlU<ʳ<>ۦaWLAdXRB)K݇Nl)VSٹp aΡ':Σ7C'HHHHHxݲ &(#S^WNGxHRm>O( eЉeds٠u-hD4m-$@$@$@$@$g,3f^a8oDf>b@ɾKmOGGڟ_Ĺ?;2Mڹ Jn~&N݋(xulE|S{׌~0HHHH x/[/x5gap;ĆC߷1F\ ȱC6M? . # z_lyvΤzXo o-K[vE$@$@$@$@$n-2c1}F@n^: >j&ҌIH\+ T2 Ey=)ٱd/8&׸F7yd߿c(˦3*,r@$ rg>=wEg5:j99 G@w¤+0颞@<WXw`[xR<6< f,:Dn|!#?Sᠭ]viyyyPAZKJJJoץ,'azЩI?XElm&fR (΁+f#S) 2\l]i8G@aSŕ:DH4 GoBcHx"}Lҧ3:騷Xٓr`'j8]P򥤤I&De: (Ms,u?\ [FcƄAޒz1u>\\n>pz0_e=lF ]9S1qII[L(:e϶uuVd+ʶ)H (>"P W3&e֬CW(eY&%O QLuf/bamj$D\-'e_hP*S9]/EZhy_S٫(>0)+_#U|5|Ju"m    7!9 t>,ߎk3%Scyطa&z: B+zWo!˵ljwƀ֖JpKpJZ4+uD۽{6]uĞ#KϼAf/Mt4-40\{G 0 e]l.$; Sgd_qemVS0늄KpFoTDӠYbC]~[-pYկfѳ5PmMEh< Փϧ|E%~~~ur$@$@$@$@HC,lߪ<}`[S4zl< QKo˜SVay܅Ȱ_ pJD_NJ#:tgd'CYjv{ 8L4G:U7L9g49#,EκR._#HFH}6@IDATg%P P`ǵCUlK j+k@)kKSˀS:yaM9ܻM Dh`+7HHHHH p+>G1ho.)й81eoF(Ў/C,ydPQTԊ&>ϭG{& ~nPϽѼ%ڡ*((Ӕd9A,8; JAM<*rF5)E&R+Y EYl d idQ}vKwÚr* ʒyyy RGR)CPPjj&ZCW>OsY0o)LQZmX ?&h ͻs C$@$@$@$@L3CX(ts^U?{.s>{,|"txK>h.>#H7AՌYq)t*I@)Ck*jVWShΪR ljIPylKլnSVJńY,Jl"K#%KR}>ǐ.\t'd|En쯖Wn3rQI^9yaOsf庠LMڡj[)ґb[YV= 78)99.\%:A?kJ%|Ȫn|])(ߚ/#@Y0gRpGwޖ騉YY߲KKf}#_Y_G ,gkh6l W o`@3h- Rlj=+SXz|6kث +ElPϞ;*P,;dvdzNRb=<1,G*OP"ݪywDLucY@@Uc;eq;IH111.c24TV&TiO]P t#v XhQuή8Ey.WnUvfl]UVKuu %V%9/5kqB;T%RCd`Ql>Rzf;Qj[P{=s8vPSOBc\='ձEiP+YdwaQ>:Y$Wyl^gq^cHHj@M1ߪY;M+BӮtOJpm}]܎e&6D*(lj&V)|mWXg}rD|Y\"x 2Z;T5NW{گ]s!Y``FpDueYP'4vpF+BZF$;(,{1g|)||q V$8[F> @] Z4Un銿 hѲ(ܟ~ 3X޼ůj#K[7啕DzwV$@$@$@$@$P/elqPPK qQ%Z8mWS-WGle6@f2}E>+ʵF1v<P(l6=٬+z.vsb=$@$@$@$@Gs)4 ?7xT`0xwf∰GP [Se}Zc+sV$: }0U ,t{WGRͬ@`Ya]:ukޢ8_R{޾2|v ťsE>#'wA@; Jo8#"(2;"͚rV$@$@$P=gcnR|~v=W:]uc#+m,}{rpzTD \$,)S|o[|߻ ._5Na"7>`]v] ,NIQQQ)\J P("K:0~7O~AG/kt#i 2|Kr\-Nd'Iq"FD/Src8YVֽu/\|imãNf=c/ι(Qq[b7-(qJ|wI`wH}j fBwp(Sxt} ( sqG BO#ltqU"+[$@ u윎kOryi*tW?9+g*F9xokQXXӧOm۶n(yU=Ҫ'2]vvmW]My7QCn^N(%[V߿OVJuC=Zy=hi8B?n.>0 }n/ph٪Ҝ荻qϿ\7n$@ X>7F^)x1 j+Dn'bcc;8~8lNUݻj$r{nyuaqVCa6OouYK4sjwTq{^:E85~= *p-Vԅq]oEm^},)93 6kk2 [fߊfgζXײ [zpv!|;6[×"xxxGc\ b`H@@ p.O c:dV8 1+`y0B g(MCڧn{$J&pK;.n؟g}xft!mZ 9 2OB Jwd)ARGM|(/9z#RAe/Il~۷)fuyQx`E.bS}.$]nf  W )i?~#[ >E`6)Ս> O$`SC[v}7d*^s1޹r(6W_mfT:+~A~yw*,ZD@@YDq)3j:1 %`4~7D{R CRn)%J)[-'qÊ>H.B 20 UJ^{v'T?CBv,uw=HH7~~ =ܽMƌ ʿ/g.ǀ.AxQk{! 9]A ZYq)G3'K3hyYa>4PP*!nްPygO9_cüvQ{eH†Xg>DYg=o7WQ}mUo1H Zf{_3?ѯy[77ǐk 2rE*JJL. JdR54&>ai/ Sp>2]N[=wp?埘'腆TO.e&[#X0ho.)йj[H/UN}bǛ$ t9 u+=['P8pUlY-a`t` Nr ؿp"y%Ǫ`ef?--M]k$ȡS@2)ͤ0$zaH[K߬|z-jK^wnF}w8es677].J2ߥe~m+OO( @ q_qM&6Vnyˣ|Ȁ/rz6/Cc)f۩mJJ 6%W=b<E+eI;_1h%̲ap՘װ9md* & nN'HʲlKzDlQn >,]W$@ @MZk\ bN(pyhڎB-uc._)HHHH H%S`jx52G~јL7 Kxow8s#;>0 v8m>,:D   p_bb7yxx*axlQA+^½}uͩW{c3_Kcα>PH6Q;aʯ0, \VM$@$@$@5@M"uKWmD,+T,sMW>߄.Cnn.|h|9ZKHރéP$2?aM֡4l!  ^~NŰ}`nj4fLDŜ!   A t_č]3yTohkt 10nl6 xHTu7 :ڵh%:]ŝ\ $W̟YXnïUř8ImΝ;-[.y:kX}Yo3%Scyطa&z^n~.HHHH<⑪+G0ga9 -кzdH,a^ |wsZB;t$i)IېwmSQ.סk{n x<@gaVY,GS4zl< QKoY1 sY1{m||]USe1O[Cȸ2$ Qtͭiff&N8۵]nu'7e!Mw8:M 437t;άadg[-ܗIo)2#X$ `_qؖAsc7#ɾ$@$@$@$@@P̰Y1o`0a#e6ڂiW;CͩJ \?Nm'fa)Ͼ>֨g)NϿ( )@':tQ$,n {SW~NeHHHH 3pjq)裘򿰭,6̺Vb9N[fO0tyFQ}ɥIH ދPEҭ)bÆ/'"*(UEEE@K} ) @.%\r.%wu3ఘy\ g m0/N7B9=KtQHHLrGvљ0Q/@Ey:{?;[%$:g{,Ŧsb-ב0ˣJ[Na~HlH:-icLʹhm>.|s:މ_yY̛r8pΏV߇)HIMrBeNs#uUʭD='/MQ`TPrz(_ 'ϋG* I@ua@,{1)|P]G/W/Dycc/h7 ( 䜱#gwu-+BAsH|nhuax3~^5x €[Vl+_Ā~|) {`(SnB2yF&ZAudqkp *˜2Q3$33 NSeohP-|pgQg|+WV2vj=TCMU),EGh)=tŒ1=8RuJ48rո~.L}}- 1\~R \̏]iUҢ?sW>A6-Wn3|+rO8vM®Kv. b/D5'D:E;S"ۧw>/o)WzSdeedQw)%!U4_a8\KͷRM4D)#˦]vE:ڿ4OO/zau( Е+0xx=6NDs00T^z'ݤ"n/\_Qy3߭G{SF֯?3)Latۑ> GY9 iZ4V|//gۭ.XslØyΏpVz%~[c7ӆBf<"kwo26P 6:Kúw~!wd^m{%;z\س?݉߃OhS<`tix4&$V hG?0~;=wGtQ}T }VM$@eaXI0+UzI ax`i{$t*  :Bx;N!]z-_>^^ҺH&$!!AAAJaHm`dR.b$~u}bqgcBvҠ ^]>25C s(V,JVM/P2Zإ39RhMjJBM~_& K1p:+vȖ3]C;wLSƳ+ S8"FE_̛61+T=аzeJM"4dO3[,_`ύQ,a<);\3ǭ FSsG`Whum۶իW^NUb?ݿ]ҺcH&$==VA nd;k؍@ (gK۱Y8ږ] S?aP$R`;J4gGr nM2ҊGJQ=7#@l$F>%hCӌt#D ddF|sa nFldyAځ!F%%%j՜UѢ wmWBJ5.aӼ\^: iQ'@8"rH$@$@$@e@H^ƪW,Rv~§%$I50lf $.NL#c.Ckʏ*S۵k1z;h,%ٹX> [^ׄrN/^BU .ڨT \P`*Fp{sOZm~P|mnS t?AMC]`ɤ.}Y 7 3Q~Jb9Pr,S:C_C 3mيAz.-#3 WSs~]*c^|8*I9&|HM5 nL4 S2dAg\jyXX+H 7@Mv}wm4mQ1HHHJ%Vbf LF!~;)MƳbŻ=!r tg&QZ]"A0Z$Iz޺c }?JM3!(I6@ ͮ%PEx / r-m 1 V́Ѵ%jԈ!qJ=u;Hy翱귩Ƴܤ1)z&7]W\op&f1<;PxіMq nk@{>jI$@$@$@$PlOo |o3.c[, m_YbYC ]l3#w! wo26P 6..u8om):/8pzYjWm*hFy1מGFIHHH +Vbն}:nut=ui9 RVW8HcWt8f0x,\>[6fxQ(UЀV# !ƞٍ P,S]: dd"Vcm B@.au=5rI+& Pr+G 8}i ~&4Vb4!KMDxmLL* _t b=#UpNǾ%\| - 8{Yx~ BZ[IbqpZ<}.䙐3s\OGQb]%{tXA98'͍!pE/?³yN%dd  (&jyŤ[gv߭('<})tnN92as^$^snu}at|~c>~=֣ GdHVB!w󵝨n{N,dtu!]c+<<@|<(YodàIC6^7ŹMj+Xh}]^YRoBLqbxU@}T@Z2KW}Mckh}[r8pR)χT<)) Uz*Gh9 |a "ֽk^ޙp6[ o &+d\fr9ѷS9 }ۊ1{O{!@0 A$-Ma0 Y#f[#5/IW&^5G B@Bi{rfv*o**@PPX@ 󴍢x6?'yk!P<ܘGatbP5   ([i5Fr['9p D6-KqW+k45f>Rڶ5g|Ot Nl::I5K,Tdj5.WAX]3.I)瑔nhƏׅ~],K% $0|zR8;m%T m?ۑ raMQrڿ)χjÂ;MY={@A|] /_d_Һu}"Ľ$$$bE.ga[K ! $]y nt6݆!8= |Sa=oX3mu˃O?. Ub^yEyvJeP [iܞtr JA51] A+Uz;yyT,_E1/IB:Z^nkg[  .XZa\[o+MEp'iLB!`ݸKb .3]/5Tj$z;V2Cܙ@7'= $+[? %!낺>dLpl{/,z3HHDV*Ӈx<qC*egl4 nDjapr+G-`ʷꕚ({VV&\΋d & ^ޱ}!"fI'd^e+N m8GvM!E3ljVniW1}e YHpT - _ʭPupU+URtq18tו4?/jy3/mڴ-EwCVu} Ľ}ݶ 2HH`b,^b۔B/gԾ"0LY8e%D:+ 5Ej^'zyP$zq& ՌþżḑRp-e+FcZ îCm=[CհS2`".>$e&`U^!bH׭%z(#z2N(x{ܘ D@>]>. J11Z_ٳp=29I80^ʜ /boPqpU$i{N*GjmQA8[+l ޹ԺW\ W03:-5-lQv_Sȯ5jUp;j0h@ c&!   "m˗bdI|rHsj-whZz׾.N˭襕* UᏜ${}=p vU̙5*7֦e̜TX#]%Rœr#Npo=̛]׬ uE(*d 蒤ϼIHHHn'Ī[> $Fb.vҙ9‹aϞI#UE[ຐ&6t7W]or8Xe!rδqn%Ot5    ( X̊Ŀs[!WtkNݪ4tCylƟQ,% 2)iu fI)X}(A vGĢ;uק˴Šf|Ĥ:GYKI-Po}ˣq͎vFXƢiJyIYkzo-# \.ŭЀvMx#[w/i1Y&Fud;'EmYjs%wAOHv\EXxkak>VXԘW.R(o(EVtkh8FFjP˻bٕ;)L40ے$@$PN`]fmaJoe БC:vGI'1h/A M˯Ǒ{6~= H e: yӝ"G`hyx)»w1ܸ,3q]ؼo6 Ί%mL:/]Ѻr{0ܗaDk!d&_e*wt^XK,4<"_ FP]_ '$|H-nm/V%ժ 5~juc#g}`G@U*Sj#1R_ +-F:WM }|v(7IH,$,"x&?!uԆ}!)]|hqeϭNO0_$4sC BR|)ߑ,ܼz ym8DZb7> }N (WH$P* jն} HL/prY@Ⅰ_`w;r tyI!.&6x/0{XkKz _ -gb$@$a~dwõ ćQh_@{Eyf_w;;|K꠺$Pp0JQjYsQt/ i!Ƴ;v#&|y2 g: g@IDAT,  BH5YFjMG~ ٟX&  Ѐvc |Plìi[܀(. WEgA$h@{|$@$@$@$P ?,ՈBj~6*t`"]M h@;KIHHHJpWjq#!]q/yKH!@ZB$@$@$@$P\7+^\k֋aBߺnɭ F$PЀ.U @!mqߍR #+4ApXz:C 6`Hu<M#օKI-#PYL UqaxHHHH- 5 lU,֮}} ڒObՀFxd+0qٸ8[ۦ"W{xّCk;Q.(>>^m(%DOuNJJBժU-ih@t 0    "UOlja, Gf&T }|kI$85sId{o}s){h=CfSCZyޞ}e;T K.!<<\YB$@$@ V Y Ƿ?bȘ'ӑq29 @!t`>SCb Xiiȹk*֭JtdS @&@ W>^v0.?5,÷|> `̟G=+&!ED> ЖC}1D~΍@k@K@,:9)ߘ-dxBe@ g[nf1m} Ta4J80eTO&ϟrr6yd$$"d軘֣rOwl>8\k"{0IE    1rZt! h  @3Z@aӛDʷ0_аr18v,*_ÜI!,]]g^S FǣkX ^2F#;or^ H:ܶn/08Sû]HH8䘮 ⮷vQRch ?M$vr@$&,A,Fi0.v2V>`eN <&-pp5~a )Pm$@$@$`E %CϰvRe";dWT:Hn 䥜@vZ ?{#F5CXzw^Z _oxd3%Z?E30O<7za=_Rl,Gk   1#SE1F'z tW;#ba%HH@ 4ՠH:<1팅F߽?Z)k0g=o Y?'r |Į)vґ mНDz1ma[z rvow 6aR &94xN.GS>ƹZV{1@#Ny6s?HI?.f%V2KKdqĘWl0^jo]aOHC`3@ ? piyFagN{L|I|OO/zd.H8/@QbȼQ܉"!Y|c@jqY|*wwuR7c6Y=r/kШp^  F9lcUt8N${lv{ѭGmg(:$ˁ3(h@٪g %.Ł&Ԭ~Xֽ|{;^j fg,}}1m1Ƴ*OHHHB@7{f 1ʕ=͘E4J5A̮ ׄo1AN5 r{~ĝwߝ2·Vk4g~9,ddX}2qFFc|w9#%)r A;lz^^7m51b/baa.\PNk׮OI [))w@ CùU*^ȿl1\5 *L1$P !:: 6,e-/.1:\9iJtJ5ѤzcIJ });ɥnd}ΝS$ծm;eNnT:gĮĬ_b`6tf01Lh-D甎;N\x7QjU'JQnZ ; "$ؓLGy-ӵj R HT_E]W6m *Uw|iN$1j<.T Rt!g~XguMѥRHJGouAfd|LBƳICI%=mR#J7Oepjx'z1ߘ14:a4\~kFY/:;^}]?u6Xy5 )}LA>0@?E$$@$@$@$@%@ nxn0LWM;S=cpj*rS@Rn,7_m} Ta4hqa$2L?DlHHDw1q&|4?Xq8N'à&(  X?Rn74wGzqp=-zk7^zwEPi"1p4|# !4X^?r4@gÐ^JKp S.3p$Wl2_ W\qiIؑaJ 8IHHHHd R ytܴ+ؽtҤl,Mմa 9MkD =M~l0֏C#o>̓I;ÄM^GXϗc;KBtQ1 <*)Nn“ 4b;m RKJ'M)261ثNu<:<1팅F߽?ZIo ȶ/.~Aoh>g=¡]YW?qƓ,X"GMblۗ+Xts tQu^&EHM9ХjY0   (.h@ۄ墫kb~nO\j ez~t'1h/ycSP; Do {єqa܂BPͽ ctx'у ^B.E7/BqbVie+KR* KXW44 .3(~{u< á[tj]A;ZMA>'wFfBM#(j9F)kp%I<9%W>L$@$@$@$P?M,??hZm[> k)"r BQ)1BWY!&#o RzrM+aʊͥ\<&/:xjл̛k;@w`Xoe@{eC1vן"wu=f3#Wq w5:fl{"/Om<@h _1VYZ殡Ri@{jQo   (cZ&SwۆZZQI43wv6S"H,*ά,o]<5Kq 6jX5 Ql rz g^u0nM&> ~FPtmV8U;Dg&6P]m#;'DuH5do\ M[qxl>M{M3TL=(8m d:&Up!>Ud #1|Mn8_Al9E?ۿ[vn<ߣcJ  &hzq0Z`xT7EL)b.]܁"  7"VFE*1UzfxvWWIS *6*ʁ(e 6_H$@$@F@6U/ ̓HHhU͛7رcΔq ! //Bb3Z%S89LUxLT\0r*";ˡd&"SLar8+} :uUVhѢc >|L T 2u C!LNE"Sp9c$woYb'9L%Vx|2-1\f@|y:9wr O)=2-RiAtvLƭT»fAyZ!Iȴ@EMEVH2-PniU>IHHHHHH@HHHHHH @HB$@$@$@$@$@$@4 h@;QHHHHHHH4      p h 1 Ѐ3@$@$@$@$@$@$@$F!      |HHHHHHH($@$@$@$@$@$@$P* n Qt{د=t2<]%l111PS:Zy2UȔL'D>d>%9%S /)O@}|N=)p_WH$@$@$@$@$@$P Ѐ." OL)HHHHHH] +E"     P hR" @)$@V*D$@$@$@$@$@$>3D      RHt)THHHHHH@}4gJ$@$@$@$@$@$@ RX, h@ϔIHHHHHJ!ХRY$       ЀV)% BJaX$      p@֭~Sb.$Q^tmTT8@MyhRT#S2UԗL'D>d>%9­~]Q" @)$@V*D$@$@$@$@$@$>3D      RHt)THHHHHH@}4gJ$@$@$@$@$@$@ RX, h@ϔIHHHHHJ!ХRY$       ЀV)% B4KaH$@$@$@$@$@$@>SJ$     (h@JeHHHHHH'USYe]tLU~ TeBԗ2.OT}KsJP_}mLL*^p/^DjTG!F@d>%9Uٳg뫮2,k*Jd>%9U+}mTT*fee!<<m۶UE Z*Wh橥'aɵGIHtpe9ХaHHHHHHT"@Z%C$@$@$@$@$@$P Ѐ.ґ DJ )HHHHHHt]뗥#     P h@R @&@t/KG$@$@$@$@$@$*      Mt_HHHHHH@%4UI1$@$@$@$@$@$@ ], Jh@bHHHHHHJ7Х~Y:      hcbbTu%"BRa@zuz39aO3L!CF7Q){b1! [5]_1!q׬ѽj˾t:P& tZyo+RGOvSjUzwH9ǬHrKݦH2 FEEwVV *($@z<<1c4XkƳ ';n|jyK9Q<0+OVKW=ԡ2anAY+ms+/RhZEA7oZ[?m}N',ׁcž02t{~O̝b: uέ|Xe*˱pF, "mxz䩉\9(,_,gs'՟T>ãհXq؊ ו(QMݱM6,?~=wGܚ< >?D\XaRڷAdCvlyU |3Xy2-u}-+CH 1Z-::ڰo>UdQ@acw0ҰjT9>ހw~5T~Yo!Qi{1?hgq_ƑF9 ahsߛ;^煆Ɛ|7mE_k9牫Gҭap&O1r@˜88CzLЯMstUXX2sf}1|QZ/ΗG1J6eSD Srt9!nl[C ʺ ATHG(`>1s[SxDDDN^[gz~d/*-r9)gΜ1X©4\0)w;M{o08^P;t{gӶ`=N<k><6e-66eg(J/Oc^Ur8ƆTy4NP d/1ef40`oA14jiiz󌆰Qn2|k87ƻuxv ޼?NkWYQyLmmC;CLЕ4ex-G+3o^<_`b,_x"}׬}^TW+ƜM3zh>!_zl4XW.ɫYC;ɜ(lu13]~8c,1K7OƑdsuO5S i@;sQ<0GӇ$jXpX)aowSsyxt@QR2(JU2Muw]Ϊm+=)W.w*O{Wvy,=!C)w *x;0+{1Mx~ W97 mW,mcd ;z=jTG_yg+-" OZ&{0rœnN[1X,# _<]/gOg!úTy_'Ѹbuu./b.Ûq} #cTky&&C[X۱DӦh*ufcy]"-zJ9בgyf|ԱL<7MO;[^c9|y5u8_sGs~? Aw+ 3Ë͍|#zڒ\M-k p7e%oE8.3m9>-nc #;h@ہAz-Zʖ䉁u&r mnA]Pt*|X'S, FeK'-H~M1S-Rnc $;^#elx";9/eF3ϨXyXyaP4Qƾgݯ5|;޼t\1/G)I gO|Ü7|>vwt_Wg4)CG\oǹ}bhg_kjrλ܎0*7lיV3ߐMG8|s>_,K5PogEP ^B"=<ޔɕ3qcn!uK5(Rln6Y=rΈŷk#܀bLyK9e E?c@r!, H9%h֒_tKxao8V^aQ'$@$P;J^܎ޙ>`'uqtK뻍2czً0w!bhE_y];fp;eYz9}x>uvS(@ ]|)͚blUͷR7ZLsu*vWj&M39`K8,/ ΖtV|rWٝ%^ V9[7MV0ѻlN7Xq)Q+-y8xt\zٌvl{N;Mﺪ흍h{Sw21(J/l?'bq=,9T)Klo6-g-zbWw~dYBhdX'hM O>h˴٨]yOaX pG=h?_J3)ͦ)erJb'xW߫-F]aGᴼJLfqdC'U~p{nޡcld3k2G4ñ/^1MD rb Iӟ,v60^ʆٹO]"_~,^˱|u=+&bRi2],{(?7%Pv,i@.|eŦ]W˯mx{my6Ë2A(25|h΀F@w W" ,$7I>)7tjLW;_](NaE/mGJJPNOqu"㚢݇A|ZUH<P>$DbC pLW&? y/:T/ETN`+-uNI.Q3<'$(nޚ;jEUΑ :c]H\`9T:s}VaC80cORmj\o. ]w)W\8mϠRM(FyC@sUo=YrbwQmi@H B = PPIJW|R)Py >+bäf ϳ1o߃TնgI%ܕW&PnK,~K|'hMۘrK<4&@RZZ*pף(aL:z؝-C!5]̍ԨGĖqHBwc¸tkB]hѢjkQP okZxgA6GתoqM[O;o1j15 >Q,`L 0Kwnr­gL 0&`L 0&P?@׏bL 0&`L 0VNV3&`L 0&@]?N\ 0&`L 0&Z9V[`L 0&`# t8q)&`L 0&hXn?>`L 0&`L ԏ+ĥ`L 0&`L`L 0&`L 0&P?@׏bL 0&`L 0VNV3&hҏaEOd2:&BL'^/&㓫-1&0=VMϔkdL 0&[ߎ[vM&.WQvt5:g'f`L 0k! 11I]\ `L 0s0՘g٬Ng8CH?G@GÄ!`>&Rãf!aL 4\.Ghhh!`q_n'FӘ~=L 0&Ƽ&qΎix0D^BO뤥+ka-JBJJ <==ld1??k@K"ee3vݿrI cܗTB 0&`@@_oSiuy^|r [I:Jsa_)װ04++KR4hie9毐X6b!CM!9*hxL,$`L 0& Nn&i%87$ ?:;5f.`@]gL 0&b Ȼ؍E'#V89/-wE6S 31&LMhS`L 0 `?`j@\\u2y`(~O E<+ 0&`-xذ'r2&` Hs)皥9 0&-/ 0&`L 0&@=]H\ 0&`L 0&+`L 0&`L 0&P@aL 0&bҤύbz/l8dL 0VOV`L 0&,"vwBQҚOm&WP+ޝ U8]frHL 0&Т ݢoݝS]e2p(~6Ob뮇K0&0~.S zj󎩸MXH`L 0"a%C`vYNX1E_ƜȽP1^ y1` s&vԩwgI@y '#V¾k=y*5B}1(lL_%K`VHh+|h&.l>HX5'׿)2y.!GB r-RFFc2]QrrԄ2Y,PYў={0k,Y 0&`bATyEL:nj *,pbL 0&# 1IcV<^;jȷܱ-g TC1.Yۻ+hO¤k'OJ t!::e63FIllpATc^snimu쎙 "@S8+91&0H<44`c ,--囑@I1lWY/,d*.jSSٌBrL 00՘g:&nl݉/m/ t;2S&`3TޓƯZR,c"bv#N 2LGW6bnWݤq-U%&>ىL'7M_B4}_v8Y.J\AbV&&`Ƣ]2醶a ̩+ZHl\0VتHOOGBB挲1ա8<9sU ,ⓏBf\9 0&`x5>J2k[/O\wl^.gcbhז!(tvcƒ h,`.vLМ`L 4F^x!1~hiݖ"Z80%>w`?G@ cCT|Lh[ozGEEEfɦIII,[KConYrW8:j7fR?"!A1w+" =&n'g]Tƒgo~t.I_D|XZrw@IDAT>ōuނFU_i!B0,h惘ZyJJf^"~>>~8/\K^Mǣ#>]"`cUb'=7oUáAR3&`}Xg&Iλ}a֬UU榶#b:Gmt0/L[eL 0&`n?koaAuW# 1Wߎ۳~ ('rGX od3Tl>WSj qw}Qh!uxFЪtF&{NTQ*gLZm-On3Suw\Dvk&DժNsl~Ex)| 1:cL 0s(GT([n0G=@#d@E(ՠR][ 5FAn8WXI.s%9~iHW'L XV12捯r1N"O siDk5O0HOOBB "Wޙ9{]0pmMuq \K8=2s9 0&|:bh}3x+zU9 lrc3&PE7q$ |!.8LjsUY.w%yPω#AXU_OP<ʛ&,@M EF;&իɸ1O_F!=]}bwЩ T]T~ǔS G <#Hy1]Y5mJMMEii)YyJJ ^^WB4O^^QϲOk\`YTgL8Kwb.X9Ot 駛$1l0=g 8s Y?Be.bځъΩLn:('‚&]S^X'Ef `Kh}4uv3(.}~U!+([E12]t;]L8zĚtq"p F-kI'k No2T:4̕!6?d c|Xt% Ǐ%z^l181#6~N_&kn=}DhhVWu>#Psp{ߩy 0'`H|YB$~7>9/*uIHNT^LɕUĀS]0ɓ'%]^M)@[PH#\$äaK Kem|K\.5&N^cڥ[R{{xt`_]p(y.d5ʼn NDU{{e/)E5 S:0vvqV3 R^-UjNL XyLLI$&>>>&+@{fް%0mɣL/ۈ)ϟ= ws"7\QyZf]w.➨8m1s\A+ͼ$~f9%jINd=Y(vVfJH Y4O@ jT 3dWf#ۺKn4d>@V[!]\1ԪܦG;hdmW d4NG UiQX9~iNL 9}yhhI_j! q}Tm?om#ӱ=b^޶SX{{5 xE0 ?/^I9"9^ثd3Şؑ3_N)fţ.l_ :0DȌ gPo\ϫ0)mp4‰ 0Z j̫Vr~vK tjk% ENvqI 2t aj$bE6)&t?~%D ݜ0slmӤ5_<$h;`>x[x̔ ˈxiӘ|*S@#>Rr9x+@q2}7i/[~cb#8~;=\qg mvmDžl/t~LqbL X=ySeĘmC_:hxw;`z8yi; !ΪwMk~._;~-dd_.oPziOtwy 0# =zI_Ia[it1r[W |=䋪KuK_Wt! )ϜG ̯oM5Ia/ve4{hQ@a7.%V ; `L* !x $}4߂,b1k{hpJ=*Ť"߈` %=\bԫ^ kЅ븙wCwv`w1hBL 4@uUA7s#Bᡗ6\5>~zQ?Nu qěZ.*S *Ͻ:cjJmPyw E72{\&+E@Z+]LG,Yu,"E p(vAϻ&2)/6ghn{ nm+5RI|O&@7/F=a&<-2 }xhpxOCj7,!6a̷4He2i/V9 1Ĥ{ 0>Iٸ'9hfH(3RzARj `Lt Lj.L_yzFv<8͋bY/?IF> q3w3.dR.bM_TL)'޽ ]n<&k(WK)b;AwBy.H.QhaX@hkxJdl? 1+3FaO>R/X(ү8sjYp̵ʹ*pw>C]Wo"~8MWI&LK: `L$05n 6.<ѶY(Fer`ȹM XBZvt5:g;o9< gkW%AjŚ4%%Erڜ\%IRK MPcNv>r\ j>gi)|8Ņh"PG]Ķ#op^S_Y+G}oHECQJ42%liRņXʊ\' p(!1Qٌ 6 M^HrX/d(h^A{Ǒ733L)U|ڧ|Ub>,M3Nʢ؀O1*QDm4eױUtAqbL XAx;a'x'HUb@ٲK]vgT@U칾ӱpţXSI9JWmF:=>`O~RWȣ̖%Q̰4Ojq ey2.fF) ^F܊ )psopg#G Eb̦eBRO_+еj(qx-.#=7'~EߥǬ1X2heMS"Bf"GB:(!˻$p:qn]\\ݰ>}2A.2d) Hu£{ \ep_'z7>~澭9\yg6D8J7V.n[%j%׀ NCk\ ? D|EP^UZEwz^(tKWp#Vo*n ;?e+lK81&rd!dW([F`&3'ı moA21#X2j^ *ABIZp}9LH+_jz_rĞ{ɊLIxA8>_u)EO1\HXm}q5>hfW+;\@[U^.W#""p|DDN2) CyFzΰÿ>1*r@̲1p8!Br)xW?=X(--aU%4|d4|mleX:rGdw")O껒|?<ꖹNe ʠ)"-hyVib.LUnn[mgLxƳ6=ͼ\tqdtȤ:ȸR/Cw#?|a9+V\rҷfpdLDy*}"bdg7g;J}duW%@X^VfR`gJ+b,D ]<1+ l: 0oXNJ [cVeiS1^AB54tpbT/^3ŪTCb-U[37Qny ~# 8ȝIXה_ِ,IaL64 Hi6>艵ʿECq`N /.= cXdOd2\vzzZp{vۼ GD mS \[ltmQL ="lDQdUh?/z9 wKq[JelIaQtRT$[Bsm۞V;V:z@}q[" -k8yx9Ā©=͇U2\obC\9[1VY56![gOQ\ZiT-߃uIT*V.\-_b'>!HҰKz35=wcw ACiY_J 6 CY[̕Lo%!0Pu5oA4bc"NL 4SOJiJտ>rA`}Ư;P; 6߫b[EKˎǞqhw?Ϣ|ڿBٴ1QOxfR;ᢜD 35o.7b,vo(9zw##X _–M-P(eu88$W2oa> B]AH߹{&pVkiL Rw$ s!A)wҖ4HDV^"J\G}soC҉L2`MI@/^=p 6L ݸۯϑObV/#y1: YסK}VJ_.m_NL%_n)gm5&X򘘊}D'HNMB1a.l ՛ q쉁2btgv{䞃FŊ"8 U~ G#coG"Vp/7'2u bVNA9EA \;*?oabM5b]7Of/jR]F6:_y/*hh"{f#U|@XdQ+WⓏžB1MĵS=1 +wֶɷdYI cܗiDڏ[0xrPlYt~Gc8B3'' 7EluuEHde ~,!!2gQ n$Vin:ėM@Tc D*=+Gİ98VU)J5&b J~OoHH;%4&؊%{7g?ڒARBm37sl|ZYHIwt3נrjVD691a ƺc?Kq%]fu^\ؘOAQWRho3yeYI@hկEym?h>%ry> XG:lsL~ %9{y4~UJ9:)],fۚN}kn י_<+k>۴#hn̍Q,o!sp rɒ2u85jx[XcvIb>b|2d"L7mCɑ0F <&`u*^V'{8c 6җ_g25(D y8n]cJD Nɬ*ݾ;Rȭ,k̗$bڣU=4v%4;S NL 0Z c(0y+ϵ⋭x=hv#> O">m_xS,Yh GnϓZ̈́=+HN'q<3{m7͟MUr*Nd8y 9QR_v})xCS~Q6.v^Az[meQy̳'׸L 0:c&]1dQHE`D {,ΣoCĆ֧CuM̳O8Lr j( fZŹ;[y-+V]'؟eG{Ŀ>~۰ݫꕔޞ֊:Ȣ6;Dfi>Ύa>O̶b7}\+.F\Ry3#oP{y4kX;3#SD=ҪN R")TR'iV&;~`If/)"5~2ko =G[W}}Hhm?f;kq3`"EK^ bC@wKא[݇є".D |mGW嶴ɻ:z⛙`ZT59aӰ6 (H弚{NEbӭqӷ-<j<q_>3s"B{%׎0!!$ОFEEI_D}ʬFD]mQT2ڏDmJJsKI!t8غݱܝ܇0P&+ʎ8TeتAt%iZ;K"߆і'`MM@~J7 7^/ܕCa _{FJxA }u'lܮl0eù'PH" E&<+RTEk'ڐi?mgvm0bV,i p:[޽K+ [,)č8߼2ɻœhMXڧs"0a}]m`̌DmGQ8`(\1~ǔS%C&υ<RHـT鳅e+zkԤJLC곦-).P,"2Y!@fAVGUmГfgnFiYՉ)vG'zUфM]Q| Ȼc70K [T xn]aY[c™8_QQġ?%nfK< -.C8–&mĸIߛj"h.@M! rJ:=XDwRyCũ}[1TX\*2SFJbpnk{8tD[{?j۔A2y.ڈx?-u'&^H#jgM| eYB {7'$PF:%s`D sA.YPݰ@g3;5 Ǹl|@Wn}FX-S:y$T*YX '/TAŠQ*˧1*ĥ7(0&ʦJ"d̽N.ӭ47[WN[aU9ݻAwvBͳvttm- }cc~)ЗO&E@}?bˎ#~G>Š`83 [!Gc7{G;IJ^Qjֻq01D78٬YF|III$ER-UMRD#MBM]2 Ma5Bs2Zv4-f1cPwr)".4IMֲhؖ k7sn1)~1G5o4(PJGjAkg?B mQjC67yJt/5pϧPQR䨐Y#V̩/J=p ӾF;yx8RejU#\麕~mGUJ5%oiưٮ0H}"OY!7$ [YIJB7׽֦Ȧ$dlSM*yΠ>FJJ4nJ@ՓCj%XFN,O)l'&I(nh0^\QP+ޝnX?.>fm}8kI=aq0b%^>)ze 0)ZoI"MYi+>dK~G<:ëV[f"D܂IQ&J1V )z8[#+2A/b7;w/|w08;v%c3 *8QRU شb i=ziock,E!lqqͭp@[chJ$gtp".:I8,"g4.f1N7"+ӑp)G Hr P."gWC]_?F F+v@ȿI|;;J䉙gi2bDFc[z0w]0Q_/vNhM&`XRPݍ7◸`dHºj¡ tev vh,LJ;vL-? '\;K8 3H$:EF^ {M:=;H{LEY̽Qԣ6!dړ ُdM !vL͒rrB}0>G7b=m[Le 0P^¦勇o!Z/)Ѕ*҈CH!NŬNH!ڐ' mO@%˜Cqhnπs/x8̺A,7E%"IΦ"Vnń$,ں$D$0XL(LB^s$?褹!%գVi\^kb[XvC$:&!`oG%K%-d^҄;M4d66k])8D=3 f4oKՓ'n_yZ(+:y_8LNk鹕). p/R^+CL\{'9~9X(K£8).rQBRiu:̜ kZt\Iғ0U0ۛwАz*3`XfGb/5.-AbiZu i1dB]ݼ$&'vМ.%S0SUgL At徻;vwSh1bIKCe}Kܗc;"f)-pXK"ΣtBbgJD=I{Dž7WC@Ng/Q~ N.>'o107e-7Z7Ǯc]wWІV!_.c܄#1CxGG^i=_X@SRݬWXwZ/=K{I4G4"!pB-j32_6s1ɐJ&GR0=ĵn,#n}RFC!9Z>Tڣ-K9$9 gkHb+Wٹ]X$/_>9ܚ8V:WǷ 6dxVo߯ڼՆ%LwC Փ\OÍ3dORaq.8,„ܗ<ʴ0-81&z62 iCK]* }*sLa8ɲI(l´Y8&Q|Jd,dnopP&92Q-}!}CQ9?N44d0 YDihHqGj\!,P&E$&cwH(*%`ڒFeIOxȼ&q1+*oL۶E.ݔ%eZ)QQ <9t?-xKfޝ;# tNL l^#f?\RTRdpW¦w)|f, SY( kW{J&m|IAޫ[-W4 8$C.F&D֯jw#x S|qMqh4n\WNxIlU" lI?^<qf%2eV^v~}J_ю<5.l0 mAG3I܋m K=0(eғ{!uc9Ġ+鰥d'^K:{4D󘀕P'aј֤l7 C&: vw\Yy'Yc~T&3o:)=Ѡc@)PEǖʺTdHe%_ߋ&ExLam$}vT,KףjRSpZW&:|zBMdg|j\wc Xr|_-s$v+)йY{1t#>F1N!\L5s^aX=QǾ9{cνkAbH3oV߮C` ScqjPJvbi&;zuPVw5% qW~r5M.&}%g!t-8cs :{J|} {ŒҷG |fᘿrB(qN; Y0a`g{(*8|N y Pr%, %- 痭9<[YI>uSs#&]|Bî˻-nr( $, (V8V=%(4M;]2Xg2s`T^E"őo0m,źE L ,Y$mzcӞ5E k .SN 31d\C hR%ep&#z9K$>gW.0o#p&2LygؽyRhfNp&?8#[i5LvXz_y~ju}B $:{ 幒#{䥸R>eL W,,hi}De6Zn"qbL T"Q34PoGe%62kt72k+OQM,gSƯU+ʧ-@:.Ez͋g$!3OM6hW{toWI `o H~tfGÄ!`>&PTTqϛpc"C^KCe[ M:9RԎdt],-+ r].5UfFF\]]9nX61&.~Cjr*̥Q#FѼ"7@ou +<9դ +`J%,u[ .oFJ7z]oRCO뤭L;uE%)dٍl`j-E/mmLmM?)L ^@N52ۦP%b1#wpNcbbPxQxbR)?)7iq|7cHQ=ƃ=5ggݾ٤2&<`B:61 G)'0|_I1"_M!++KZԟW/הl>XBnc&UpNʴ;zΊ% rk<44$$KKKTƕA@wIx &yGLY<i_/L 0KTc^%Xs#`g?;\Iѥh"@CzeE xt[ʅuPK|CBqhnπs/x8lQ ;`VJގY:ve]J߭mq.[[5GK(Wݮ֖:=Z2&8pB'Nj0iqh^$MP>a'۷LE1~K܆<&hX'λI | zwwxbrgVQ 0&Zyyxɍ;ٱKq6ݧj4ǯ;P; dęL 0&`X|^3aa߿9(rUަ\p4GIDATm}cuE眞Z/x9Gֈ8g] `L 0&`65Ie+0p.`L JZXEX gœ•Ƞ[/>Ěw3~$®SՕl̉ #p \;L(p!ɈpsE-.˒B<\_R^+EJ[v 3<Vdřv&` % tCYHyx7[<h>QZMrB2 .~דUEm̟݊H ,SN 31d\C hC/*"D>YRLu}u2ukls-L 4"5e y m! @ 0&N^j٥L adǝ8p z4c7oXubgݯjh8B_Ĩ^qFև8y$T*Fo ⡾XXr^ @# (Ă7\p{1a7X~locL 0&p)f&`5]ud $Co~F˸v._\鸆w1kE7UsbL 0&Dch꾻$>ſp̸[:PlhNL 0&p7ksT#t}j=k^Ya.Gh,"ӆ|șJ91&`-Hκ24 ]}Bl+q? 1 y|>ʿ%>ل=ayUyX<=X;:J>i \ׁ{0ȕ5~1 yۻO=L "Px .~8Жp Xv'+moEI*LRq}xO3'&` `q&#~?>Ug" ,&,@Yʳcj5 >\zc`XOlzs—!Oq8$>gW.J6g"ʔDZ\q`ccQ'Wti?rRn"88"iE*^Wṣn ㊯^Ʀ4%N V'+1Mu%`LuĘǩ1I]\Iί/W[I^v7 xj]a7byn\ 0:n!,mqϦ<_x)J? nLዼۑA+*aMep oC4!xŤ|TV_SyZ[H: o;kӱ{}{}cpcC=/1ա8}1sL83Mc{`LcܗqҾn2X /[s$*s;\R|gæ! 5H1R$p*| Q JQDRD䆢(UJI$H蕖6-aCB&ٙ3ɻ3s":/98%_\w_ M\V[NKPףi؏OM*"@r6]D,AeCtW3,),SMF=]@a7sTZJ?B0p8w% yZX+L ni[yXc7*.;i!-- r.Y.v-[b/qHlƒ+G6ILLg 98g|o+4^ w?$%X-c1蟇ESvLS_eX} ;"V "P(GZR,DIX$~\][AYbÿ}e~=*5ԫT >7y~*|&X4E>c@1~8>r%vK|'h׼RY/լ{`Gl>&5Z@C A4oq0v='N74*(?]N<ۧOYÔ>aaK;{?͖t-qʨA RJ_ (f4˳ 20f)^QSk{Q_ҰNaqcr4⍁6fm1_f]U h&7oyy,9::Zsu,g,4o G9 `pHqp^J512[cY?G~K ?f%DcRFW9!Cs(@ X^`yhN+Z~1F0"TUOF彡h&3b* P(Bh F e3$H(`=&ֳ~aj@&ϟo֒k@:p l D]УaM P{}c (@b bY},α=&yFҲ-4(PS (@ P(P@;v[=ȼ[BΣ(@ P(@s 06ӖG[o8>; /bTk5#vpM2Ǩͺ`W'cfZQhZ81Yk>bn?=bG P(`%eLLY~:R+)Lg2럗#])rYmq:*v_gF!`%LRI zcf[F9]9B)ܽޛz'65m\ƪb+2'8W}~+Q9K g^io1V PS}e`yznΆZ.{Ɗ[XipEDb7a4TTTAxƂy}=oУ뫈7=Gaeƚ]о숭׵iiՂP`;!&Ke-[GY:>6{s5jYM3Ԟ&*qO>WlP#'sil g(`%pX]. [> WnƴCaMeڮyMmzxf]{( X5:˨T8? uEcrawScʃWY gq>?E=]1vu<K,$cܫ@@mN#<1 (0֣>hvd^R$8P`]}pK<=fܐ_ ۇBQYBҮϞ_@+sW>t;#TwXA9ğ7o〵e~? PD rѣG5Pc-anܸiֱKFľMQ_stLUx,ӱ<cvCL[=! U&h7?<66b{NhR*}HkY285@v^;7`SX0> >b`(jIJJwW)SF猭c87w@6O$8<Ȋq Sr@YFR a[8ly.~}E%bN3Җ{mSz|Fa2F{^r%&mrrBq,DRl0NQz$7IwѓEz$99ǟL!w#c yD1|c2j PO8͆K,1%ד&mҺur0v]@)@ Px|ǻ5P@KP(0#R =8(@ P(@ P`Φ(@ P(@  064(@ P(@ PL(@ Pqx܌|L{jkS_Bd 0ԃD1x b2l }9Vo/[ϺA϶ZI`g(d 6&苒+꿯_z+bloӘ8)c$fG@c/8p] .U:o@mJ[k slY:! ns½.vo+dw<UڍBٰ8L y͏'HpT ;7O;Tx9eEz;>vKfX"<-C5pCzr>Ъ>{ =nNDz#CA@?w㭸8R*Q6$j> >S˪ŮEA>]o3p=GrnN[}e``YΆZ6K]%[ ;*`^=8cnf"'):9<6TS.`0${|#~A*YSE0pɐUcÏ ـM[bf/CTV4\HqEKxZ=U1 L1Ҳrg[}Bu;5/@6m}scb%ףF7uqC4yivG_Fnq R"զ%t}6}K=zƍ@@}X<%\? 83L]d  5 33^;i6:YOǀ͡h޴6"@Q ݾn@84,vsF&Ah7KX-p)[3_϶.5%\jMbM1D=ZߜAM^ )`N3Ud*̣IǑQh}n.NO@ *ԋK?Zz8# qr9gR;~94WըzUܭ![]O{8+LN}rDLVQ7p\<м r8n^ܚ蚟% tv 3tv,-aqD_Y%IJD#rhA?}݁Uv像0LKV`@pR;C)рk_ok[lAl~,ĞDW P Ĩ87t,YnWkβ ctvM4tw^D4sl GOM-ruj֞G TE0_mz6r t&.vjs[ĢDe٦P ~^V\b˕SBz%]-! CbnO(j.VCgfZ zUr3Ott`|J t\zп 28^ls=E'b_:[~WE75uᅧ/BCzE 8_wORe/(Pz>}𖖪xjB0#C&f $஋;k~6v^ΎLRRR'~2I9sÛ$blog9?硄 XS|,gg5vZ?Uj&˺乥He,!ő<|pMv/^T$kZ- PfP1y6 *񔉈Cx0y- aYxLo1 t{ GԢ#+q8KLݰ?팆_*|+S~dVYjnҟQN9, K=6]=S-+(@ P(`3)8*1;aв訹Ey -zq/ꉋ|^_s̑KxWtz)GVz1j]|Q|(@ P`]$ P\iaRݞ|b%<'KRsxš@WCQ [ۜaي/0)8}$j4]'p(@ P&Kl1\G@p~ 8ֽ;>p~(fP)e~ ^USKV3S 0}dsdn_Yh Nsm|(@ P-6\B @PYX4~,V<96ICj(YV|U;wbZMbʉYF{l>z}8&mĴHmAw綵J P(@ &0.%^P۸%zv+C"Z ëYƳxgi(ꇨ_^yQz,D P(@111/1qmZ,N,I-g`-9keu̳LtU+-(@(`200,,u P%u̳DlV')HJ/V+ JebV,qg/Vߍl(@ P^2cY5jcUTuwZƃcBE`.(@.`n(@ Pq/ 'cqxs`,>l]eqVNe S7o@`]1(@ PHt;LS'>-gk@}#ڄ-o­QȺY()In(@ Pc!O͚= oijBR-bU\/N>OJ#( LLBA0ӓwᓙ_`Ùxg7=e7`)@;`m;!Q(@ X[]n**@?Q߃nbϒ<Nf?<4 Qڥ~лf|{ϟXQd?:?S!Kc?0 P(@ (##bPcCcJpU_L,۟e@y.^\[֋K4OOQo`cgY@ s7)b.y7Om·H1GSlM5| 0=ø(@ P+PY,JK5 1]S]۱fkAOG^O덗wNmP(|8uBcrdžJ%SHMH|sõ3(`GLhg0 P(@ yفc@,woCñd'bCM¯9x9u0k'哎80>XpBI K)@{=(@ Pm'MxVD+ǡ/aw;qGLF#8{-BVMzi:~ʫt/w%<ny(`_۾(@ P@Vr0#&) W<-,MoF75Z>M?% bY{>u>3l73C Vgm)@ PA@4f!p4chW8u blq BeawsN/9#YuW*xL;9NL{b{m>lR;&EWEu{~)E(@`mQ(@ XS\wp?J$bo . z9e_&ޝ i???Į^ i&=Sś~ckaة+u:}?*??Sv%8q℮Njʕ+Fp|= P#** G㾃@_@Nz n +e=]&D )pã"x^ȝ0R8f͚O S'C}t򳜟 u7Ðypb(@gRl1\;+n(@ P(@ Q 1Y(@ P(@ \&%wr(@ P(@ P(@/Ef'(PѳB#uhZAsqlxӆros01{V7 W0[/xWόFb֭q 3ּקpc3Rcqxql{.9KGJͶ[&t*.m,+^g~r(@ P[ M|f ' =Ywp%,~); 6i"Z~H»\.(\9B0 r|= j g$#Sn1576qF^$743n` )@`лS(p*#+,tR"SV]=S,p,tma(@ B'* $p8N_/T*%otCz-jb80yޜYs\Wjl #k=$DAB$}f}H4#N![>9[!c̶BHɶq̗p÷Zsu䬊Öɘyڗyb 5q6ߖΞ;W €RU3 Y".N`@|0 PWa%tYmVkf:5K+p+>g͵%sQ1))c!ؾ'3(:aH!ih4Qiq)Rbq PJ@ۓ[m*m_8"/CcrZ_jOa?n^a-Фo8t#:'LO¦k%V%_UgRM9evx:_(>w}& MG.M*"k|wÇ"C*s_2nQB)=*/ YUp(@ P~>}OP BJ H5d4NGm}]!i2V XR8}$H(-ݻ,g P@ P'9]QN2ūk iH\,NP=e(@ P(P111fٞׯ,u P%u̳DlV'/(@'`200,ٚ{R+(@ X@\< pUpS(u8uӎ^^^ؽ{7Ο?o:,X@NNx}RƗVƖRƗVƔB*U)2F o$oD0#$D0#$Xov@&ML4-J̙34- 45̈45"45̈.\0+㾱R}Ӽ)MScL+CSӼ)MScL+ch9...x'L2.Tk!MVJ4-X iZ,BW(t9.fEAӢL_NS͊ZE 6(y.(@ P(@ &P(@ P`mP(@ P@;@ P(@ P0B H,B P(@ P`(@ P(@ P&F (@ P(@ P 4(@ P(@#@"(@ P(@&P(@ PP8qBmD9(@ P(@ Hf͚M!{bL1ҽr~200Pg93OT] MͿhJS F~Oij~)M/`=_#cKͿX#(@ P(@ @&%pr(@ P(@ P$lQ:G7ۜ|׏bP* &Fw1z+=XVp (@ P(Pbdҍ2~8V6YUear3XFr˘@k(B P(@ P%D@@Nd,sai} @?WJb'rE9Z p(@ P(@#?,41\XNJ嚼YZBAɳ'/f-8P(@ P@̳< }_ILthdAfYPV m9O?_Lr(@ P(@ 8̇hxBYDˤZ@k h$+tik<>(@ P(@ P%E0''DL%LeA},h<3(@ P(@ Pg(h 1, then x = 1 - w. | x is the horizontal position from the left | y is the vertical position from the top | h is the height of the chart relative to its container | w is the width of the box Mode ++++ In addition to the size and position, the mode for the relevant attribute can also be set to either `factor` or `edge`. Factor is the default: .. code:: layout.xMode = edge Target ++++++ The layoutTarget can be set to ``outer`` or ``inner``. The default is ``outer``: .. code:: layout.layoutTarget = inner Legend layout ------------- The position of the legend can be controlled either by setting its position: ``r``, ``l``, ``t``, ``b``, and ``tr``, for right, left, top, bottom and top right respectively. The default is ``r``. .. code:: legend.position = 'tr' or applying a manual layout: .. code:: legend.layout = ManualLayout() .. literalinclude:: chart_layout.py This produces four charts illustrating various possibilities: .. image:: chart_layout.png :alt: "Different chart and legend layouts" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/chart_layout_default.png0000644000000000000000000002701600000000000017237 0ustar00PNG  IHDR?觜sRGBgAMA a pHYsod-IDATx^uGuuHU*T)*TUTHﵟ"%#ނ[ &JN55S( 5/%=kٳgg=3xygͬ=߻fEfao)A{jd{W]YtA?Yъ=$-k VwagYr:uA?I&P7î|"4n֕/Y-¤^~Xqwvcnv rS!ofmȡKK !~:0֤%~>LC=xT7]N{>+T׳fLyݾlڟ𭬏;0>sz趾8 fml 7ßYub?2.:k? u 0mLC֣fW_mTYci'_nȣnuf,n_?/[zgWYۏ)Sƽ8nv\*siu֍7CLVe ~|XI5wOq5>'{S0 Hc;].Ïo|ܺ>9XFPaLjlW?>u˜A&u`.? /g;ڱ[z(Z7y D}7~9ԃՔx+f<0Xƫ>3Vкf[Owv?uϊT3LCBՖ'~ ~`#T7kxL!w7ƷwͿa)mw`joR/5́O|63}:dgMmY'~-_~.?QaAiw\7X}0,T^,c_}P]:A*TM? Ygz׾ɫn+?>ՍԼ);0Htq6vp3/SsK++ q`o=Y'eܦ9+{v q%TOoӾSݐ-.Y=߄Aa9X`껟jz ~xNz(\&؂mvn@f/M7刌Gcz`\ 80O8PtGL]u@Yie]m`N*zhhW{b0l }\4Hvi}1WsCh:EW( v@>>ǔqDvRҮM.|#LAoz,MҪ^hOb0@OD QH @ M  !5hd} E? x kbl@@R ~ )Z4ĄhSie~k?H $I@@R ~ )?+O1O2ٟ^eu$"۹T!.vTX_g\Yd&~Ә*;"~q:ݻz 0 KǞ|r#2SSY*2AEώ]hCTcWciO{Ȇ]hCTcf6ytZ]_b mHb v"?G~\t7:.1Ѕ6O 1H;Vq]hCTcuafVׇB':d~<]hCTcN C t C R:.1Ѕ6O 1H;VO贺>@ڐ>1 X!~<]hCTcN C t C R:.1Ѕ6O 1H;VO贺>@ڐ>1 X!~<]hCTcN C t C R:.1Ѕ6O 1H;VO贺>@ڐ>1 XmF/M]v]d?6VׇB'+}s7D-~n}VׇB'+]swv)M9#l:.1Ѕ6O 1H;V⧚:*;? 贺>@ڐ>1 X)rJ!h:O.Ϟ1jL]hCTc5yaMz?ʾDzg~={1 C `-X)RЌ?.EN3 t_N /K>]~gQ61cuafښ'-"~FxQZr]C?yvuuz â.?Oˏ!zwg} $V^(ŏ)d24Ԗqz]B+Ξoe/v~77mHbkaJWQI?i1iu?ͧ\"*D҇Zر?%Ԗmު Ze3S1-_ѿ|ն mHbkaj3g1-qY~YN /˷z>m3 /)C҇ZرOV_/)`l+Y7_t~VL2!}+ES>e#S.bdSAE'|-B҇Zر T|rk]贺2]%SR^=.{ʧú0 Y5d C `-XO{U{t-<7=b~/VlP(ey~f7v2I򛲐zkІ!vTOx(\%f> VbxZ:.BnP(Ce OWJoi)hCX ;VԖ-lNj>5V8 :.e?[6(/ɘ2Zl}*mHbkaJW65O5%3%iuI܌ݠPƹ[Lu ̓PX ;V⧤yڙjsD=#iuI&AL+mPS tu*}@bkaj3'4贺AؽzlPSc |8>1cNK t3vBC `-X$~dT V0v 7[9>1cuafٷtg)_.ej^=s6(\91][ T>Bbej$X :./ um `n BC `-X^=\?@R̰ :./we !,̓PX ;VzǑVa͍@%xァsM6(ҁK@*iJЇZر?VF٢2?op8!~ O(iu5./|s0c2٠{a6$se:˟eokkx1Cw"6v6'~. Q4rs.rnƩ؝C6k3%ې>t5Nu3x__hWl +E3eP*4N[4;N\__bU5ld.w v=;|a'>hDz/)v\Na`Jusifʌ)J,zٝeď}=<$ e8GZ TrgϾW|է>W PJرR?'Ԣ2{*EY MƩLg14A^ؠp Ն:>In7_9Xuc,~ rұ1§%nX\p2q*mh.ùB 3(0SL;"$'BZرR?רNY,9QsJj"vb2&Sb25&Sd]X ;VaUszu6?g_sSČ5Y,I= ŽUޕK kֆdsAY#{,n篾n ӡZرZQTٛ,iu}.ކddY# .nG%vڑ~ kajO\@(Ò؆$ #٘/)bnGDnGF~ ka*5?ۃN Q%B ɺYg#v|64MudZЏa-X!~&@?c^Gl SBݒ2E%Dm91 XmbxQ]B_zB]yki<5 !mHb v?iu}B(CANQoO6O 1H;V^ZK5&'/PP/?INEݑ=x\B69kc!}bA*رPdzbMQ(Q$xrdi);'PM/C: *:#ȱMđ߫zر2sB,Q:bQ ba4v@P_R#8˯Ym9}V&B/ _=t. )؃GtbWscs:BZSdnmN{ߕכO?yvuuz ;} O8eO|Qun::tX\ '|לi?z=U_n~O4;V⧱?Ƣh30G7P4K\g$k/~T^I-տLHHݎZVbwjO|jHٗ${}Ž1Nu/ITW3qUqO{=AFAdu 0cMgdMLhY>Gm9{ʉKf doh lȞ}7.iغlfxiAQX ;V⧚:*4fqQٝ7`sM?ԣgY;t<,v=kֿ "2d=Θ}fL\O~'{/gϽ[N'> s }Ž)Ctli1:.EcLd)1ED̐Ip:631@_@}_:}M>wOIzbA*رPV>֑\oɿ◮ YeYN{1ArHgx(f~m̐-oM~;އC R)(Jiu@ݐ}̭Y4,'YWubdLK1 ؃G?6{aKtd$$GlHɗzbA*ر bO=UZ\AeKFgXL2)Z3c u>%,"tUԻ mC\X)rlc>uuezF)GJTO*I&cI-S d2E&E<Ϟ";^h+p"{. ϒ ;Vȹ2Zo:./bFD9ՠ+kJ|1@COpmy]QxM:~mỔc;ҮR2!)#7:SQ vx^ %tbKu0lЦO4v% [8ۤ-9O5[j++t99 (O Bi%贺>@%7,Ĺ YkYS$ߩLgW ~? @ tz~B"_Xڐ%y>&m)jbMu,Uewӕk㸙Ur9UL"?tZ]_b^/$WGfCr#$sd${?QvEFZ)~sCؘ>tZe_bE,uGuhC[?13:]$31w SPeulKG]__HNdM݆ -Rs=1g{Scy!n<sxc/~JyڶzJ贺>@so/ԋ,a%S*C?N;V?KPZlditZ]_bZT</_/,B1C?N;VJkpkSF!O'I4:.1EY+녖8LgQuI 8X)}L5hL/Ʃ C tيc3*6 q*ر@)nDn u^/]]]^0 Kڮ~/|?.?O|u 3#7z%tbKYQԗLmm( C$~ v.>L[/մ>=zM|[sčSׇ^HBfZp9ЏSAbej bJؼy<./]hCTcvOYďK(B!І9;_|~W< ;e6μ̗ sx_\{Xc*5?Њg:.1Ѕ6Ϲ/:EʹKo|S Ә\ە4B !>رR?fEŏY9:.1Ѕ6ϹW?'kX[t S$ߩLgũ7|Mߎl%aJiu}.!}d`\&_MQ#W[GsE~*uDGc/~J)2özJ贺>@ڐ>_({:ʹLM7nb|k-K:ӱctZ]_b mHb?13:MuJ8g>+ď'tZ]_b mHbЦ; i|oMSUUlN%xFRX!Xy^ U]hCTcK5, D!І!`̴4tNN C t C RAbejU3?UZ=?8s^-)7贺>@ڐ>1 X(~R^Z!>jO7NSliu}.!}bA*رZQ[TgcO{@ VׇB'OsmŴkaXZa` {7z%tb mHb v\cD!І!`*)sT?,x.]B_ І!`*Bޚ8tZ]_b mHb v+KC!І!` VׇB'O\iu}.!}bA*رBxB!І!` VׇB'+ď'tZ]_b mHb v?iu}.!}bA*رBxB!І!` VׇB'+ď'tZ]_b mHb v?iu}.!}bA*رxp03`N C t C RAbej2?iu}.!}bA*رBxB!І!` VׇB'+ď'tZ]_b mHb v?iu}.!}bA*رBxB!І!`*=s...Jeiu}.!}bA*رJK!xbw|VׇB'O.v7 73C!І!`*9k(q:ӮZaa#SO=U0]B_ І!@@R ~ )?Hyp03 1!:d~ jZ3CߡC$Pc)NK'kVB+@ZYXyR@@at\f.G.)!p,C=XZ:{?^Bl3 I@x :9?3h7ED?/#~Vxç (  vͻ&Gpː,˔yLߡjB,0SFAR~8 |3v#_!<S!& iB>>%IC)?3vz3ԛxk XHVƟ,@Cnyn*2N?sF_5ኟ| Yof* }7{PQ!fo[uK L_Z;-zMC?NJAWA'FtΖ$cI@@R ~ )?H $%~>LC@L1V1@@R ~R>ټΫ} =  Yn-x\)?oA$]vUgAmZH@]𩩧>=mUMFSh"fo=A܌R@ukL?Ib9ԅˣ3GBGLu Qz#X@ekF?'e'q]ٝJMf ~g`QigoEщ3eAC "g1;̀ಬ[ LT" gpJ  ~㦓BGԟ ~o-NI =B?fy@$H-h3/B%~'f:3Dd< ~$jrs_Z[1ؙ"=RC0-af V,i),K趆i, MLGu$iZge)S>;;he~k?H $I@@R ~ )?H $I@@R ~ )?Hyp03 1!:d~ jZĠyaa`mLZGoGBP_13iru4`*"Y ʚ='\#U+c<bF`enoo/ #aE ,XjmSG3/OsֱJo=eC @ 5Rklf0&J|lc?!@ @`2:>:X\U:W6•jkkӃ{'B`4E!9h}.ᄷutt.Ȱʍmڵif76HWWǠqaZכf5'A @`َx&©)hԱTJ:;;ҹAF+xzH:h4Z"K,r㚴EVv0yի^%^zoi\ezNVs57dz&Ш`\lOGm޸q7ȑH}+?C8L4pnP @@.X .}uNtq~x*1[:\z\S:thzH7ʩ*]v{۶mfIgFhO{Ǵl_5Yg1?%͛7ϋiӧ=Ks//_>ڠF˴~Ν٥6æCIܰaO^py)n9ӎ97E"1lmե_<<<(=QwkR~eϘq\.tD;3N7_l^М~G>ejqJ8@ dM: >kҲZzFWJ+9^HY5kt/۟zܞl.0M]V^W1<眳M,^L@ d?e]dA7P*P>/-\Lʴz©Luڬŋ,[ۻh"'L7a=^'WgϟEúT'жeR @@!p 0>W+봬N?Ë-K Qj:\R:xdko;w_qe83k`!@ @)΁PN?ȑQ))GxcSQM#w_I4J:======P=OqS]y@ @"`izͦ 0[[&}=>X{a @ @jyOCr"+Xqpppppppp @ @4Ʈ#^H @ [8Yz@ A'+Ȅ @bK'+]O!@ dA @@l dŶi8 @  " @-v=  @ UdB @%ۮ @@pL@ @ pb4 @NVT @ ĖNVlC @A *2!@ Ɋmp@ @ 8YAPE& @ [8Yz@ A'+Ȅ @bK'+]O!@ dA @@l dŶi8 @  " @-v=  @ UdB @%ۮ @@pL@ @ pb4 @NVT @ ĖNVlC @A *2!@ Ɋmp@ @ 8YAPE& @ [8Yz@ A'+Ȅ @bK'+]O!@ dA @@l dŶi8 @  " @-ض<'U"Y;)=#Jdj!@ PDϪ\ r֢V} '!mu|YJwlOJJJ4/skʮx6s,=ٲ\/۞l/[^gW~v{n_=+v?[_l]϶dsݾl{gW~ly>m_ɖ}d϶l}gw}>۾bۓ-u֟m_eϮ|}g'[^1KPo:dvڥzlg`)((eZ]\6JR>Zo"MVnZZߤZds+ßuw2srzo_=z2W im>^h]?_'Vs{ck(cA?MB9ݟZ7}~]+_h3rorz^2ޕW sLm5۟f,_+Zo&G?d9jt&/|t|_*+W[|]_wգ&[ȶ2R}웪>?Ї}8_?d?NW-WWKcD>u~SylOٳG?K_﷩>wxej/Ux_n rcwOe`sSw^nW2P`ySi?S;6&i}f?kҺzNsMIyǬfN?#>TXp^k>+nY1O719b> R|uWUud> 6>oO?3g /y)E&9}p '!mW76beիm[Gɞ(Βͳe;aQ};]1W.L3qwPWyv? !8ԑΤGM)\ u_S}r^oeTS'o+_ %*b}JrHqFGTo5UBOgO@ @ o<)J;Z%]豝mX닆=X$@ @0<6q9N >6t.h|xDxѰE@ Kx6\m]'e_U@ I>kۼHqy]n+y]D h҆,m^4 @M$#pmY$@ @4^[ҽ4s++G  @  pAw@eF`ddDv-ef9B@pW:@eEo*3ڿI'${{ӞmrUW9N*o]>ʜ9s3ϔy^:y衇ƈz[*W_}cA8p@#JHGo|. 8/wqvm|EoEwC.| DB>'> Y` ^h"+婧GdIjDOUVDB T2}Mu{x*v~+ߘ @`j\sk^rM7yQ}}U*_G?_|` /P>ɛ&k_K+"Au C6FRoHQ"N@ ꐽ!ٿgEaeN@4Q's4[N֯_?zݖ-[ .i4J0N:36m޼Yɤ-o=\?s9SFϭ\R yҗ$6m??3J7 C5O:M:Qjjoox@>{ nh4:>[t8ӽ}~@d1OV.XZSJ^9ղ gNy! Ĝ@WW֦lܩf[lhh%"F:Ju]'guYy^t&]"~yΒ^U?,^z' 6=-֡?',wяztP ؠǯQ`N(z:6.hr LMooE2iSO=׼f‹<-]z]n E;<﴾:?_WwN٤-[&+V"f:Pq.MًZ$@(Mӱ܅**wa2"4'Atiuz{{_|^&oI#NA;oq [ia~Q˼ZG-j>9U{g>-O{^%9oF wliDKuk./3L)GnݺU>{Oy Ĕ")hE՚5kB躙'6=i{2?~)^xa4 @J@Ш… l;z59]gϞ**^Q|^E*T=sKO):ݺk/K-~E]e#PnJ*\er,|a(Min Xxq yT*",ϮA LF@b/c  lT0 @ 3d匪*fV9|+]]F[ @ .yM{~2\1 a1@ T | -j0\ͤScP@ &NN&dcvͳN @ L::6/XP2\h\̄+\0ȵ @@d9t*lUysP@ '`6w\,c*$P@ Pqew>Ng5'.*hX @(!}N/~fuTf%IG^ @@9kܥ tI貝yha qQ@ '2 oԘ)k:d9&n*/eBDw @*}ޮ2khYs '1qY#YF>wbA @m-gӯX-o/\iC6wl @ PtxY%hs%喷ӡWmB:n1 @ ]A jtgNKFG PɄ H"a6'̗W#L0͖JrBFL)G:IwTQP_S-R[kdF٦xu*  PN첩8Y.i]I>-Z!Ě@JpuɠLypP8V2\q͙q s՛fYjeq5ɼu2kf̝Q'sjeެz9N '`Gjar|dF v :@R@ztyE[̱f1 IkI͚=V̝&'̞.KMlK͐Y ۪_v=O}}lw" !7!]}$q|LCۮ6gF,[ 'ϟ!'-hS0[ԛH !`6FRqQcD@th_{>i2[^T,w'd.o|LkrҙrƒlLZ@$`6/R\^d八t$@eBU:jٶ}ebyeysǶx ;etyrs0@% /@t"prFEE@M@UGMؾAb8> /:N-9ml,Aq$^2#ԾYnCYᑤmj2jEg,ל1[̚*NVt%  n"Z^4֋Tù]HwyomW7 f.%zY U #o<B(jI/thYs '5>]WWҜ@ hIf~u4El<ˑp"e Wvi {~_v '%m:UҜ@ (=Ju 2KAo;Ӽ-/_,PՔ@0I)*¸|uХql8`\@ `DfYgٍ;]ͽOoo͗7|Թ5qC!J"`mm8Y.itХ}(B(@svsxYp@&#fmͪWT^2{Fdqr RV+g] έwd8$KekP~j )r+ș$@L>we[p\6Se0:qQ@Ev~Fy̵@"H@[l3̔wrYpTHS r%_W_v,}es)&$pshzXofʜ@v=[< W\T.5ѭi<6K!Gr`i9 GOKGm#W6eϑC@J6փW("7Jxߺ&⼥rūȼY҆X@A'y?lO;['9~BRIt\u5ZrCfy9 $yV%v5m@+1feN(==,|? !PRlm|HzŘ'dRrTj޷HzIp68Q'pl>k{OKq\}(B1%}-kd8W1ʩىdJ"Onm],D?@?_.咶ult?G˱)"C %C C l~SO}2Y²y: P8lټpI^I$+_bE׷l"8 ➻X10yxao%Wr\uI2&XHbOŲK 8Y.i^r@lu%MmӁ`]/'uoX&?gQ9@03g[8Ynyg:* ӭvr@ںɚ?DTb f!AUXĘN?DHر   {]Oj`|Ygs;[O/=]NYPe#a^fqw:'-oee Z"(W-]eΟHOrmvC t{kwnwDy'ImMu6a B dJ Ij~yQWP dJ]dܶ'.?C/U ȀbG Hsҹ[|M䖷xOc@I #mqED;EVi(:Wv S%DWȥXFB*D@!Е7[a^, !Ge|hT+ΐY0>OK!P̃K#57)DrTZSy~bڼdJwU]VcꖿFYm{'Aȇ]p\[l]"Yz@ vLh/@ ȿ~i_|-eF}M@:IpAbiًf@tiuG)B B VvG>uřr ,Q Ȁ@eH/|aM󴬹pAGYg'(@!{H^8X HKנ|랭fp@:U^6 &ã+ַJr! 3h$D@"۞'{LT\vqzk 2_vhNCتzҞpAQ /O7=oKKqr2yFo{m6@;40\%mOW:2e~r(@GV]wH2:. P.ew'k_K|gI}#Ka'"`ߏe'OzL*u4 Vs;n =*!vfcњ "@ pN;EÕ6dis&0ayv x@F`OK|WZFs  %d9ƮJݴmA t7h}>,J%3$߼{l>Ǵ =@H18Q`duiך႓ $,tvP !(޿Csu6M@ m; H$S{=6P@cmnd8KưYU؅JNpyb?pOe#>{6>t}:XJ%;pApw~O?.< cL`_ZYSW1gܡ8Ya{8bF=B9Z=:@:Iԓ6[Uf 4vB%"1 ߹oD &mrMG@vJǫ1 't~,=e PGwt-AdS<Jܥ8Y.i]^RX:\0;6u({۷s;nD HX]ݑ Id js|A $2uK,>I}NAc tU~h]{=@xz{$#YF iÖ6 B[C#Cee7BM޵M̖@0'+Fm:YpAeѐC`RÉ~`}O:'I@A=@G bF"u_!5(@*5"+t5t=A(@,of!ƶbEq= NdsGj=58Y.itζE@ ?#[ @-oKGCݒG#n:jI(6NV `'ټ !\|Aײ*-@9h[.CüC I@z/ Ae<;۶Z#W6zes{Km۱ك 2=-}Çwzߐl !q>o0w"8YtL4rm>dC\ twλʵN`͞ o%̓ %U("SK͋( 3[ @T zMlNJQ/}6wM'1erl e)ynǏp6@^?%GD>_g쐼F2Y1gK QN^ݧ@ zGa"!L2l@ duXaف^DMY)&h=SW 1l #?pt}i6=I1&7aq t@ X̺F>k릉HV?!yXGvƯ(dRt!j@"ac਋<掭ۉr!bV{sJ@ `Uc&,!v:DP\{eY@(Ooo;%!"X:fvlHy^'0C#fOdpt@ "n}bvtfčTf\+3'+>Zqp4n5؃@<>Rtv J$geûӋ\UbiL |+R-rx)oӡ^ݱ @[e_m!J`ˡn M@8 01;,3TbW)Ø^ITrṝ?Pe5@4fu 8ޅWSAX=xh"B LɏmX e=eswVdci.hႎa=$  @cǀv5Ga| 1;+7pBl<$3P gKw!d™NA _<$[bv@ h*.A '1qcoK?  S޽7m [cVtm  o2]?V]vkKw;dþ{)D +A0 E@ y ΅M$+{~e A1'nf7/ 4 f>#QXԩ2[i6N[*/%Va)ͨ7Զ>h= =$rV{A*<^6NL=Nn6V#!Db@34( E/UێF4l@P4`Fzd&G,]>!qd"AX?__Fd(ai4KټDs#RU]D@W_:Xt @"՟kxwVS*>^PA8YotRCL};n2bJŽwK2cʜfCE΁2k!P҃fĘE#p\( tM}!hj(BЌJ@C Lʝf (1uceJNT:Ζ& 'J.v@.![tPć jhCzr}Evdbv@IDAT'mƫi- P =_IÐk!58Ya ]<,; WP" T>m䦖o(-+6Q,-r=Lgk9Nwdňp?F-JCJ`4P`r|`o@l;6u@@"IF, xxrQi"ﻀJ ]',umݴmA$tEVb&B dH$SfnѬ,,B ',SۋdtUi+dt Iͧm6+ 9@J%X퍏HRof JM78C9Y.4q*=pO X !@@ '前GA@GyCu-.qRTհnpL^ Ȁ+Ȑ+u {m<,#f!  H>w%&wBP麉ӧټ164!@ $#Mldټζk 4m LX`x\[^Pô.Ade'w""K`!X *#PwEAKm^r ɚM0g2`8#:zs{"r#ȍN@g0z;Bx7-a݅`iyz,]m@ .qh*m@Qt7ZƀYUh&B /f`e$$8Y{S=her&8d^@LI-$ G`n DžcSlNKڪڬob6ol]ۀ>LBIr F`kvF,@hlPCe d9~=oڐcP $ i ,^(FVy۩2{*0Aez!`dvn@N`A {beɪ~(@gO 'z >7 :}URuI[pi }Pt T8YЍ4h:!˾&E KNV^JYvK)YȏNV~ @ w2/+}]a/帿L_=~B <-],}4C(-] ,-P1̰dc&D@W_ 3$Q G,%laKe:fk~~Gw)C@~'̻&6T/˔hy .*C쯼F"@1&hY16c4\Ue6wK'-oA rڻwG&  $)k9 'ȕ(NV `džڼ !\" $FH)\@Q#NV{kmswӚp\Ke<$3Ps&]@!J$HV%v+m*#,|ḳ7msQ1:zg*^HZQrA HV ,3HVd{L @ :;e/!X─3n6dme$Sqf"Z;}~}8Y~!T  W)͡ȋFl+gyI)2NVqZߍeߏepJ@ LHw^%" DHڅQpF0'!lUU ]WEe;6ufT S @#N(*2$\~ N®f, :ԍo-S #pUZX=9KS)$1)@~1WB@ '>`H1;Z,V0Ɠ5pAݴm4+@upA T.aHTni& غiJ d;tfuюwUo T8掁 o!̓EdMLbΨ'm6ހ+}4̂=Dʡ@1vdÏk˛h|1Ds-u!P$v3dH\@ ;#o#B WE!|[}{!@R $U}K&& ^gX=HȆ@D e@$p'8U&0A57]v?' '~L&0zdE0@ t1\Qkd鳷D$13+Ke闣 xݯx٨A@@Y>r ''%13|/|@5DvBpr%Uz9X:'럿1#dhDN@Ag'2zVC4kc |z$u_Vf͚eUe* ZD`(>daT @ 'e$j7Hf,ubNk}}Y7iV;/.D7mJh$M1$Pe"Xg Nc9Y$E`aG/  d> 6 JGtN?u9J4y7Xc4)v}l};G^e'g <4 lt:%0䥔F8 NdVm?_˥4D ND&IMRXK 5.BdD*i0A_+D:Դ7PƈNbb@`dd0 '04c"Y!o@m $cj @  xj*6wMHc֩ײ$"2CUS):W@ *FRX6wZp\6c3PW!WԴ@$RwΖT2)iwUM81J,M\i'+ͣ?̻+#8X  ֿufW|X[[x$'k_xccײ殓ZolUJc ;'k[ @ ~L ;+_^[ShK"4G! TIK%9_dNFsN`pWVͬ>G8$Z.]Y4gٵkW+"Yq*%eat|\v_eY}DR P_ytTL\|̘1C/-_KB4l^9 !#UK/sCCA]t)TWLQL %n׸VM{A_}5LzØ]iU T-[{Mc7m$_G?s9g̹w2 gn '5SYs4'A 2nڅLN`I"3vh}n\hl}dE߂s P~-6449_?vZ馛䮻68ako~|/=i͋XD VKl˵IpCF7XP$oԒm;u|S{fh8Yvjd]য়~͵cpZ1r\s4?nSe/>%'29qRy~.ʒK*| aMe[͚ڥGI Oz$UfjH_,x>_Z*C j`WsT-'+}3(9jj<]PC)9`A2Q!P'2A o-;Q<'k.nmh@@ NB[FoW**jۧJ$HyNVI0#$M;;I>WS^bq=JvV(y:_kښ&40d))i8=O"y;H!ɊaDz'*ᒶ=-'G>;ykCaKj #zd刊j@@ =ɪ^ͱ ;Px P4e @`j'\lb5}(0=@)T*Id1Lrk=, d 8Z'p=idNm2x}h@fM#U6.)gŰ ;nNcK;6u1'PǜhE_d"! SE4j@@k9 觿@U#pcdM'Ͳl2[d? jYe]' &ytXfD@#ӼР}v\.yWCkdx5[oU*yO+VupNNh^.*Z17Dzy1V?;K!tIvE-r֪_ =ʫfG> ls+ |ӟkFd2o޼ڔ4A tT͋X8Y@+Y{CI eCk !0,^[BqM Sڗʼn].QI֍Z< 0..8.F@]]ȇ?aٹs{EVe+R&ap1NVЊFL,ˋdiNk3;H4uf(lj7+LJ'僛Moi%| fZaۯCg8a6c1ͪKoM74\90Hq7I?Y;n2"HawuQ`R8aTI )Op?Ryon؎E`NVyuXZh+mo/Xjjjd ֠& exs=?p6ґ+&h tJ~ Pqohό(%7*<eKjFji^; 뮓|+ IPrl^9 .GPf j~YҷD`4r/l@C"I=uپA,o~ͥ6Rak1\,&U.]k;O;4,2cƌ*_.E0׺B_gl '1q]B7M6Od;h ey8p=a(H4W|v9sZ:&p<)QR d֛3ܷ'9t$+ٺsP^7KjK1,yyw˜ڰ K#,\5Y^fdmt9YZ7u%0gƉ ;}Jݹ_P5S2k]w{g2nO`1 dܵ8YgyHf64J!tIvUJsrjGMN[+!/kOu5ղ`x>V9.dmt7G;6u̙({wޝgoT$'ʾ/i@ h ,=W$msdmtႪV$E`N aF/JBvV(r ;yG^]4"(Q.rIvʲ:xfV(oKHj ,%ds_[9r xf[OLv*>6M=j;6u̜>߬0`n%а|D9{//{W5 B,^.}A <(=:IGgcCէch DxY7Բc!` 4/u{.y[."'Ԏde7.NZp5KKO*pOZݼqIʄ|2)&{a!#Rq;R Y*{wZP_ٍu:Us&OG$k 踍d^"Y 3Y=,-M Չ^Y}{m3cx7%D} d9`y!K[%=۱Y X&/݇9|Q_ˁr%8c@"@XP؂srM܋\U,S-6iHm p@ktȶr 'vȂ}!U"KYب6G>g3'+?ne^y7˒N ]0{yYڎ$PUU#5+wų%lu2k\3zӗɊHW`F(:{sk,w:O:!`1@ .d+JG#r_'oj)XL`i2.d+Pxr]M@X81@ fIDټm^yͪgG^ӧȌ/;(V!?CZ,szQs1\%;]{.:mb ag-a>Vv@f𘷚{I '+Ht}9Zi# V; +9)˨&N >98$@|ϯꆣAC~g%,U~?}"dYYG؅@,^-bfY\O/ X<'a6whNC؞*u;ms6Yfa^VvE~MS 5#2Cw6ŔBrcE-}jr[UigoM@%t &`u8l3#8,ge3$Na>V]ԝ?]咶U=L;u8y < G@`Q0!0c\ͲvdrIS0%pt;?LrӤS6wl 0.%sΒ*>ƅTWH]GR[|xOMR_㩭GW.JLI@*}U~|ʋJZ'EXLyY@3dᜳhBr'v$[sH4/ok ͎8+>Tޏ>|.xasiE,աΖ& 0 40գ%ÏÇ?+gOѮk`4WLA'k @>m_FM!#Ui-9J$Au?r?A;t ҹ(Z!95NB5ޱA)b$5JˏI*}+$xWM%6 ֲy@dAAV MJ4A+3F`Iǻs?jV2?W\NkLBFx?7~ۦ.;Hd9.i]T鮍mcP9 Tq|d@5FY^}Y-?k1,^;%B%Y Y?j@,͵a VD@{GvEg"P%ro-e_\`oS:UpZ6 (DJdmtYj.kHӓ\&EWɓұG([sg+E6s}m+ϑdV+ԗYy\@0zZWHC[C?ZvFyyU`lF1,ǍmV:u(K$OS2@Ob: X3C1ܯ غo8(8"@U-t& Z*0H%s2rah0ش+ZKomѷޔG~ _? ٜ;:r\+tvc0$01y$soq8 L ISLIdSCXudخmߒ/Ğxh<,۞Nm MahMƬtiV. cYAln]Svy B@ؐN1Ū|^>,Hkސ.Irsw`i:ekky찥d4jk$ )~>&1؏I]m**X  ֽ!r|؅/67Lc9n-@yпz 2hC!0{{򵓿u k.kȻ7$Xy-"d-B뒲޲ @LV h=˿O< M(]x^ku_˶߭G0t#XV֎eX ," 鶹3H?w+@%Crߓ{r$[63s ;!$[[x,7ě/B,@23:kj\Qj`H51/:N6VN^ HӲf!3k@<#V;O ۧgOwJK Bw윿& hZw}%>[?|5J`rɤ[j>v@'L X<|zɝ^n\.x>t8 '@帍ldj50H$ҲvѬ0kۛvaWycУ?\p zZrٚKնҥY.i{9&r((+$jhTVz<>ëHݽK.-rYoXIEQ&`VcAu&;ʒB $f4kf5gt@  !f*/+UA,ū>*'F u HatF,'{-Ҹ|{h<JYn8Ojч_uNɋ$ !M ݲq#q{`;'2p牋l sfeUR)A,`uZmK[Y-] Z'Jm__fb<4fzdI?DC,E,SL@ f,7Bt,W9Gb*vB?ivuU] hP{^t-_Μzg vuҮ*h,Y9 Ȧ՟2C|uF?|@E t^s_xaE2@`at9EAf VrӫYK۹V]!PZWՁ't#5,<^C@vpH}O@0젆A n7,'ƶr D:@džzn[e; ܱ)n,ݬvDJK"N$Ȏ7 !P%NxVR-%k=%˭rY+\yW&Ʋ̪(&pѪ{eE]vz0:v7eR2HH8)pY&ȚLNOFfҋݏ^V5@E sYWFEVsoW>*@,g$7<&!0c;AZYo7YNRؤtl T\sL4ڜ.~B`ޛn.v@i8H* 4ek>i~jvJtiw-l;_` 0kbdC]oZKJjck:Fw2 h}Zt=TPzZ "#+dӟ3>05+ >A`S#Wv!FFH K~ZQ` d{d_x:!h$`簬P3dU\%/f\e6|@z׃#`S[z%jn_:+ Ŏ6M.4]nMOtˮYP[D}V.:B RSS%U! IDAT+|lD<%wh!@ i۰10(G\\m +M0^mʊULElڼC!w3lydG`}}U44_^0XYisG5 _W>t$+ V1E@c Ry=cR 4C:҆@Z`3SY3Q⹩%%%iM@_V|/JV9]|lO*&k10X,XR> *'n:-V֝8 t5/7֗Mbj)yRQj@ύ7)0X;h: 1umgV:6u{Mr ҩՅ- pO;eWF@4ѽ`:VVU dld[:uڨ%4$Wɦ̻&$βSJ`[Wa rY0nl]7+:D@{n@YU\iGK%JWK}عc (K.40wMtd9&M@"EO)+lӮ3z u-<\[M5oiF1]%m_zf :̃@wyNkE9A,@"/]o+ pJwd&-tx]F!BH!*7l_(>,LY ޱb䇀s+VҺ~s(jrtm5Cyի`8֏:@`bl\>m_+OY 0gA!B@;KWo]bq~'J'%`,_u UnYe$۶Z^MWye۫O H? Nr!R#`++`$kOdDmK{/Gsl ȦuJCϏ-Z.МWjDl0]=pG?)ƦSu@`<cdͷ*Ϗg*V1AJ[Vc//9zbnTtms-XX*%Kt]sJ@o,BF_ny~diUO=wc>wsV~J*AuH q邪Va9Ƈ: D<-_%O;zضPC:K$Ņ#?B IwKϵכ?<:^T n_}. +lzdj!Ej^.7^ yᵟK{"vuYAKu׬5WLwϬy@`.suJҤ.@ 񤜿@9x|Oh8$)Iwc/4 b x6#w#+σY Z'@帅vh:r8:6܀\Ow{_P@_*k,5 dClWW]s;vV=,!rIH ,D1}dȼSW/iy5Hwv8Ԋ*@ K \6j/7 @s[Y%vپ;jEdTA6$O&=JͷH<.٣ Q#]ImY]'rWh-+2@ vnɋ{,cgq愈B2̲,lQ+mG}tA7V;FD@,.vɻe"n=om bh7"-w+mU! C,緁 lUt97CL\棲bJߛUPtU^oeI Paɦ&il\(/zPv|Bxa*SmAwk]Odk8}й-]GZDatR)}M%mx Vc.#rI[zru9u@-V\*/{H^ofqU5#5,=/TUG@-2;%;`Ta  ;zpgA;֞&;MJQ(d2+oWK{);BFǪlW3K]x|dBg?CM ?ផ./KF]RRj:FWl@mH%srқe5c^ub&J_仧bDYW\*}7ટhx 'ҲҥY.i|b4I@ [jFLGeFx̑E/틮 I@j 3/F^Cy@"  $ vzY>yn_76ii-^t &Y y .<BA4=&; ܱ4?ic P.1w,T^?@/#[+d~cAem#].qb̀TJ~eWtA;J]Ws#P.>б'~c2ӣ3"ϙ h^N(6eop [pW#XVVz@{n@.\!9dρǽm;V3Ͻ͂B<1Y\.=W]' KAE+.h.L,#e "HkKGv+?"{=#ѭLUT$|+VIUJ %ɀ@ &VNJM[ەsYH,! O}@^{#r=y(TRqUY+X> ivfh:A ,ǷD`itق[uLQV_։GC{/"KuqҶqH"qVN@'v.}#rIn[Q&@!"F@ja@UyI96=|(b$" Z6l-k#+FeD>gO&T e[B@ ̯;M#+}]r'&:z4Pm ֭D.WN `ʹKT.AVXΫF6o2UF&@̲M+Wy~ fyn +jH66Jض~4^ @T g/@ gйY[uY;> ~[[9v9o$YE8<%Һo:`*&@F?UviAKF]DG &:@ D2j2{atT!G}3"wT[4['MI$Q7 J3tX%k_]YT\#Yѽ,V4P M^ASr]&zIW)ITglvfzz& y3-1ۧ*WUM%4 իBQ (ӧW讗YHWd(憗I6ꪨ* 5vo+]O咶55=П*S @"5kpA9a8o F#/ɤd,P5/5/XyD H  ^ ل -(vhk@gto3eۘY"侽r7ԁr}2j^\?6%r4d$'ٞ>twP @* [#ȪJ^i^ kvX\@Eu_nO3rͷԛ|3%ɣt[Ǝ ,JK2fOutfq.#ir@!@席g4lA :@Sinj̴y#&:*gdIO#cf!'$o;F<)G,ȡ{^x}*4{*)1/M:ѐDcͻRfO46I"h=ʦ&IK20ɜ st,CAid9 lP ݱ˨ P6}N2#D9YZv= &2c %Pܿ.N %mӎ@ h f5 91pҟ2h2:@ =׶ҥÌd]6/ (EHB @ $&I b[Fln$"9m6@ @<ڟ~ݦjسn$AΓZ9,Y,ILb1b @ ,_m7 I"]Uʶ/U$ @ ڟn6X2Uޕf+\; @pH@/MK[wc++"rLL&eKk\/ql @ ~ڏ6Ť衬"r ?oVo_9"A @ ^sRe銌\_Gb#rL]6"ٳ1!77~`@ PO.Mr~hkmekU6Yd^`e/>IB$ @ 0E@~VimKmMݯ{ˈM;nsM3)r1o+aZd%ߒ5et7%Eki#@ }.Ӯd˘5 oNKC;vO766w?wݏ+mw~͚IsKBHX:ۘG7ɂRcdCMA @  ދr"mfeҪߟVf7jso dرcޱw?,Ui2qѷnz yIoNiX)`-7l6JJ˫}y۸ߦUVbKi?P)?߇75yM Rڧ.\> ]ag jGKW< iI^JωڰzNeq6Uy~قGӚח랲XGq+곞SY.g]M϶k6 i{}}~JyZX~+oyi{Tmlb:|?}i㉋+*'#M IOg7׌b̈nVj6JC#Wa0KOe[䘨SuiߗVVi׭_׫i6_jZ7+5m?*_MrдeRwmk+m[ngo?VϽQGaO?8ϧgӏ_y=uR|w)iGmڱE.ؓO>{RkDu=nȒSgCw6=lz F? M(1qzs_Ps){GJo+QPrhMRK}i> bK^&?qy^">M~k.kCM?~$l JMnsVR7mw>|W_S~vB۔-KMG|ۖ-[afG~'Y-v9~2/[XC9ҿl(V벹nx JʟesIm Wz, {N&m#?Yu{NOVUVR?YU=p`V gVZY*Vr8||4qzRŻYk\@\s^^JNފA|Y{Z^vvF>gOdE9t,~jO(c @J :[zP8ٴNcf @ U6*J]Æ=mIENDB`././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/chartsheet.py0000644000000000000000000000073500000000000015032 0ustar00from openpyxl import Workbook from openpyxl.chart import PieChart, Reference, Series wb = Workbook() ws = wb.active cs = wb.create_chartsheet() rows = [ ["Bob", 3], ["Harry", 2], ["James", 4], ] for row in rows: ws.append(row) chart = PieChart() labels = Reference(ws, min_col=1, min_row=1, max_row=3) data = Reference(ws, min_col=2, min_row=1, max_row=3) chart.series = (Series(data),) chart.title = "PieChart" cs.add_chart(chart) wb.save("demo.xlsx") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/chartsheet.rst0000644000000000000000000000036000000000000015204 0ustar00Chartsheets =========== Chartsheets are special worksheets which only contain charts. All the data for the chart must be on a different worksheet. .. literalinclude:: chartsheet.py .. image:: chartsheet.png :alt: "Sample chartsheet" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/doughnut.png0000644000000000000000000027031500000000000014674 0ustar00PNG  IHDR-ӍsRGB@IDATx]TEfw6f3P1+("O|x'oF, %@A@Aeas3U웷3;faCvꪯ߼z,oDA=}{@{#W8CˇgII9tX(ȇAeAJ+]X>&N92)B\_SWO**_g3gn+9]TM搩oGaSs5> >e.!SS{O SoT7T;IBևTc\2|3>V;SD9-z#uv7b9f(//W0w½IHqA03;| DƢe9Y(2rjCP f\qIЌY?ᓰκvpt [#ѮM,"Tԟ~b\73'|r틟y#[B1eصc`#66tB:jRQn6_ꖐe|m$|c믾b=ZF:u`L*ݧfOϗϟ_twٞVDuh(/_NȬ?^e~:yS:q7t4=ԜSknj9uua9ƺzU.8IX_;<(4q WKSjťH{XѶ_꫰z1_=o{ܣ,$OSBKQNmK},H, ‡™4 {WZ]1$|aY?0e] S"Co$vHX"믍l*Mrhm⥷n:Mn$%/ X(!O:l|~.RVB1e$OBb?7{[%_CB[Np=KBm ;dWYo_bgIej*CvHaI:%)=39eS_\bB{+sd'a5Q֕ibpe"f.#ն2\>'~f{n sM<, QJ2װ_qU.CwY~3+ j͸WyJXZBc-C)9.k|e{%ծ@P w!Aav³Ԇ"nIY*L]ρg􀵈|]WYV#"|g=>OE# ;+v|c5=PѾa( tM /#5!hbbƀ:9ohRV0/ JE  >+gEbXlߑߟ29"k89۬ TAi~JoU8oF(B\O0]D'd s0_Ԡ"{>9Wl8ڬ/'o`: PlT^`\b2dg=~N_Yu=C} OP[o V\C+w k'vu|K P#}fuCaz PsƧG?Ĺ?5Tx Np*x'sy_sI-M$d#9|?}S]+ ap~ xK9}jc9%ӮrCAn+8c_I?/ 'j?p\47 'WMmyTW@oW\5b/r$T?Ocz苈2z.g8B3_K[sy\i0''f}$_7K9 ow=Or )c[?wEw/v˵gJL+y#Ϩ+5L7xK9TBvE Իƨ+0Ot?2Kuud~gaRf/r$;qdTe?:]\CSBe$ۗT״0ٯGWV;5BnR ghq(]j:3/&NpZ|i@" I\ko$fAnds n6"H8D/ Kf~s|]Aҽz%M C﶑tNk5ZS.qLcy$J:Kyq)#Iht \ƐN|4bybKi Vj)}P7oQ%4qܟRNBsyIМוT"_=GfYR--yk7Luyϻv;/RGPiTHqHHHPqQhX^(dɷQz'xltR*l+1qSqZLpbMz%rƸzi;vh{W6H}up`oc{+S41|Z,;^.> %k ~ wW[%dNc\<3j+*e ~VDͼWcd ٕYm1͆y_޲y{_JٌD"d#I^5~IQV?۫LCIYƸ5 Q5R\ ´ Ǹik Y1nOūaMW4dħvUIȅq%$Vw:Uհ.ꉭ,WܣTTѠ2F^ھtrM$M=ZoC ᕐYq/EĶV`+8V`QIx-$UBf5ƥ4a)Oa86YL^ G~~v؁֭[#..RR'*#,4=4oƉů]K?PhL#R;a%aKع{ob7tvl/~կN~+3^7绤sf7W?Q/­t@yQe\ǬF|T8wtC6sX'砣堪bSS~'r|Ncg^ y" w9:svLKGn'e9T|{Ũpa>|.#us\8 <%D1.iRC&"̊¨{ƅ+Fhn*er\ _nk_|\F$.659|m䑲Ri0pą_>a}!q7xéDw +[ioL2Q?㍿HsbIE+eCl"Cr$I{DoqL+4Heq(-OҤ!/空Wq,3Yq7ʓ9\ I\d5CoyRC&o o|q<-@&reE+J̢jU 9x-q kj?˫t \oܣ3iYpC*M얰k_k.'BcfۜWג'm9jl[|̎aq61Tny+n`:5 `04V;v,01/wJ `VR ¥}EKTx8|8Aum'2̲s-e9d2[|Sgcza~)/K(И'q W@?)|fݥ$^a=Wq9m$4o> 9H  ilKxE>o`+y_Y23^,HF}$..9cz$4${3)>&K*CcYKe }u뗸Y/紊i!eLŘ%OdJ9m@/z~f;[{y*x'8 xuYO'Or~43Nl Fo#KfS҆fY"S3KkLs9)/Oq#$i2fYo,l̶ /5 k(M1smref.K.Ćާ,Ax`OÛOZߴ}#{oƟSOy]v~o"6&F@#h4F;b>DY88i"YaU=c:ZxUtL#h4@= wOXty|F%QP]GZb *zx?m1Mܳ+U #عz. S\%uДu9,t&9V~94\ۿ%P⢸~C`ٺ=ÁR^u\kv~'›PXo2F?Ģo2LkBiS4F@#huZm;cԗ@igXS8:1u,B oEx9cf J -" E㜗NT8,JNq EvzSܓ?a빝TBSdfEr +}; lЯ]h4QC[Gn:~|>ׯ%X˒o+mN  a(Jg뢏Í>Aǫ0I%jchL.kE/)0w1 w߾xLxlIpSFIx'?عx*<-h4F@# kZkip)ΔW/AT ZpL| Ê+O[<˅D"+:v.|gQUA?/ߍ( EV(L<(4J)qiI#h4@6jjv!FnZU!V\.I,ܚШp}By Kہf]9ip{ǧ>FxfcD˚CpQqEgKO[-u7x=a [޸j<%%`0Ch4F@#X^$ c;gEp%C|𧫳R+}=e {؎pG7ރ3nZԯdѽqIX xt'ꅮ;SM l~_Xrz<5ի#)G/˅ouKT$mF@#h)^{+ca̶ǼP^e؋FU)rfWBM YI( Fbb\@޸q#PCX0KþBXۢs\gBŴ~Z~Æ j߉'X?hF@#%ڵk1~IөO҇GF2]!_szߑ$70FKyn n^VuX׵ o8)Mj-I#h4Z!iT|`^XMk>gxB'i4F@#4lڢx.d%}6S̽`gvw kO>ܽdv{yb l:@Wwi/b#Hc*HP#P'OVS^y>|ZJ޾K8SѢE uY;w.#jk֬QNΝ;8zj{nz+ڷos=~-y0y0źuCqCE]TiJӴi@;݀.r7rH|~#/N{L?Ә={_|Qų{Fll,?|{*?-m6L4IMz7x#)Ss_o#1V[7競KOOwI䦛n̙3k_)̎;8ew۷σ~„ УG5]|C=8o`WnTw2Su7oVyW+dW_7~tZEtߜw_c5}.D줚f|/e# 89^l֬(thkVn>}oCxv_謅S_Ξ4d _7.# 5Z z MA8Otmߡ17F\@2SSӥ W_}SD qoQS$L^XXN޲e(o߾O<xJѣ#.obZU,_[kV&`W>l<WuL8=rc<۴i TO߿amac׮]x'kYK wvz)cyI'ۀu6=رCuفE|2;_}.upG!裏TӡQ?\^߇~O^ZW^n_/^_O>Z ?/g. 8|oup 2^%%CÂK]I(Wcqcq+=#g9hcվLgbQcGR؛W8~ck 6~L5rB~8X{Q0xGLsK\p8)+UphLRIQzGWP39;ԩYFFoxͲGg}VҿKuM<7Ӈ[|; U 灇wS ۴iy \7g5}JĨ"^N;ƏL+KNNFuﵚ7|k/tzGje_(v ޘ:Fm!|}_JpHKf9<: |3&zHP D;96%hj|&%w1 wN?z? -A^Cy}ûhE?Z?8v.^ oQ϶S|uQ%skc m#x#;09ұ:eyz؁ SGx4*WNGKDa_3;7)bgB6XhZgBFixv6@񨎬)UVC?7-|68e릃kIo2VWBn}*.Vei翆+?GC\؛7 GOUKpw=|"{bhI?|9; Ra%V'·=ڝ>-/f5MћHi+yݲxE&{^n&" /%S|N5zSAxzx:SՄ:x wy ]#Nw\<<oq~#(G׶~^mD+IWijevAax7sJoNʱ/d"x>䓝*^!vi$ao,+qƩ`iW0e;F/Ef(;8,ۗN;歋SoW[7ZTV̬ئZeޞ6]ܛHNvmm15"ZؗY$)PcjޣzzVȖ='CGiv .؆X*!Bm̼\:rl*my?: /ڸ1oNZI.YjcJy[ :w2oy썏h;ͻ0)Ij+d֦8xKfr|ݪs[~FeѺ;NQl},<1VGyJ-oVC+1 |kLX<4(EӫVR#|$%g45=ȝ] (Xq:ZZc)и7ty==-5i4F@#иi;-M U1Ѻ;N~״e&cǖظv6LF^wMZ*Y:_[F~H3Yaҿ|Hj*Pېk<7}kڰ o dx&atʅܭb܀7bޔEN}©34F@#%~2&N$mO;zCd-kQ,< χc_]Ês[T4:lu6. i˟y5҉9{jLõ^BcAmh`+cX{hŨJ\!l] &F@#h4D$|WlWlINF#JuHGHe< eK.PIOIٵHď%{tw|7:- W}) ?7/ҟƠfcx=zp7n4c,RMF@#hC_׍AεGAk0SjHD!o>f\<+Я5v#&Zp%F铀5Ij?c4U"@SýqqҺ,;F4E CeQr3s|i@eF4nلۤMC{,XsfsF"PR `#!E<"hktGe 9 m;u8~.ø<ũEOjsAs]>+ 8 dLF*yU*¥kMJFQh4Z#h8虙u3o^}~AIZ2SВv F uH l;r 2tMFTXgo!B׵J.7VđâI#hLkZߢI#h'DEǠ%}ڴhNaA4"Έan>۳[IvZV4Ch@T(=(+ Ҁ֪h4F9#^I9y-~1칩Hh qc[W5j|).Qa9 (vYaN|YسsVqZ :hꀀuٲeu(^7Y//9F@cZ5>՘hLƧ&)))4 /&E4F; rH sPNBbZl H6;5R#9X'74B,0s_g~>g Kyש,w7>˸s S#Z:8cQ(gmvڔܜLd!>i9dBdJ?Te0E且`Kuf42e9)@I^ux hCbl)GQ؋QRXSy:4hܣY>fJFyPϳ9xE~xr8qVnOʭAǚ%yLw m-h}Y8k(8떮^K<2)(E%QQ'Mŵ_oiI+b4LFNJgOYY[nRpQ‰7NELk􍋯ãr4>4سe#|⟰mhۋFU(C 9%젔B //-5uuTj Y ht$-I_Iie>Сڙ!G'( !BNrAgX¢J@B_eTI!;0\| HxӐn%j {vŷT~LJߓC?Oa")x qZ]X2]q ˰ó10|}m-./;k3qЊQ~C`ٺ~p尤~ IK'=skL}`5G>YcWud(;w~y@6}a3(B>Ż_Gaz9?h(UHSS i nIQF;9(e17QL[F"ȖO>LhM@DӒ?o}'"ȂZW8 j0ݻ1+Vݏz”QUaJG~nK ڔ(ȹ_.eШ835,(a&|*͋i3:Cj#[Ѻ .m?BӤ4?r_Ut كۄ}iD}[;N`@-.Aŭ'[rx a+;n,$Zo#5 { 4v]ixq˝#ldCW]4?Q8op̣e3pӘNsh;+ ͢YHhӖNCq!O_ԡ/UkUxbҘ> & A%2t2^TcnM}oᇾ2%ZQRZOQy4ܑCChUF*tZhV)Z܎tؔk\@تWn@VFyZ;J/gIK7DX篆B#L?{dsqN Y, _N%Ⴐ\|}@2&[Pա5jnvṫ?CvUץsq(`-RNgFcpޖ;K'NE=i9NꁔUi{z\㯢g/\hLj 4Ilg\C\$ZO DΊJ~I"ht̚} P+Ք;_բ SRQ`FptU)/.E sPBތĨ0vx_DN,0eVlxb8z'X)uͧM!30h>ݺoq/b6v[ڝt7~Oǯ Aߢv=]Kf-SSlg+Z?M^+%u8m LZ:Y @=bT%X.i@ۀzMqÒ/",]F5 Z vXޛdm^ؘC>Ѿv aaihH=!^SS:8!62 {L4BHxդC(ϻלX-7Iowc:%xJJ8rKopc;xgE1}_)ƴn J1VOħΗ$džSGDžxAQh i{ߠVI#IΝ;q=FY\VӲjGO6 ǸףЊ79dBkX[r~b'HX=w 0c5_mЏ'4*[,Jߞ<8 PD;9|*JXC@ ~E Zv^*֞}nSчli@%c18J6 VwtF2찤¢GP^|)^)S#,p[|Mq\`QyJpHF=Uq4ֲ!i)GƎ8S#ʾE-m1:. R\^J[zիe\20Oq멿`&rbxKI9]2y}TQ-M=B˭ dL\?{Ď=R+)95?n= {RD#{Fxb+k:o]k\뜨6)apY/r*{ǧqi*ކf>g"{=Q0 0‹8֣¥EƴVa! O s崍!:#FWh*/9+,mXB?ݐZH<*Eqq9-^B q9* +iNYRo>g2^H.[!k?Q:/إxIH|UH׳8Axw\|zߪ>52ѝ;ZM'ݡ8o(9QO.1l#Nc!$ FnvTl`/SASݕ\\Si5&1ݱi-zp^ҨX+ߐرӊ8CDn {Ϡe˖[n1ِq(e! + $D!+Eřd#+Aq1ɶ,Dz缢D병<ؽ BqF <(Ը(LieQ曊.)EHLdƴ$HИVlذAuN<ĀԂayI:iAo޹K /E4iav1mco o@-hzFvgggkЯwwArڣ$01b[VXC2Qjǥגڵk1~iEO<\~dBsҌD]{G ;hH1"!KhQ,/N>5/%9ܛ)rWCN>DNDRuB[4iԒ젅G~[F;h)9,Mjg {<5Bte\HIڇpnӾvu)FG:7`:uF@#h'([zzFXck 75;.Ԩ-t\DXF@#PZwiyQѴN#+6LStX.XTJ41#нg7''!zXm`e՗N0Xp^`kZ 4x4i`1;,mڀ ?eDEgZv\Ұ[(kǻ)OM!WvE u-Jgo>D&}j85F@#`w;GǂYڮrLP 'ٹHKMQ[hq3C~;+ >m"6:]:#&4pJhIF@#hm\]j9‹,kŒm4q'nbiڵFzv:T:.~mKbz0 ~=[h4@A-4e"Cgvi:f4 !ۯpĄk-9 Pb-ځ>ۈǯD"'5 CPFF@#BGUz;83?[{%b˜Ѓ)I.@HH 8 \ҎK@r!rt ɑ@$&916ظIrfU^F^IV1^I~hvgg﷣~o=Ӝ a1+ 6ťU.aiHuq¢SUL @GDM>~1xiO5MheE_mJ@ (%d=?tWHc R\&8#قӦH iiسww7V ?{=.4tFkw]+%Dhy!+n 밤BD\;.q1^/N^'̚p)g% L`HKK+nҶuVXt.Qږ DPJ`dDH㽫#73edRj/.bulƷ8Q_9lm׵PR>ƼsQŽc&oQ_QJ@ (%,+c|怃V%.`Rąnbtj3CBwV)J`HwyA4?;*4sX^/:l%!`,߄v vdRyƱҟK⣙.fnOSP-HcVz<_Wj:%}c%P)ECv+(^)! 0B._!aJ N`@|{yK{F'3 ./vW~J@ (%RYyY'-, H dw6l|s5/>MGNwKMCAlBMn2vRj^*:j%.'',EFZt=<;7NcmQhSJt} dAU"J@ (%DUW͌a"ZYD0kXʶ4dB3Jַש؄upKjժcD_~ӝFN@HT#%5Y g}}=ˇM_e"ZV?gtFVbEfa[lg\F$O@43R 77we:e˖:+WrԏJ B&W))2$m/,puҜH @,nr\(*Ŷ͛pq'hl807ar>g}V]xJmdΖTcTJ@ (%pDlg1IOf䳲XS kS#&`WhĶf*ZF qކBdŭMbݽ/ktcQ;w).)^{-~dž o}렯aJ} hh7{hצPJ {~Lh7d)5,$Vp3D~КKAΙcm!<``%Kpاs=7xc)|a]xhbK}%䎨{kd֧<ב +^?/N&u(+-A[c-KJ2*G},4c5kг>xlXX,7oW\믿Xj1|z}?џ #Z pO~3ahIGnص8H<))%@?"Z^yixj"%{9ҋC5k2j'b-TrʮmBCЀӺ{QVV:Kx'k.4֕իW;::o#ֆ|ɸ馛PXXاdBw4Ţ2|i,D0tlJ@ (%ЗLj|n>S^_n)fݖq NT^)Dsc]‘m8cgq>h,vmF455SQQ˗UUU8!IvYg1\y*륔X#ZhMyM/,7_ºftPJ@ ( ;;ּ5n"Y.b d돑Pd=b9p8Pƽt15&Gv-f9 ͛N8ᠻtww_*lۍk|$(`aEpkbO7mי*xtJ@ (%ER{nc0,b3ה96%pX{;آ`v){(`DaoWrb1c4#- 磾CZUP)F@zp)V@װƳ0(/*Mf@wƼ*2߇>x^lo*'oZty?SO=e=Lj.tN>s5p(XPJ@ L8kؚg,t& 7fA ~]ldddvGZ[ޏ}>' t-NxyʮB,8]OF (%"vXY   a2#빜tמ6%-8bK+E/%HE hg<-JS g&_9eOc0@,JRqQPPdff ٦.bCBSsժUGdׯ?"I(T&@zP{XYdi .0fX ,JGEnchͥ˖-a\~T:\42M.OM&vd ` ;ղrdѧhnxh6 2|^1`thO---PJ@ (#K@DE3sP0An;"RcDucٹhk,0A O˰;}_nGX͸D=`YQ0dn=_\."ܓQ L$Ê+W!GϱggpHE (%R-U &h4EY&HMצk$Vh0]4aDKvoC8y2d?PKS%r3S^ (%R@,&?ʒcla 3*µ]N'̰1{`o`0er:숄*Zc6^gwoEÚ,|MSߌ!Z cp?,x3 '䱔 h϶m/< <~t!EKn3ֆm(X0g;vK-|-cRRJ@ (%<8-*C[wՓd56naaZHhex#(|3QZZ,nca0`d@ lGۉ#&.P8Y\A?38;9]nļr`GO60$ õ]voW6ⴡO<DԈPo&{1-Au暗^'.\:t7e rJx7v%P@epQXf(}=Xcebű+rl&͘ gG;l!<>4o2dgeRpG+[fbq{RasX}JbO.=m!4z %ˍhӉ aɒ%qNNzKCZZBķϿA/n"/PJ@ hŮ4ڤ! x$G҉4f=q .K˘ļs!`.ց{QQRBƷPTd#[}mFf'6t)cX,ksϡSNEww7կb˖-By5ט yYzTB݂싯NJ Ya>tdݤPJ`"ѲnZз 36zaSbdb%)((0fٙ7MȤEvƻ8BL{*Ʒ$jn-*Kz*."455ᡇ2^x.1}t멮RHf=4f+~S%P@=,>Qgppcj@LM1pĻ"BdR=R"%/10dddŅpMgs\Cx}#\ĵh~к3׾rwmJ3N>d9s)ۆ-q.HLM (%@e|_= 0Ѵ8RdndMDG#<h^x}ze&1Re ƶȵdN!m޿IpZjd{^M[r (ޔ2M>(P{PJfD !&id8" ؉xȉEKRorxhIEcK5jnk '.EHJ`sٲe>֕+Wt,Deeht}*4Lwۧ6<{v$EotK$0),dtO'-C{5O˟q)R OƷ>kA(%% r-E+8qϡhMD¬T"Dtz?+7ݵE":__@(/B{>Q7CkGqW*\,ٵ%3-VMYrv)ds`0/> njSN`Hu#a~xlYk ~EP_>:~%& b=sq!6X 1p+… 8d\a&f%++ĬeŊ[IXy#V9?g#6 | y-6~lg5j^<< ;{?S (%'`MM`:玬ϓم.Lcd3c$g12[pS̀E NWYǢ?tj J+#=SIu,EL[[P}z2t3څ.|oy>d;[w*/N,>j:9X?Ї?aWG{6lm`pCh7Vq%jaZ ~XkA}+J@ (%&.E&#̒ј8FӥI)㶞Jcjb%ƘHXpg(vo/?ʧN&b)XMeecse1Yʕ y(Y\1?kx1El"dE|;'!-ͲB̛=ホ}tdg2`dT, W.WZ$a8͘}vK ubs{-aƐzr}!EK$}wo:-a 0UkQ!_PJ@ (O@ܣN'2 H;bp Y[*Vx~QqXi2rXkFH}eeP$b9r|(q[UK|Fx#8W1}0rlalA\B&eNִNgb1F?6tGs# #X'SSȤj (޺~̚uc<ۘGbd6oތ+_Q@֭[xw؈K/W^y%ZZZc"|k_CiixBs:hE:c.a<FM (%@JMcJ[w7KyDMbqg-_)+ X~.#3x1hM #S P ipۜ}&Y&-F3J,9]RaLD IV5O{JU2,dG]3j^$|og3SNyg,2"`jsٲe>+WrԏJ B&W))2mG^ b1hL&`|ďh0~"WCqQq֕cyf"!E|YV,2Aع֢݊.LĽbDz"ty{Tmk$f#[VGIqaeM-vf,LJY[ȕa,"BcВU27z|9X:8F<z+~ߛ#~qN ѦPJ@ Le¿+QׇhYp+N>u8ܥbE&Gee0/JvT`mReKBdeOh {+d=AL ԷNF6]aƵ8p>x9X4b-e4e|O?AG!1*$4]ݸqy,?6mdWTT෿-&D)`|ͨ9{2h:]S 3SYvGJ@ (%&c` FQtlᤒ7ēK@G RJ@ (%0Xe'3c,F̖"FGb.i5 +E, { %VnMY\yIDYgEJ</=$[XDu\=,Hw;W;zpe0}Tdѥ- :3)embZQ6@ٕ5g +HN ld&<{ߢsV`^;}'U鸕PJ hOd\Έ[['QZDM$ -*>E-tQ?q-|𑫗㘹PRdsIJvF|h祸v&gaA1ȲgQxwסkJ` Zm$#><ܢt&?dBoW\B}b^&:0PJ@ El]q1)h? >bw cKS 8>bE2 %Vzr7#sZB+udBE:La̻p舉1I}]akkq< LLC-ʤ?f쎍Ƒ iJ>rtta9̺ht8~xeZ~X_x7@v ;RQJ@ ($`cXi‚M1qo)D"OQ%b%Ŀ(~p2z%fŲH639'_Qhg'W|`hˊd 0HYVs1À9,3:TԓE0981J z޽8uNϕ@*D Da: 3[Th~Uh{tPJ@ (@@āq;n]k@@%1| @s@)VD|ɸbbtdgge8<JE" Yӟ`YV登͉ΣuI}fT;MؼDo!ϕ*Q,Z(.F!q-5Sqݣ$cXqzgqL8΀}lZo(uhu>ba c{,* 0@^sV0ozb 5®p/Ztž͉c%PxH-^pKvVpF+@ƽeǪ%SlTA`bE`yQ99(q*tsӗTв2ŊuqH\06 odTJ0#.b՛LrRH*gZ[,]XW(VVf с3KJfҵHuDKnbtf'\nVe^6iSJ@ (%*d-.bǞt*y7z.hɠk*"!&qRw)ݭs1uLتb߲"\E9'rE,+Mˊ/`bo"f ZVd,Mc3P (D.d9QUPqinZ[H }"x]:(2{߁֙?gоgl]ӲəyǏ./N^y\w s"ᒘX0J#hItg9_achpoG[W;>f~ُcf I},iEEq/ 'b0GzK8,io_gpu;QjEf^%}ݨG>\|xww+7O,X``}q4&;WZuDNlG8teO[*H^(/I@IK? O?t - %XZIJŘFq֕cyf70&fVaHkL"V05 (鱬t%XVt[Vt/}c!ǡ%A(͎R/ݢvLvzjj-DqvӊE1Oba,j! 6tQ\ar}ފttw`_NX{jO=b͚5Z+믿?z9Np I?hͥ˖-KpʕFY߮; DkKe~-B_ubYBO>]],>pj?~_"N,/+O?Bnu]3g}Q<=bKM=l߾}QG'6ngpILd&I]]~_aعs'~㦛nߎ7ko+{m5?uDPJ@ (%02E,%g_ܿȰ3OWܲ/вrQ"0&9LZ6vnw+Lu_IRZVbe!{ o z21ĊE[Zh2]E.lڌ$Vw}ؽw ?)e|Ʊ=a]ӸX]ìc8*7^z%̘1ψ=X=D<'>{XgdK.{.^|EaNzjFeP=ͤ>Eӑru[[ "[="ťijPЅP&/AE#Zsc}NrΉ>_p!wԩ6l؀ٳg'pYO2;v7Yy6q/۶mÒ%K̾ӧO,qm HvAc-iӦ}/x ^_n6ɍ/Rv,z]?_6qn G\|ף$<J@ (%Rv>ٵ/90d&BGX :pTFx3֊b+VmVc;^ϬU8, u*)3KD8NÜxMIaCͮ=X,ه^YkW^y%۸c>b/wJb;!1'V@KbE`~A<;/.bK>qf}'\Jb&0kb b坶MPIX`LIE!-xiY0nE,+[?' wS̍p ֖IP|L30ؤd#0)E,,pmgc2u K&1ԗǸ袋ポfaa!>᪫え3gyXE"Vq3eC=ZOwQVVfk9| &5~9GSbg6@8f,&. g,|8$ [*%@ d[bZV+Pi/3beŲiSEXPE,F1D8;E(WhmaA7E(b8h;ǡ6#B!1ogkX,Z7l:kXiv-Xh"!gM&1t/Ab5qmo?@,=]nXMŲ"[o}u )V/nJ0SeEob0 Q2ؖ '2AԜq!`!j J(B\GiZA(w7v-,º3Ye~mJi;=!(XGD,[`^;65KXϭuciqmJ@ (%dx%q)nw/渏B=ī#A C6k P e|T!^Ţ|E2qJC Xpߓ* }I8F1F%3;yǽfλjeI^bbDlсodoԽPJ@ L`"qs^س=;nE=Jb=Lib]X4IpPu*JkӄLfo]]^ゆy%^3~EĊıH].q'ޱ==;%p ->Z[[XWNƃV'ftӊF_ԌPJ@ i%G=Vƪlo@MSzwVqsh'--]$8h*tef5=m"6^-a&U%( ?{OG6mێWZYTUgDY\YQ{ğu;c;<~=w%PI' OYx!;HO_;b%t6K\KZ2]vQMKq-bia=8/5"m{ Ty1 Өq èohDL]QaTK`@ ~5aEf_P.bb}{6w>SJ@ (%L& +oېΠ}t[aNΝ7$yu1,.@zcNQQgn:L9dm8h(aN_VI;`kk;v̹cL#0@vj܇^J@ (%E@%NA2]4B(v=,Xd.PaD{_b[KLʼn;׉ιֆYn`̺梵%7P &)&BpP}c[-+!YQ V*jRc1v~z:J@ (%-.iDBggW(D'AESQ$$%JA$7I}\=~~%+IvLKUocPŀ|1naAO+K}CZX9VQƪ+ Ajժ#2Ai?meLO y=ף!q-aR&9y`YqAiUuys&k{ Geӿ# t CpEX\|SȟQ њ:[ZZFוּg%P)N#777 *nw Ci=1kKRI\KC]UOY KcZR촤H ~mW"֖H#̠| bPK?=u*f#M]%0HLKTU5ӁjŞn:lشr+DPJ@ (%0$.VPEQM7Ř9ik|Kc<1ݧT֍ ŊI}L71Y[P >?Hcf{c[$Ik.~>nhlBms*07 E_T%0 gIO/ Ѕ7~}7^݋4 gJqYfwPJ@ B@K)Ќ_6<{EZ@ wS<㓡2#[w!.b1;P v}^;H^_1#XK\u#y:Ldbm1EX.u XrŘ{5e\zɎQAχv18SJ@ (%FD@&RlPHƕ#}Zo2o[>`gt(t#7T1#ƒ._݄Ώ o.YN8iY$İp-y?6mۊ iaRUW@wR#"0@v oetRqr4I (%aɭQLU+Rߊ's{D`@>2^c,Ў ߬XUZfی%*FBbDq .7;[AQh)6IqsXnfQZT\ |ZYg|v`QrXJ`U)^L';i/eLO y=ףm$J\E ݡtĊ\pI1.r:] a6'H*\rF t#_aE^w槴}xo1"dmq|ާusMK g0ߏk}nzއL0q NfgyD 0Zs)eFʕ+QYY9IL+ޔirJM@&Xwe|"`+2&3:3%nQ6xq.q-Q '3yO+Ur\@|IIt#sG Zڑ ;q0]~$6PJA`fn81u4c>3,XFk~liitLJ@ (%-+E܍{^ӭӈL2PJ@ (%pXI1%_b9hݍ`'-mq9i25r鐃/Ŋkq2%podlJh,"&%НϽ~Z/ab\xY^Iii B/3E KTwPI!0 {XOMox~TJ@ (%M@&2!%bNq]s?O"fTxBIKʇ(dlb޸ZR2xMV5>ie괸 4c!\2iyUx;y*d1GL\{`ҺbbWh] Ϗص%3f㸹T aɾ?%02DK mplqׯ@[k>>ƶ [PJ@ $%ZdlY\$q|<|/}zX%!0@vj۪wBJ14NanVJ@ (%0XV+E\"Y]Y"OOcC6DNkMk,N?&} XS8_ Uȹ_?"K(T&@zG9+rkS#!0xԌCh4bM̾5h͠X4f I 2hE6#di:LKGh1!.(N.Ec}#Vܳ!8JO*5DqZVG?sٲer‰\a B&~oW$2MĄ.R\8Dŋd+LW/L͞/j /ƿ0&nAZbh1d3"BFfIb1X>(EK:< I$DbTd 9r 1tl>V>7vNʑ3g&;erJK*ʲ&'I'J@ $hO---I9AD (%% ֗؎c?dspChǚZDxc-C:pQd9pYQR&S#.c4zFvf\ҸK8wi GE` B4F٘u ΘoEeQhUqkSJ`|$%_k3jgfΞDnM.DuPJ@ (%0 XEN ؗɽOI "_ifЇ^@"f[G5Zbhbٷ\ӭI29Q3+"s#!ibq8?Qx.~Z x\y4.bzdKk?葮ן/VDܧ↛&#!^*~ܔ o _J@ (%x `Mem틵B\E|GKeO; +4bkgËYMB[ `)Ug2KP*̊EnN1"D+6fVGƥM (A`hɚ_ld~1#vv(X+B&PJ@ (T!`M-#FD%`D""%qA#ϋBEf]D bDPo-TjZذDֲ9Y#%Rǐ*S 1c.f1GKWx=+Kc7| ӦPJ@ L'" DHY,1\6Y'<KZ0VVJ`b ZmhCp8gy֛w/I ʥ?,}PJ`B/ DHXbZ-"})Z'ZKYkc¾{VJ 5 -aP,׾7uWDvsg};dC:{֢bٗ)wjzVJ@ (%PJ@ $ہطkD+E (%PJ@ (%0()M (%PJ@ (%0f 8WZuDNnG8teO[*H^(//O^ړPJ@ ($sٲeI>Ձݭ\_-\=;AFezX٪,>ݠPJ`e QOC (%"PRRg}6mj7} ڒG@&Փ2H$oLRz (**Jn ď33gO#fb=l*,AaFlc C%HiӦ ! "P&ZPiy*am۶阽Zz]?_6#SqMς"߽/}%. L44})Se|Q39K|%hXFf`g>a; /@.{]hPJ@ (%@ 1 FBY&<8@(gFCWJ@ (%PJ`4 D;І ¶E%Ӏy1{_NDvmJ@ (%PJ@ ($`iyPłQbŊXk߰bMcNCPJ@ (%PJ@  ;UUUjbEKN ;f%PJ@ (%(Z|/{'?Pv'<ug^2Hp6%PJ@ (%yqܳG!k=kQK,j?{&< m@ (%PJ@ (%LDK5aEfb]BFg GZݟѾPJ@ 0^lɾi6].~,rq^ pAp^ի(^ŋ&`@]@(-[X{Ld2If;sLi;I&3YwNs˫PJ@ !ZBM;јЗPNsېu-鎇PJ@ (%PA`h9Eb j'ݮPJ@ (%/I1qF (%PJ@ (@O$A$^e.e}ȹj*'Y+W؋̲744( sea<2U'3sL3O gTf@8ϩ353*%PJ@ (%2D`]O=J ah&skPUiPJ@ (%PqSr, \J^[^I`z-/߳(M (%PJ@ (%!#DKҳqF-?gGV:\XA_g;] UGOPJ@ (%H'0B8c1s(`iW_3^shPX},V妟Q)%PJ@ (%2H`hvaDmWТu/^VxePJ@ (% FVP,vo^? @K;5rN딀PJ@ (%PM` 2<TWl`a5"C60]PJ@ (%8*#EKN>t Sxp=( xݎyE(<*J@ (%PJ@ ( i=}?nm6xԬ.,Y4'x W>6ǾnQJ@ (%PJ@ :ϑvHn`o>O=>QVlGǞ עPJ@ (%#DKi'Ǹ=ҋ~r\ɜZPJ@ (%PH`h9E (%& LoiiQs) UL'i"1qٹl/'pqþPJ@ .&tiPJ@ ( %g `uO>< ĩS/' J廬9WZĖ5k`ʕ{Yve{L3 SeQ]]ŪgSJ@ ( 3g6n8aF9;;;3PM=PJ@ (%PJ`bCgS kX_Ypj. 'lb YPJ@ (%^as槶ﱜ3pW*Q$wn9ptPRP\?*9!>ZPJ@ (' ֏W "]mu6%XR3XRllG1 HED{,)Z :gAr "%{~ Pj\0,m\tjaDzPJ@ (%0qDTJnDyQ=(Sypί1vbE@F#Fo<'Ī)fhIČX(@χp(0%@& -߀ykDZwcwobִ}PJ@ (%0D0/o!Abm;bFcE0텻-,0JnWc0?uvvvNJ"J@ (%0buRP]UڷT!$2WnSF0ӧXV"ѐHl)#7-%~tf2!2"Lq,npUE^yZ47ą̕P1*`F+@#{]O=J ׂM[csn1 -J@ (%@F Xl~.ZV*磰jIS7/ZSP +U9%XPbfMpR4u }RHY[\v>8`w"X8vNL+'0\= n~jY圁RTpï67D?}W[ *%."_݊O8J?K0#`?B 3Y1*hs.S6j,Z6h$bCDݚSyb_rEj>ii/W1>q̛̔v~QJ -Kƕ- k6>oR|n;?sTdݍ )%#`/Ɂ VU3p3 \6L`}B_(i]%X膌I07CC -Ϸti2?^%IcȘ0E/3a賂!s iQJ` U%Gxk>w,?~+-9K%PJD<~+kC-jb,L7'_  K6C6${f 6NWˍ,Œq!%>F.Fqc]/+Ǭ sxS (1 -hZ|()(F8էbDsP?E (%C`yG'+ -2Icl97+ge:.YBId`4Y\/N  Lbȥ("^B@n ܞ\/Y{ob3{~6 Pj|bI="˵xPI,G}'=9E (%fqՇatf!vƫ$EI_,c\fPzqE(`xh/b}qQÓá:8NI+ ]4UT=,#0BT\~VP^?ޅ8$s3̃MhUPJ@ (`yLy TTA P1sEfueZxazG29E2:M]&jډ1.bg~aƨ3ytPJ@ (YK@`**_`2v%$+R,mpyC#^\F ju6*-`5Мt%?vW]!DfH^B{%}>IK6YFyJ%^9pa|o68QT:Gc]FA@8׭[s< ݮ2=|f:BoWl#^/ڬ볈w Es0UqA ,0,̺O+K5UE4KK*xQlΗ/xkJ ӅJ`wZj™Y+W̦ L3{Ǖifyٔifx9Qg"Wȇ¢bĢdf0ЀM &a¹ι۝.ռ=jz䉸z@`~PJ@ (' ی;?½/DY,#^S h=|{,-bulcN/8Ek*1bNP!0FLKfv짞YxL% h^lEYc"wh.)%,>Qp_aXYf܈EXM(-bw8 Q0ρ@[Lkms%p=b܃f9sJ%J(:&IrdJqΧ?3KS$˾ZPJ@ "X ȡs%1,e&= .27jZ*]g F8MX}J@ (%(=|? Á(;q BFfŭJB+ !F"%A+;s-[ftpWFd#P,\iC." OrG>qt82ezljBK -Gut~-?L+ #,-ǭ =l_UW҅tw}}_]}?l=%PoiPX,Q૆onLBX\jkU: j'Rq X>Ju7v&n}2Ж cVi ŔPJ@ L-[w;K@FFH<ư]I.\#Ys\(F{Ǜ\f %Դc4k.8]NmDAJW+%L" D|Lz8W2epkKŽŁ'aKB9WS*A`dLA 2`ð ҍJ@ (%03Eɚo~N/]yl{a15nat?3nD.6;(Dߎ6oMdJ`:p[nR0)יMQTf@zQ]]I o"ֱaƃ*% 3e>}(1pXĊLXaObV%)\fp v 5Nell6Vc@cQXR w~~>̙s'q2gKk&E&sah]p<ή_!&ZćQ\F%(|ԗѹ/Gl "\E(VWT;(z1EK"@m~Z GQ~dуM~(%DH@lc }VĊ'2NP9 z[0PaAen-x+2!_JDhFip7Z]lLf-dǏ,ijenj<<Ups<"X,bYiIw{+|m-mb+pײWj G$^~cYq'W.'܂"cLÅyuy|u~## D5|Z FX LrX/E CR"_.dYFp1vYngy/ߝY 4­ړkE,YV( k u"NSVrѢPJ`Q"co#ڈvbYI 9HW6#Dи%d a +j++N(;mx./JKQR>yZP<`%D@$>^Ŏ!Σtbdxe\X$d,X}P _3PRAˈ  z` o8u7AӮmxs6*bt!36S,.2p9[I7cs8eNQH-:E (%t' &-,l. Hv0@G/'0~!ĺbv`Ow+<l>0Xނ*%aE45D%)"y%&/67]XiZPNuG"6eY"FMVA8vmC e,.*@;c{NO1geHKRAQ1mt+Sb=:֭644LufEi2U'3z^I(sggιthہ\yuv+ 7E,.8wLb]`GxⷰP19sK׋p(h(% к %lx4# m#d50D)9 Zc 3-XLv`MhebUq2_Gr 5ɇAKfkڷ%%h55Q})U&5kr l<4w\fMf+hK7mNgﵓART Ư0q~|#,\NmKV0kDZ럸Vl}ȡe"7n_bEIΙ+"VTϑ&*8ÖtSb@A"*V9s84LMm¼EEV9d0"ji:S{)Z[= !:Zu=&tՖ*%,# E2mx`. %5pҒ8 (]sO?EݢF;XW$^,,V/G_ OiG ZUB` MXbN:&6󃂃P$&F&;jKhuy;mEiY13ޅrp2]b]D_p3`k++m$gv,1*GhQ3bK ;q$ {y Wr ~yb迃7%PYD@ĉn`øX%"X" %B`˧/9f2VɻoFIMqalĨ)ZƪX*bUDz%{b}ƑE5FK̢'nRl}a=m߉jS8iu!7<Ӣp>_ہwaE&6-nVh g`n!s<~pzt|3硌6쮿!`({9u/PJ`Wk(HưT,K q K f좫PA.Z~&V]u,:Ar0w0ivؙ92"JZTB sSNGkUP',6z:/a+v>m00&sJKf%.ue0+O0)mw~hKN&ixh2|{7ncX|&S偣d)>{h:ƲP3˄WYqYd`BEc(;IkNa%,e o%_Abů쮫>, 2^UD8"XVXTx፴E^2qm̉NB9x000`d|XMDzi!\)\ hm+XqjmN/6D i2Q\ЏG}8%.ÉcKԢPJ`Zꖆ(b/8ŌrO"na /^q6>o vCQ C><1Ub'&X I&hh,"#tĸQ3!V#Y'.˱ 1N m89(Jvc]sÌ\K|mzlM -tђ:[<2SGKAWJ@ (YA@DXwpAIsLa"V5Evw]jbX,bOEr˵ppHW'dOC,}^`yZ{MTy|列=v._pSJDt.L@ $ua\ƃEQӕa@3wgW`vI.8jTZPJ@ LbeynojDG*"q, f)Z$μ+~=2K i%XO뵿ayiWy鋧ea.cXvqclT.Yۺu+ԢQ& &k+dKMbs܉(::1wnŘ魏z%0D,Rp^ DoL.a;Z)Z7Em*k槵s-X~if×K9WZ5֬Y+WNufP4/XVY>$(lsn2Lxޞn!3JCbYœ|8 Ʊ&m8?\+XL 41 #r7nrNZZt FIlLt;$n3E2řD:n~ 8̷h w דHpWGqǛ7pnf\uU#ǹ;|լ]N!v_s(5XV_ԶX_] 1W)(%Rұo6iJc1ܬeq!EPt/\Cx` .ca1&lƱ;ҡI>6QW_76N;m2EWg-)ZZy3[g3G|rbƍi{=c;:I.beٴi.|s3vp Ҏ_D3 7is?8=\z:P?OKB;'Kf@-J@ (%tdYݹ&Ij1(,8;[أwނCID[ش,x`|kpI٩Q(P87'JiyLl5hֹCr@;+I0,vԄ~<@.wwa׾/bÆ f{oonmv򕯠,3Kh-÷w#ُ ?:V؈g=UE8{T]_vf|Dۦ,ҽ/Cl,Mhe1hm,UO=ͼUu0e$EcOؼg͞{7ͽrSNq^޿ x-Jh)8>4%tPJ@ (' {ar88 lR1_7늬";6dsbT_`|ڭ־2+}M[)R#e8.SiMƎ{gQL71ƶJ$Bf/zg)p8>iQ3@h_`^{ro[rivL>묭cUX,tPYE@DDw&,*5L\Ò]ž1,Z"ȀkE'tȉ:>J‘(z{r)Kd8kJŒI-qV;7]1BW\Ĵ(N M$|W_:M]=0W߱%YZҡ7%jW`N]V| +i,.2s#s>ce)ynۿnv5~eo#9s1Xmu::辗SÌhEjvI֗_bAFfp~z%Ai6mTq2:]PF@:NյwJ=ˆ |7"Z1긢vAcY^}0^>.a) *@ J &Apa oQ Ό¸礋K=o{z_ L%,y50J@ (%0$ݦh6'gaRt0EĊga5d{O1h+S;7>FLm}qe;JOɈ]ܴroT'b8.a2eC1.bI$)JZL \n0:eB0矍'WTf@(93w~&.]Lw%B+ +'rao7_9HFf #鯔.6L-bI;cC)Gk[;B-2FUX[LWeܧA׶<}8J՗rZ(v׬Y+WzGcP50Nprgqu2>ɗ VZZlˈ{)D6(X=v$ו9=#_#;j##i|wd5ǫ =O#^ĵPHN 1V]I`nM͘a"|w-la%ʐjۤ)=cVƸ)nb̀@ST/sY3ƨY;rݰ晿ᝑ6TUUکO<}QHDSX֣ûgPx㘰Ϝ+8% 3q9&e*+I(1Gs疢?p4¬bN#\$017VEisYEAg`n!s<~pzt|3硌-Aǒ5 p՟B (%@+ ;=-y"jfte5LY|.my r4S6dAKd蓵4Avx4r`uP0_AA BkȏЉrɸ]7X1 x-"E|=25a7EyDg9NX9w.ZZZ`$8*8;8_>N9WѼenX-qvo根B['?YWu}W#PJ@ L40{)TkӊhVza!vq!C"IJQɰ&ݥFۊ#;p::]hӇΞ^Q<sXa/[qY.4uLa}ep] |9)..];N#.T%&رsD_}U\r%#C8uG (|ԗ%۱ۋDy}UbѢPJ HGۻ7MdC !JgW`|8 YYm~׾7%,,I ofO9%g'ځN[N(Ďa9l3EyHp8N/ƒ9dIc"q.Wĵ-D%Rcr,Nr"N ,L)+G__M@ͱ3S֦tђ%w ǩ߆N7E 4IPJ@ ( żfR8lK]*%}sUђVԗt݆bzN;`{:Jk8,-go!{Y'D)ʼn5ȡ*.ٍV-E~>_ N9,pC,P-tbhia[&</h;k>?@IDAT8{1yf?4ʲd|衇ٺu+<#|kguQ_|ێYOI+>~d.] -J@ (%@RdQFqb&>J,.mhϴieK<(U5e=u O̭1cH-&(I3SB*~ؽ jkQ\T7u3byL)Kr\T*4 L}}1-/47K4u5'Lc:tRݻw;x:y 6yAz Fq}ht>s7n{}ePXaEvfܰU?_yGP2.+%@D8_zNY[uKK;Ekf+,1>4+CQZ"tbh W_@I>rssp{-%0 W?'$BDN|~)# Z01%׃"lǬ3J됱Ie>]M Ty >$p W?x{P4W^y- 5N2Ǖ6˅f{4K,£`ܳQ'*O9+hLiy TG-^`S+,~~J@ (#`d撮[mUJKGX5l{yc*mM$[4XY`d㋷= 1tbV]p0/>8Z;P@p02$鐧RX7!I?΂L YNܤfUuҊWDYW)t!h)w?`ڵhooXҗ͛7A嗛%9^Vro~6·HFZkKt# .׽s"jv J@ (%0Z":cHoƐ2`ä7C S[BC)4ซ?KAii) [1d.V.6߆nZ0*R0AS%K"ϒܧݰ3I{"$熋==BVT(X!gqw w}@^tEb׋: &ZK>tǗ Zvau? /ә"O^f=ѢPJ X%j5TC 2.Atb4Xd]z{?/qg12Z'ǹ5Lߋ9e2ex[)BG&pxάavQuØLX}M2s؁"0G Rjr!rHZsrZWQJ@ (%0\2=m[ү ъڽ{ q"?Z48KRmq$Eq"\qJYZqM%PxC$&AaHTK\In N598jsV]Mƫx饗аC_m-5=uI (%(f*^y3δSS1je#Bڒ61=Ă%)H;df#"S)c[xY[\\D E0g6EH/q vZ%pDEK" p_ޏS@{qݿ]:CRx=H (%&ա'9;nCwל ^e,-9p#-;R& C\,>'\bGǠwb{NGނ"<1E\%\0@Qm-l.s6OtrM~%Aw8'D9heEb_Ĵd_-:W#0sWu<2ѽ7(awk[;qCx78-J@ (%y|,R7< -kdߊb"kVӈciƄ7)v<3AEdlI"1A&/9'aA//BVaDAEeE9#¼yޮ"șSm-݈jzh3Q Lf exǻh,-P$ ܳɺuGg/r[~#m~9r󙻍`YtwpN0E·l)Œx^zy'M/v#PJ@  Dh)W%򀓈ɔ%9xNoY &m 1[։NjXc9EiYa2co-}xn]y +.#;\XRRU;q~?.=xh pO_}/BD7o-,po50u,&S:gD0P._U/[&sn>Ug=κBa`de]kW.*3ϣqA}{}wG?>ppiYL9`ܳQ'*O9\G f=|(ʷ,ZPJ@ d-N'Hӗr/'Rɾm2ݑ@ أ4LZ!m(ZcD16x0S* @ Ծ_C)-+qc4t ?_b -ӵOX>?jBt_^{A>3n@d #YT,b٘ $ VH ͭXY1XZrCZXunt֕"|p.LW;w3zcz?{AэCDLm{ɵ{-YV(jÎCoIslG`' h(%&w}jnyBގ[ߧfn0M';.vvv)͛wvFOoE9q 2^Ċ1}2(ᗗ:QH"b%Het0~βF< 9(Վy3hJac{^l*l&6d~M59nim!dfYR4I Pa~)b]E"֘u8#"3:eJ4.ZVuk ?9r3/̌'M$|/Ѹp.񧏦ZOНlntތ8PJ@ (%0&dv*W d[{鐛Uʂ" ~eE)ض&[6|sܦ 2 #kDˉc +!ƬeA/}6W RPP)VX E"L}@8 sm(p$G{ԇ` s{qfg@c0(#@|.f` —^0DIyrsݰXA 4Kaܑdװ>OYRY(˛|I^bݺuسg"FPTT:ˈ{,_xxq]wk_ڌ8VD ^45}}y7W7%PYC- ?nj&SdX8xrA1lڂ?"fdA^3{%}#Vx]")B|LO2Z{bAAR YVDGf4~VHĊ+X$xWnakw1@?[fV2&wV"e.5L )"D墊 TFLtXG*CM]D_u֟ҳli+N7?yyy:z|rcMEHyGK/᷿-oųotbPJ@ (O-NA b2tڇCOFKh呞 +!ìy5Ch&S[ђW"]U8h IvJ֟nn2ʐXkĬ<_'J8?-&A"Vj).UK{IX RDE,]x-f[`=~?3:ǎFf[:;sʱ(+.11"Zֈ>38OlW.s]=~,C̭Lw>ҩ5r| na+> YJչ瞋O?x;EFl+N1GMFihh̪k(neL3O sgzNd3LJX"ؑd ')c* ` YXuE]j;_8f΋P| mI..8`+QQ1u]e"$%S5X SR0Nq+~PPbE=4DqCF댝=i1H96<[#qwz1n2@^5Ɲ"]bTz!Ƴ47{q²c)ąul)X|K€0qee,?V230kPiYX P0>4n`"V|{o'U}?W4 Q㮸$.Ĩ1oL2It2Mf?ąqQ hqAQ 4 յWUߦi.sVݪuV7yΑԯAy(w$r:X؏%ąW㚝h|=tNqyy&P:CP-xr"\ zzCtNc"pvhsyf0~’rCnXQ!eum~zsSI Y&:%P'(EAy;'$oeN֧ 25"_2Y U9|g?EeUqX2qfzdb̟: 3D(\ |~ "BX ̈!xM9k&21Y<ZbE) kt"".µ`"xYl'dgTNe"-a,QSK">q<<^gh_*S0k|#awtyJ}>d`IyZo-ƌ SCFSk@2ƿbRee cҟJ@ (%,"\d_7thɷ]m 2DU(!D\P)01Tr:|RL>4W0J:L%XQ9mfAa4lfu-s9"N$#+N/|bzU/wr k0b%ϖ3 VhRƕ`9t9kX^1mELCyV? 7]\F512lj@jwkfLW<< qeFpeR9TqU0iP^QJ`Пg`3{is g "5Gwՠs)7pk<[PJ@ (" ~I*Hrr)b"$GZEUP>#+K<~6e9'gK&*R!ˊJ*b")$esX"LQ gvdYޟk %g0En8<#VMbIccEҌ/bP7DY?V,ixo5++Iɼ,|λp;Ja.{C (%@f 6.QV90…qC%g4H/pUeO>V@S %ƫ"BEc|+L.|?<=ffö.8-̷᠐ar#-"x >+8 Q3y<bE "VhgTѕc!VxxfX)brĒ"(p*D_a7k/0XLy!%Jwܲ2^񌆒HP17Y]{g'f8A䠶HAϡhDͻR^B/XPJ@ (L$`E)D,oac?נQf%3|3!^Պt*N|N;A_UU}HY"CyP[ ؼ<˧!{lFh#=u?)V:i-B7#V (U;s'TȊ/(K򑏬ȹ"3bcyN|E79;݃q|NUxaQ ߏn/ϓ 9R& #Z8]:b)`4*\/VX`h^} #܅5U=(oAۋU DÏJ l|Wx0 G^㌎p8uJ!\rG KSts-P6iZD=9qJ\xvl6)"P;&JfhA^=d&,̧e$QM%9čԂS'2:3@f$Zlo"s%f{'*-wogj :/s%PI@D5HA*gI'Ӟcb`|* #/NXt驲U5&*e=e8 &kxQ((EQb"C,}1 XOD4Y*|)UBe'&֢;'˽B/( =+&VRH3"fG55s05Q( / l@$*I \a]h졡},lr䣓IC>Cmǒq 5guc9*D|d˗Y71e\#ZB ۷;2}*ѽ?Mo(%4ERbGAicfmVO^T:e.8L=g "KH١TZۻ>. $uOb/V/1MR }@*Wओ ),A$"#}_\a+fd \xneRdeIZX'fN=.נlemiBP׈2#x1BgDYE컛P\Rk!\c92p`ZX1ؠ3;פE֡NDKbܴy[aEQ/?7UR{иm%PD@&n"4Dx̼wyp*P߮q*k?k/|ڮ E"HyU RHd$gCZH*kHAlj逳ă"?MaqB:'Gq2YkbKr1(eYo^E?l/'$[TҼ`"&Ntpf^TR!B%)!b*JӋ٧Wђho?`l. |0h]N|uAfzVPVrDm+O12|H U9X|q'Y$^lb YX!8+ٓFnC4Dvq#Ckeef_Y 'r3>)f6Jѕ0]a݌BTV0h[2lqRXD H̾>$.TVVpNtK:ܱJAS6g};1k֬׾5x#/~KXNp_$GGz ()Se~css3ҷ1'ޕ}LDXBE<@BeO`wx]n*pWQz z~FMTq ҿrH,y/NvD*09T{d0Eё)i,\ܙtbMi7Jy}xf.fQVcX:KjM…&V klĥ.D6+1d(GxepO%Fig,4uUS72}Gp"4gHzs=~C$3}t׿K/d^s3͛Kw܁:˿ lbξ/a޼y-o52z ;vmӟַXnI sGzLKs/'~,@^G(L-Y˷:%ZDSdP̡ =.TfJVbjb'" {hhDŽrhm}bxL>1$ "J19h+'!yq/>-ž4e%\a?6FW$Tήnlؼ睵Ee1-~@ 3uiQSf4 Q?l r&*1ׯ:jkk3c%'ĵ^|DgIW\q.ksDx\o <4M4442m4p{:µLiw!G*:JQ !Y(n-Mٗ.Zl'&BK;iBZ`%dal߱3O9l0)ZX !9}ԸJjI KV FYY@pԎmI c&S ; 򚚚m|Njzf=~x#Ln݊.|"wyx7iӦĉ!w\r%IWK˾ϟ'&0a 7^y xHN&<-Fjj3՘Q[os [ mA+gtDTj&-%PA@ʁDuɦI2n؍lJ135f-Ltb4ӏ6؅k._OE%#Xvؘ2/‰1|̾J%ƨT"NAhV|rlM ;V0Gʏ~#\ve>p cW_}5nF!"F|& /DC$"if˗/xYc *p7;4Dڵ˼YL*xkrO Qf9G~ yBVO+t41 ĕQ %>"f#moEsGðk1_1xd+pd*ez0:G2=2nzիͷ~ۏl=k[L-Ĥ*wpROoGGrI*`ct0h%3jw7eDj)`PK V8f8:RX1k8||{rX(ͨK=ӯb҄*vx[d ] ps[?L&3H4}* ?|bX,BAXAFvn\MZO&N:~P!;!Ud|xk+EDRlY$"En[n[>mCRMD ?!.ҭKf/k/CCpQυ ZrP[W&|跡sQeO}ȫ镩c|%P)Wz.6%;PZPPINhx1fApnJkƖȭ uK?21bZRmQzbpŘG 6Qt<,NX~X-Bý%X3xuP=yɤW^eI 4#Qe%Hds6,<|M 6>UiHECYEn:KXu㙴_ASdV='ͺ V~QR'Y삞\&aϞEW]3/0qП<HLk`{:)XD'+Id4o㜴'EE)aD"$)ALuq$’o+䚑>9IcOfF-(_)q@`h?UO+\x3|A'NU\-Y%?&mVt9WQ (% dO&}s Ɖ~spczNbC-LCvxpρZuj2#CeODfdY}0LwT '~\ǦnsTdOa*U_02 XZZ`_6 ձvTJ0#P3KĈbNIyf'/2ߴv%p<OXu|a:wBb/jToR<뱩,pgtXPJ 3Xtʹ~OIsh{2d?-q;%S(ZЎ "19/wYE%BoDf71FUe9P? OLJ7S9qyfz%FċDY-Bߊ0/wjM`)OWM7ܷi&"UΙ5aQض}'r 0,ݨ3DMz~X"=4DḎ볹QQQY2wS 63$k˗Y71e\| MwߋoQ_BoB|osPJ@ (㙀-sN-K=p0'aF,nr2DHwSoH-,O*jC/1Xyq9&qiys4%a %vYĦO>xX9Bb6Vt5yl~`H#9j$|,*Wq${P4~o`jv\lf SNdf*³*dΧ%P'hE{`yjKVFwF[2hu)DžE-v[~F ^N+~2'{>"ߙhq"6\$aXuAmӌO7-ғEDJo}tϙ,L&%Yd^Өg͔2L[gy(jukhZ!*J 6rҒF)DYL #.>lj`MdPR` Afr:PJ@ d("`mLI(Fr=(MlegNҳJۺ0A(0>~}EBEoԣI:@Rޤ<'ᆻ ]=)aZP K˺>]/_Ibo.RkxMy QG?Nq$B#‡ebv@V_Y[[;Tioc}-FS!u2M/Oٛ2U'=6 ^'_: .R2Ycpz0~o琯{.2s`敘Gcwcrn zN nӤ4\\(B,PDyI0LDHE_N*vaUy<(E-.>&&?ͫ(u2+ _AQ$+!V P:BQbCK^| ^4<{8o eIIn TP7j?"=kظm+"QJH#5r.^xoҥ3gΈXz@(^qe^7e^ \޳$ECD[敞GY2)C!{ osBOa# "\B,kg(a$'bթRgrR܎hcM;p"4 ,F]#IP9ᝂDΈ_K+br\bt=D(KԖQQ #0RSӡPJ@ & Em)j6^زQPÈQgF(uBqM$O uxkpb7.F^eB!AepA$!z/Fam3?#3WJ]쩪^n=nMf Kӗfd9(4mٽxBn:PXYh]<[ĊgOG`_r79>*+@tlxuzyTp9+uģ#%DE}VuLIc(1VF`߾@G#v5I՘Q[Ëv)(,ETJ@ (%p<+ڲGxX%K ^ 1<V_a,5<욈`MYUYh z{.d<'6DaIƏ9M*%/Iq0KIDATq{<1`4?WkG`tbBꣲ`tYϛ\XbԔ4) !,YDH }.&R&qq+]_ȳk'3K)cHV1,FMM2r)eIz{L$Z͸͉g'<+磈+~G7{p7wZPJ@ (|-pKMA,)E48kz@zIDNH.y`5h)׊ԱB/{8L^$CN$f C32ݼ$8'~ +Q-n=L }Nc>فR89,F>}'Y,y 1FR'DYĿBqƝYC~ĥʀ F\b}yϝϣzbI߈R,b(Kۘэ9 ϤzY̕c ͞;UE݁% ୦3qe?C|K/OIp6=M%+db(=0۲{4;)XJx0fui ~; 7kQlfը-DoAS 4G{+hst3A#,JE%bd%ot/8#&2rrcǝOy90u<YqZ|HDXŒ78yOc2z}b=3Ͻ0etIe-F b $+Y~vv湨t=u K`h?.sʆZrP[$ b4EȒ\Qގm^_E?}MVJ@ (%NDE-7W|˷11~n[P7@w./r)`,+)c9F1BLΚH]u]htnSúaߗ0zӮ$#U7"Z&8ARY_3gCYi1\5nՉIu HT%QFUJ64.&qW$%LJ:jUPZVQC`ђ/<=ߪgDYWa~2Jْ'V#pwpY'=%PChóc uqLM0=ʆl>IX㡚ؐ3wKr ]^"^L "喇bfrbd*]}iuzXV<n7A:og>^ 5lݻ1qb Ǚ40Ȥ>Br(i`Ýs6؆ٔ`m,Em6JZ|Tň0@XIFXOE):?fuc"jOzz{,,ZϸsSx`ތoΝ),Xo)Tf㮋мǗTJ@ (%pbIeo%rKZkx=ǠI"ezjbJK%)<)ba߈6x?Wł=#bg)Ŵ& xIf"$k %4XrND=D@<>Ҥf|~w-vڎ=^d{(~'Q`ޒMP.?qe(-.ޒ)mns1O3iaUehΝ8E1~M\`IhoamQHsbѳSJ@ (%`hD[| X='|1DX2޷ݱnx4]4M)H @"lLɹBAv.b6G^KڿpI꘣;$򐴰1%LšY-lGKμtiC>~ -7`ݹԃ|1u?28$PJ@ (%0FX|IљW8Zm=?ޖD薸 \jE_ļm 0 YvѰ"%YSB҂/'gpI%b( 1 )ev'}C8&;Y.胑3),)$GbX|DtXA~뚰WpLɰ%},ɴu7ˮ6 HHp}*t$ZRCk/x)d5 ug`|J@ (%4Eb]x޻ jT/'qHձT&}`\ NMyB5e! Å> -e YӤfUP0尊qˏ,.|ˡI|i spR@4d5:`YY<:\zDa {:I# ia9_KM+[2^1=p(K+ {]4|jR>&GBؼc'>qŘ0aX'5J`pX0Xe!u2M+N3eLO }{lnnFUUUv{:*[u~-$rY"lmē/YeRN[2z1b.4}-[iZqi9.RSL)&k)e|7'+*aA b{&Qvlشξ>6,4ݘFj.\xҥK1gΜP4P_Kk}6{_uV)d˘/¥ ;񵻱5_]6;&EAlcJXVxL:mǢiay]+~ 0BիWcVR%y|،ĩ΁-?[2KA> Dh>`zPBع;O^ E֛JHK4{jY;nEV;xI,@-Y~s/ l^?PJ@ DX[2h>nmlau)|g"%kaVVvvba 0r q^.1KEAϮƆcą6Q@}Hh܍ 1k٨`?ڏe.qA`h>ף~7I% EYdrs?{˖}8mD PJ@ 4KXe \!)7FWdBA(}[lyR;{EM-)[Lf51DBJʘͪ%hذ {0]LRB^,\݈M[vbLic)栂e. 0X$" iV='ͺ gsbL _Gb49 @DOA (%Qb5eq焿C>#\+}\z%pmk_ SFe0#=\hB''1jei)nÿs/BMM@0m 9*WQ8!0Xt窧.e>bAcwlUʿ,L[o*~C (%VᲨnTu"' J1m@ivl4 NX$Iebbg,>[Ʀ=id 5EF Ѻj!DK[Pwfsg+$>{.>r7mvաPJ@ #` \a~<|kAE_{p3ٶ@}ѱ"K_;I_2J`Mxp1=\zسg/3YBؾs'\v,pXu(%pp~Klo7+rwO8qֆO,ǖ۰~+{2*XFW''GKO%pĔY^nن>:'^ק3ẻ"/Xb~ J@ (%E UmYg ^G8;Uhpl1iael~-Yd}-D_>ñ1,+,lL?~C ŮtxqB^xԌizHJjπ% _3v%Ռ],vB[Pc%\%\ns|M%xdo"Q23pqɛtIC|-V-Ȧ6,<eIp,R ¨YiY1KQ>x L,c~4CS 0$PJ@ (%%\sϢ?bpz1)VqkҝeG46k\ɦ$QlŒE,"\:cӉ«/s@դIq#5rX2d%0@bŊ;#yc͚5#1oeˮLi oͨJuOB@&"XDX"R%t۶5!b&‰2.c1cLYXE/PÖ bo3ˆ:2rE,31+(DX|)Nq"{i6#GMt\ʹx?KbΜ9#>c L{ŕizyޔizݥmXQd\&RI?3xtSȮ]1d?1m s1vM%~-+d1%Fx\T+T0Iƒ}]hGTW"E+\c:X 0RSg{{XPJ $V5\ף<hDN6͔Bsv.Tz,y]ZJxnZ)_I S%W]3Y`+]EKnDTdԯqJ`?OK Ea/ƌ d\tN|Ag&NS7PJ@ (ɬ,e2bҖۗ. <_xwzdWx|'K9dՊe!.c!el%eCtZ!ZEW,=H2$UU 0"FWķ"+L Jp -ffR|˳ pWGCUO+ptdgɗ q| g/%PJHEĊD[|K]gǣ I88YIid=/8K }]Zbޤ%J_۞^_KRrE)#4ۋw#wubYgx|HtE5*苔 -{P[UĚ~Xj:WK؂@Ÿ秋Qi_8sP4(%PI˴-_YX{&'<,<1B_ \,.6SƀxIWۇ0{d1B_`BBcb%FJ7K7һRo2UVH:O+z6E֍J@ 1AElls#XKj$kjw4-螀KKhiހm3q_t(%PGLZQI1"rgff⁎=3߅8U["0. ӬgDKk*ג*Vp/h04'+"V$ODWDtPJ`d -7zO4u0U,j1xs8::=x/#sW%PcL~EHYd.2)Y=YnNJOy69,ȋ3Kpvs;S#n|-JRX[Ǣ+~zQr{(4QX#O=M%0*<@Jpx_2\~"?pn$TJ@ (%5. "O# #%,FhpIШ@`_1 kdB8[uځMJ50~kĉYӷO$dde/Jkɘy0DTDX`wE+GY=(C!hi1;';(X²DB/ÿ=t9:6NAE9J@ (%.oIXpVߙxMw丑U6)%d.,f"/^Dϩc'k1-m"Q1֋*VDa7+|VTJX%*Zs8rDM#Xdw;Wzubz\ZXkpPO 7CVّR (%5A.I_99ʪYxm-:fOG60%JsDbdx0C}-R.j%UZĜ/"ERD((1"b0:RSnKM:T"+_FWF%0zk/x)R$g\'I}ߞƮv,]+%)2aZċx]dRx+.Ë:/-*e&-G9NkqnlZ |-"L"9W,]s9WF@>`1ez>dP'`MY5H-aD(D`D\!W_܌/#wj+8Eї !iY&ۆK+?62/Z*"Pr}Afڗ֡C`h  F:T7NLAu6sN[w}3lu[Qɸ$'ņ,ib'ΧBD (% ذĈ%ddmݖ爠֩ϕmbvz?km +-uܶ^cer[P'.!9_Ŀ>i'a]7bbdz> ?e*-brSO\DzfJ@ (%KXk ">d N&hyzkk-a=.S͓Pc~^itxQV!͝d҆`urcL|V$PJ`*"RqX6@kkC[u$_D_QfǝrnT: [dL`m܎a@[ܨFy٠?PJ@ (1J@DFbt:*XHO[ H-ցڑ;u< p^RoD .Ƕ8uJK碚e }JzPJ@ (%PGJ`h΋K_Ǎ5˜;;}[=rѡPJ@ (%H?A%杆%,irmeIֽ9އpyW7KzP`Q (%PJ@ (%O`h|غ.\j [̏mp]l Ս%PJ@ (%$Z$أ%T{"쐫C (%PJ@ (%p,8WXq,kX_ۍ7QT@܌PPJ Fj.\xqu-]srL߰/Tb9biاC (%@&=[M (% ⥗^I :qczW4_*HU\\ޝm?OKXA, {QU#/ ތv`ws7'OBiJy{J@ (%N&L0֙3gsc~_"iz?41B8s+]2 [J |\_CgĎMwPC\.dgg٪w2=zÿVh*ӣ7k\2uRnq#ßy~ջ{-^1n:\}L=-=.%PJ@ (%NCDKgsHG>4SP-_./mcPJ@ (%2BOZmw׍ك=؃6x\2ȔPJ@ (%8 o?Z WtUV}7^ǯPJ@ (%qJ`?ђ !p`)֋jxZhinTJ@ (%PJ }bؼSǣ0Q5-E[oslvtmEWNC (%PJ@ (%nEKPJ@ (%PJ@ 8_"Eĉ+"\4/%%hIEyц?<t(%PJ@ (%pD_q"F,-EDy,Bt(%PJ@ (%pDa"*E2 \Hl0-C (%PJ@ (4DX$")b8#Ċ DZR_ O"*DفfmMJ@ (%PJ@ (#& D%\DX%a&bЗmr9VEPJ@ (%PJ@ -z0cEy%XD`QB:PJ@ (%8j^"*HE4 p1Fb-ONh!J@ (%PJ@ %ZR#.CRyl rb Y[+MhEPJ@ (%PJ ]($/rۺ/Bĺ-ԅwč֡PJ@ (%HKZkٿyڥIENDB`././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/doughnut.py0000644000000000000000000000243400000000000014533 0ustar00from openpyxl import Workbook from openpyxl.chart import ( DoughnutChart, Reference, Series, ) from openpyxl.chart.series import DataPoint data = [ ['Pie', 2014, 2015], ['Plain', 40, 50], ['Jam', 2, 10], ['Lime', 20, 30], ['Chocolate', 30, 40], ] wb = Workbook() ws = wb.active for row in data: ws.append(row) chart = DoughnutChart() labels = Reference(ws, min_col=1, min_row=2, max_row=5) data = Reference(ws, min_col=2, min_row=1, max_row=5) chart.add_data(data, titles_from_data=True) chart.set_categories(labels) chart.title = "Doughnuts sold by category" chart.style = 26 # Cut the first slice out of the doughnut slices = [DataPoint(idx=i) for i in range(4)] plain, jam, lime, chocolate = slices chart.series[0].data_points = slices plain.graphicalProperties.solidFill = "FAE1D0" jam.graphicalProperties.solidFill = "BB2244" lime.graphicalProperties.solidFill = "22DD22" chocolate.graphicalProperties.solidFill = "61210B" chocolate.explosion = 10 ws.add_chart(chart, "E1") from copy import deepcopy chart2 = deepcopy(chart) chart2.title = None data = Reference(ws, min_col=3, min_row=1, max_row=5) series2 = Series(data, title_from_data=True) series2.data_points = slices chart2.series.append(series2) ws.add_chart(chart2, "E17") wb.save("doughnut.xlsx") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/doughnut.rst0000644000000000000000000000043100000000000014706 0ustar00Doughnut Charts --------------- Doughnut charts are similar to pie charts except that they use a ring instead of a circle. They can also plot several series of data as concentric rings. .. literalinclude:: doughnut.py .. image:: doughnut.png :alt: "Sample doughnut charts" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/gauge.png0000644000000000000000000006644700000000000014140 0ustar00PNG  IHDRIsRGB@IDATx|\*z/"F"Rl` *b{ATRTA@ H $\Z䒼23o޼ݽw{%Pqw>tzv;5%4 ~~~rMxx8~mڵkp鐝49oذ!7n VDBNOO莎n/Â'N ?郼| 'VߴrJe˖4h<۷]w݅k% DGcAhg\mZ^Ts \$W]D.tkZ4jH~+OӺEݺuk$''oa˔wL\{9=b2_ ("@ @;Ȁ%"IxbI\IlbCt 1@t 1@@E|0 OkJKKM%"@ D"@*O 00#"p=+/_Fmjj*)"@ D"ALy]^%U^<+v45|kED/Et 1@t 18j "A8_=RN[1jo6y TR7θq(󜧲o:S3R 9Od+;k}}eQWX_~Y09OHUm[f ^id]Cz gӶTS˺|[Oul]OoGuGWp; U ʜO[ϔ$湽$7N>~EW烳:їTzd>j[Sr'LE_I+ b\U.?|La_x__ A1ps{ar]ew寺]!Ǒ+f9+<Wy`_Uqk@Y J ΧW=9 ^Hy|YY~)#=^Y9Q}D] >Td}Ӱ챘P.|.Ss<+?@_A"9`8z6I6\Q|ʊAAA/k9s4x`^ZʿSgd=_y-ͅ#ѴE(h-%kO!ŕ=j.kݝiQ+8̙:?_ߢHlŭ]M;:DoA'>xiL 4`~ K(tiMm&R5oW{66eAW)#?{g#_Fx 6@?t*vs6V ,hhu|[E,W/a` #}Ѣ]1 ./;Cj{yEO-n:IzO;^8SP*my$/g"DO=Lfn{WVj"w%MM0 n&rd#9s[_c("m&?ovaſltl:2Pʾ<WulEEۢ,E. _sM:sP,գfRWyBö46t+rG;^EzG趷-\$QǷM}+P&+nT7LB6b };:ȃTy3ES=r;K |SXz--EU#-}p?(Wy 9W|CQv$$Bb_]i! ,)1%pV?eE5 cv2V/yx3\4&nഞޠ2r827 IWE,s-<-aQWk'Һ\DS;=o8`],y'&6OJyQvzX8PLV6 a[ogUx1ɲl\G{udHvGx1gy],1"~qE:vܕڅ/y+M~Pl> y_U?We}_:މ#]i&Ϲ_._E:?WJ],tl Bty0s'˓󩰙s9-EY)c,9שL?QGȽ7ϧy; Ӿ܎}[-Džom4\窽>_eS6yeS|CgV#(JL{-:S1o+:u.ܞUn3i 2b,SApp04o ] Şn!Dʄ뿺[vNWQ:G\FY}D.D"W_pk =[6(ٲt_ة̅-R>z+xٕE|L2O\ D+岫}>!'r>:.\YWbʑ}憎9SYd8@lsי>&rݱ\] obmv#R>v>^zE(|[l~㔏+loz~"}Mj*Ja^22GMMDց WYWSnSo YveY-_m] vT 8$8vPRb%9n<#oeG~v?xm} Ф[z2`)q7fmGq|?>7e^z|^P? >_;˿<~G썯lwV6_7&vS6MS툧/lE(0-<NJ^ ɻj}ؼ,eD\)#ʎtv.eYԉM|'uz[)#j\N Qyn ϨQI@0%aEsKe{:ї<+U=yw* ?弟heC޶Ǖ5.cW[ /y)W*q9!cOU;#e1./$JQ:HD+)7|q=G~?w";_45 0 { ݅ۯ|M?%k0]RaoBuh<>"{'"}8(kMuIGX :gоfV  ZEAf&׆ 6Y8A*ؓA+ѣ5O2"@ +?wb_YO9\#`φ_0싎ñ* wzt@ÐHt/: ZLMg]pG- uA#oG9#HL=wʝRϰ&/"(/ xmVN7.AE>("@ DT'WƵ1-Ђ=KQ4f[7MAU'pv%rwHχ3ٻOH/R~Q0ײ7M7dR"FΆtY jӨkiؗ_o~1/~D?ԫ!z碟ň 3d_&}FT-eBn"@ D&pze@e'` J pػC:_6lzLcPMadVNI/4ͫɳҦ+t-^DG/ yH\x xټ(AϞS]78jW֖gW/~6ayzCSeG8I/ D"@-Y(,M4AG&hb[|>QqpMxW,͂>WqY =2?Ő JwNT/&U+kM1yjZ8X:#0,E_F_#C-HD"@ UJi0 a^/uC㦶 +nė8G:7Cmpq-8u{J˦S\~s9pgIYyX̥@{0*,ϯg(mP8N~Ov4 x6}ԝi"@ D[4 ,s<ʌQpp3F\\FQšCeʣ(8 P AV#+Ozav葕0܉Y,Y/"V1JHH@lUm!IzUԃ"@ $%%?#8 )lk7Lsηy}^p{&Vʼn|6w-kl98zXlGߣIBD"@ '4ڲ=]-+I5;ɿ@2L+8z"@@"GNz umv~)[D["@j-FBf8|3c 栜O3TİՐ(oЧcab,ԫ?y,(#~t^HۗW(@Rb}׽9..T\zU/ Wm5nr ?ݙ6v`) `Vu#D sƋ2SpEiJ.3Ĕ:Ԕ~S& ΦRSvO6 |\w1ej4tWu$mƌ֣$ztLMG@4c6)"P n_~/ơn {O~BŚ Zl]31ϥ(\ԋ@4=o΄#~o,wɈ'10TY?^gohjGڦ*7 ? 25o{ WbK ΩXt?{X"%/VGcRW>ƵY%yxG{֠ݘlOڋ|M{rvz_OM>aa?5a =lk{P^ǎN\/=C)s~ ucVSȕwaA:"X "-h}I9K/^,}bibkwV?mƅW}&Zk3dX 1C-%U>. Xwx6cgCTS0/uLX>tPKJ̲{-rݥ_f Y&A]4}}tȠ[]d}?m`c7Rw ?IW3=~+mc%JozF/Inz{v~#N,QcXg'CmA/71)DN:%\ҳJhck"{cQ5NՄ+cǥS)j/~ 90o!#=;%|ҟ|$8²5+`)~1#mT*C]GʕV 2HwWoḨ\)49I$7vtcfT>1HQNf}₀ ϼk2le/,ܳHi,gw_qV!YKϓdiY.Yn߹eg E0.AIUD\|-?9H0!11'QTo\ AHT0pϡ*`P"C\ʹa_^Ұp`xb'1uD o2wqgxqN2I?L6Yexem[pYlnmUw{o0m.OC@@XY.*oS*B&;E%Lg o<> lJ 4>9P|;*~ ^[vVXEo7űࡡp 3$$W*Il\evxF[Dvpz'w5kXŽcz Lz"PdQ`q;moaWF&+[50#.갴FYӛx̵nvS[EjzA d/Νwde9sY[e5Eu|!obn߆#X[;R>))8V_M{͊vS+1=̦=̍KEMe5Gf<qNgo1lN[DsPph9~S]+҆bC7R{vUE%67rW>;hNtI*fc_n{ln~VS$9:XEh5*C]P.A݀҄ ع@qi@N{ >k嫇|q޼tʅ_ (}K6:j*RrXi7mp7*Yb'oKOt1VJ*f9_[zRV7mX|{gJkg9뛯3%V+0a}vF_҆ncv2"Q ϋul/9q[$J瓒)vuS0nJb꜏[)0PR@ƿT!fm[I.1^~94æJN~Vz_=Ҭۭ,ZNm/cKY]dr+d=arR\Ěc녯6([4g.ٺL_\.Ή%LHU\ܱGx~e<{M]TLO^'e~'zYŤ8"/FzV&ؽlr£#i_l6-:$$ Q"B7̓'\Zcs[8 C[ܳWvelI7;05biK]1;Z1|+ס훻0>!].֕4 TT$nHJJh#Fݧ"l%1W{Oi6/qz'D D h->薭RRzRm9{ܱ{չ듽uZ>,ݓoAR7-qv{&<0eDF+N#% ɵS1MMME [ u}^X,ӯ AWT/]b U3m&+ڑ#Gz8zu<Գ{z`xV+i#D u}ZwZl7E67EO>wc D|Rڌ O>ćL!D"@j YD:83^.@&hש9¼zgu 1s|fO#V^V_Foa x[՛[ F#XN47cݛ$|qXs8ۤOkwǤI[4o->ٽ¸t6I"@ DZD-mc ɊpMObL \cWq)U h@nl@iXt}G>'$$x}61'c)$MD"@#Gkk[I["bZ)e:2H*Ua0 IRtPg"@ $+6##Û~n"@ D"@P,\@B6 '5)gnKځك/c7jC蜲LSMb)CX>f)qXOyj4=08oP^y#$N{t"@n9%˰d>dU(U@V)ٴ_ S]ѹ:u=;bʌ\^x?"g®um[þsi8}Ό{]TcKUrI D#|5fvߕ"[T4 {' ssQ@pgj>D՗uK]GaVr=zJdNJ(x1 hn:]%!cǃm1Gwh6}]yC D&pze< AmaT #+́8O݉eq]sg_ZYR׸"(/3Ը1h?.r?/eѝd*۶ !0D D $%`X.8vb!pw_n?碇px.8~>\ʹaSh1<>/zS?'Zˢ=#6-tjdZPZ"@ UIa02h"$~[5K?VŭJskX{@K#Y DGٻ}1aL]Diw糰juؕ[ċٯ9S1y[ŰXtLu"@ ^!BwPd"KQ/(3zŐ4[F]on4ms;`+08tO spTJ9lp0+"CT&D"@@pk4ooybl4>%I?ɫffw5s4f_2+Ʀ7߶u8ܼ|g\ H$b""U o!؈!Vu"@ UIa0^z _ QMy mX5 ޣ^ q鵽2ĉǖX QWec{@i>H:Dc!W϶ D@—/2_HF!҄g+2%"@j:cr(  і;{CI0RS2Qm𑒉@0Gn(cDbӛ6 A@bA$ O@#%,Z^[,w]kx׆؄=.̥ D y"ooݰ@&$Z7v6yI@ `8 q bY-̂v,$.͕_._h{+{9\ DWA4 DN@ !7ׯ,BfAxU'i?=xpa]$M;dȮ/UKh<"`6>>^Ghi>eʈSOMMMELL'U."$-dFݏ,^-,8lϮkqwB0-{id KiGUw1r~SubY͇XY复[?v̲S>f#srC$B8 GCxbQ'Rڌ ^v59D $gna,pryKח- ·l]JDx;99Hf?7Mtn=LS'=qbK$axyI}Er~~䴱6 u_rШ_ Ca?AɸR0tg_4_Z&7pf،ㄗp%}Ya޸n4[?Qd=cOatܞ#"lұFr,xݲ05hTM?*R"P-0q/ju))-q>R\6}E6>voNpobg F#]1z-4=nGR=v%2'`WH|esNQwk:ƴewۇ7D_9?JX5n-_u3\/SD^E84r؂Չ:*"@@l'*Wa$ncsF15&U_Iv[Nqc`Bvcc7ٮM[~J>ur]q+ҰZ]-z$i"@(?n 7݋N;lCa76C6]MUxĠiXhzܦႮꬫm#ŴbW%(K=ή@9xq*6+DH % `(bs`O9jB6ue*N|`օ,IDATBq)lNgkVNbB3'c6jtExS) e?5(&ZG%"@ ɰMI+kRɸ]%rF*%$7 X"sP|!k Rk`1i8+>ٽ¸tF4_ߋujÚ*  DTiBƶ/Vlb"eɟaVjd"=9jtH= ˡx)!idNԩXt}G|j7{:Ki32us"@@U8+0a0tX[ԹfѸt/z1 ;\Sqd9pG $C DGxˬu#38>>>j [.ΑDو0oD|"@e8 USSx@NWȽPA{iG'jKJ@M%0wk&(6J"'-iź/M u@a.p TN7~*ҝ}9R)0bZSu;sl}n;!w:a=HC~АD_' @#M)+U/BI}cy>_TQN<x32+>G+bX?W\"@mU{sH DxQ# b"?o@%0 `(4ĢE׳Rv$]D"@|ۀe/4 K!-qh5M`E1;(ZkDl m.8!"w D>x`WN."+m/| 'u[@m%0Z7tq) t(ZI  DX,vnP@6;7C"VuiGA1IFCsLzOKw@@0wtm@>"@@M'{er E GQ0t pǞ4={MTG Kso|9%0jQ@!N'_3pQ"@! #Go^LqqquO5?xg;1,O UKڈ@Y7trk&`47;bӓ>ll64 kZ:_>sz^H쵂`b)om'WL"$+6##8 D' |3 D@MS,pڮѰ)j0~qWxBbr@\مUZOLE?7+_s{S"D"P4{'T C Mr ~Ox<WCS\F?tB6}".E 6=_d ĝ .#b,3 %"Pk8Y(-6x[$ⱩP "@ UFOҬxƳ\Wl, ѰpMJ3W\O_x<f㾷7,¨VH? N<5\[gk#5;I"ⴶO?2"P' hb|w# ץ4̧hcC<ΡM"A8 ƫ:?[1@ 7' FI~Fc=@+ց#\$D2>~LY<Ϧl@\ J; | MЧ89"& [LY l"xP^ 8 B ,SGdJhJ>(;"@OH> `Bk/6-v_0y~[VSYr DUV4;RVQZNqi2֭I#[kQcD"P#/-3-y(3q>߲ρ5|M_Yt<̟ %by<#%"P OG"¨8GC<$D0=ǂq/F{+k_W<ޜ3 Ww\j%UGi07V&WKERuF"D{dR}ut* 곡#Y>*V_=+{6~=夙xIn WG}> "@@&js!g x >qDcH߻eK vѫjקȽU6V8 N,Z_lؑA"@|@i1ǂ5R.)SetU~˾U)0IGrHT9&<xn۬=C"@-ۺj c 9o׮FUƎx`ܫ#r"@ !+zNZGנsbh֬]_<]cUGL#%"P{ h\1ooQSrb9syF:^t ϛ77nDX{T? /<@js O %"A9r**..P}$ D`_08dq% ׉jQDΔ w!(%lI)uO駟:qY'= ӶQb(B)6m+OKɕ|+0OhLw>K;"@8I_7>)m^oKϜ9Rޡ* %=*A|`"J~†? nU  DH0W~ C燧_t.f띍pSһb' q@BNq-z7Tv5nI=hZxKD%pGVQ<j)EEE?~':n1]Qt𣾾Ka01b荱co@ö7L]o2"@}Ο~RWTv8?'Roj7Ի=t)k$uD78 ƍ)Mߌ=⃹-dd DiK}wMP^=vm^aջao-3g#NDp40k+&')(`h1~D"PSB0޽ںu+"##ѯ_?xyë]Ň}Kƒ(K߄۱JCЧc%D"P +C];^!EU{n4i]tbKTS (!TKU6k8 o}YPzjd> D 9ol_O h޼9ڴinv&h4cuGa>#Aa01D38eAqAgND"P;HF4y ӶzmP~a9Wū"i4IJ7W&-Sh zBG@B9 DTMAndhvU\DjNRxStJ~׬!D"@£*kd:p[_,'x)n֜(>ݻ>xryۧg$mD"@ D6pV%qM X"|XDܾsD D"@`~A1#x"ζO"U9 "@ Dx`?"\H̺IH$xk^"@ D:DŁ߰,HuR[@ D"@@9 8 Pbh!<{~u9ݻ a($N D"@|`\c_[D6h\r_5\o|!D"@ 5`X,fKMqI(e| tL&D"@ Fa0nWθ B2ݛ"@ DIa01Bhw  D"@ "0Kt Ej D"@P+RNHH޺z~S1MMMELL&"@ &+ڑ#Gz5[uqqqJ12i$0 $R3 DxR 6 D"@ UOΜq2ӑb@)'Q GK/A7F$D"@ 2FoMK1y7f/itg D"@ {&=!aJGegH8χ$ D"@!`bmX?,i*;#6} "@ D"@$`3MŘ,BL<Qc |S)W2 D"@  \7"qVǞɓQ\-`bF~:H D"@(;xіyGP$7b6/4GLHYy!D"@ D5`(.sR@'hxvv_(@_;!Y;%"@ D"@O&-.\MygoǏ)ӗ3/c`"_1> WރD)"@ D"P67p6~h ] IH!=n}sܚF:9.('D"@ Dl񒔓Ht@c(=AN@ D"@pM0])Mw͉$ D"@kxRHHH&@LD*ML+PhHMMELLؤ"@}ȑ# '..^)1^'i0 IMڈ DxRڌ OC: D"@(' M} (LEbb*ݢiSHgD D"@@ {|x5| i<8;v? ɈFFST+k^QFFYSXmTPGNƝXQ"JZ* T)uEF1w>ݞ׹7>+yޏOO}/L{m 5?e?0-@@X-cz:*UL?rP e*Tjw@@XkdߴSەP̌x,u[rү,[@@+դ<$ե4]]@@"20O_HE@@)͜⠨  <0(iLG" #LNb EF/h,6s)F@@\s#:3fjTnuukS=R og|Wn-c@@p񆽇^W4)'R{#\T`];@@(J';_!Ϸr@@X{B[S@@-Ztb[zE `Z$aU b7 7N`.Bggs:zR)e2'֔}g[    0GM;] oJfO+۫o!   P+դ|6hJ<[Xzz}?U+EV=  !9I|u).}#Ⰱ  \#mOuu%ګ֥+n v"  ua<Q8טG GTWU:~G*9JTjiNB@@\a%uН"@@-n*   @W 4[X՞5vAL - &A0Tccف X)j٩e=j~y0TJgz;! tPhgC   `ӭSG4`26ȩ!\TYoSZW|t   %>#'fS{9zI՘gD7VL\z:  KpMrG=hJ9S>7?X{v=yw9dL^C@@-7v%3OdqG?zA~y!UkX8{@@ F5)}~Q3_+}&DjneJ@@@kth(WKOG     _ OTRi|oן|{ (E@@kq%LCDpDuU-M)]k\+5V[   \a}=~Y))O%W   "\a|bOt4z S&3$wQb@@ph*8؋  @k/fOlN<AYbKi ؘS& +K`.Lggs:zR)3-Oo ,U`d@(Z@@!?)A55OA Êϳb@@(,຀3vKH  % -$q gbק??>bFƃz"΢  \f}֮T[?>a¸4|%@@a<Q8X4G GTWU[?yTi'%z[&;@@@ G#:3fvTnuukS=XzQ8,3,Q5l   \aa!W]͓&]eu_~B,Nv@@p>pbzEtE@@V@Z N@@W@WWײgُqL3 jllCzB@cw?񩹻TsswK_LD81sHTJݗ]R4F@cPS;Xׯ+w}wSxztZ%%.S/5S1Lo%満s r*'#+3sʚ_> M@c"eqڵkVi9sSz jSEdl:rlv;UGnPSCz~:MT*  `JKKUYY z9z/}|O7X+whߝ+x:Uș髮1y~F-S255%Ir.|@@>Rɇ^_2 Nsd3wV LtH8@@-OGG5IM7Ͻ?~C[7 8>  Q9MlOjzui@@y<j|X꽘֯vKTr#  @!wG4" #LNw19z%˧ً:Y@@@`19Sj3TnuukS=RX?8=ƺoFE/ϖ   xCjp?'9ܯyRWNeOL_V.$j"  K'}P_S&)nkxU-@@. ㅚB؏  E =C{)P @@ݻҜDŽYQ 3վV|Kgg瞞L=c1SLGz/}|O?ަP(#  3g>> from openpyxl import Workbook >>> wb = Workbook() >>> ws = wb.active >>> for i in range(10): ... ws.append([i]) >>> >>> from openpyxl.chart import BarChart, Reference, Series >>> values = Reference(ws, min_col=1, min_row=1, max_col=1, max_row=10) >>> chart = BarChart() >>> chart.add_data(values) >>> ws.add_chart(chart, "E15") >>> wb.save("SampleChart.xlsx") By default the top-left corner of a chart is anchored to cell E15 and the size is 15 x 7.5 cm (approximately 5 columns by 14 rows). This can be changed by setting the `anchor`, `width` and `height` properties of the chart. The actual size will depend on operating system and device. Other anchors are possible; see :mod:`openpyxl.drawing.spreadsheet_drawing` for further information. Working with axes ----------------- .. toctree:: limits_and_scaling secondary Change the chart layout ----------------------- .. toctree:: chart_layout Styling charts -------------- .. toctree:: pattern Advanced charts --------------- Charts can be combined to create new charts: .. toctree:: gauge Using chartsheets ----------------- Charts can be added to special worksheets called chartsheets: .. toctree:: chartsheet ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/limits_and_scaling.rst0000644000000000000000000000354000000000000016700 0ustar00Axis Limits and Scale ===================== Minima and Maxima ----------------- Axis minimum and maximum values can be set manually to display specific regions on a chart. .. literalinclude:: limits_and_scaling_minmax.py .. image:: limits_and_scaling_minmax.png :alt: "Sample charts with examples of axis clipping" .. note:: In some cases such as the one shown, setting the axis limits is effectively equivalent to displaying a sub-range of the data. For large datasets, rendering of scatter plots (and possibly others) will be much faster when using subsets of the data rather than axis limits in both Excel and Open/Libre Office. Logarithmic Scaling ------------------- Both the x- and y-axes can be scaled logarithmically. The base of the logarithm can be set to any valid float. If the x-axis is scaled logarithmically, negative values in the domain will be discarded. .. literalinclude:: limits_and_scaling_log.py This produces five charts that look something like this: .. image:: limits_and_scaling_log.png :alt: "Sample charts with examples of axis log scaling" The first four charts show the same data unscaled, scaled logarithmically in each axis and in both axes, with the logarithm base set to 10. The final chart shows the same data with both axes scaled, but the base of the logarithm set to ``e``. Axis Orientation ---------------- Axes can be displayed "normally" or in reverse. Axis orientation is controlled by the scaling ``orientation`` property, which can have a value of either ``'minMax'`` for normal orientation or ``'maxMin'`` for reversed. .. literalinclude:: limits_and_scaling_orientation.py This produces four charts with the axes in each possible combination of orientations that look something like this: .. image:: limits_and_scaling_orientation.png :alt: "Sample charts with different axis orientations" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/limits_and_scaling_log.png0000644000000000000000000015775000000000000017532 0ustar00PNG  IHDRX0aCKsBITOtEXtSoftwareShutterc IDATxi`sf&I4FVBA ܂"l(,U@),lRSݠtM$63ob4L3ɓ9s28ILLG M b|G͛7_?ꫯۮ];SLq %KGB@!׭[,FK륗^Znݺu!(8ѣJ_8={vXX;}vO(}ooe2&Lݻ`p¡C>( o߾h͂ _|a `>>9E >2oX>rHƍGbŊdY+k(;,$$G}y+M&믿^PPpq3,Nz5]<==AtREjy9_|1({W4UmyG N!!AwEQӧaj}Ѯ]:իW:!X"))ɾcǎ}%&&:N}( ! O;}E9w^>}! >իWWM/_~JKK׬Y61X?8_~3g֢knAAAgr͛7-ZlOe77L:^ ~'yreX1b?O)h4siذ!z]nLW޽|V%gCGB|]'UV9LإKGp22207Yf}yV%'';{sp64ͪUN>=nܸ:8[dŲ׭[׬YW_}0`GRU7K!|ܹ[M={O?-u|޽vwݪcXlH7xirϞ=<ǒH(kȨhNrDW}۴i_=zt޽cƌQՎg[{HHHE/f͚^x!--6oZQwG<<<p>~~~ίP!Br+c 2wݪcdBd6vQTT ~oܹs !_~-/ЬS# ]]ѭ[nݺ5jhȑ|muLX~7'ON)]jkV&tO8q3ooo r%bUpfyUÇgggB._Λ7N[uwŎUnԨQ7ϕg׵kW^w8#ĉsss8kӦcw~fIKK/n0<==ˎ!ڵs,\Wv0mڴ{|r~jѢcy׮]eQw܉VO>q ]xe.XYWIwݪcʺXlXU y׸ne׿z`FΗ̚5kƍ1QgΜ;OP^駟=Sfڽ{3g?>c޲q\DYz|`8cof^^!yhcϟ?Do߾s?edĈIropѢEz6l}}uV4Um^VVvG ٰ,ƍ+w-Prrرc;t U- U=|39njX+BVuL8p`ev2SlSJMnݺϱ[=Sq]tܹ3qӉ>cUrCUO<aȑAλ-79] U 8N-NYYYӦMr7Tgܸq=T*zĎdr<߿BBBeHV;.p3ͪdy~ƍf9!dڴiZN:tw„ $fݺu(VZ :9E@m_p:{ldK1ݻ;nU۱T;J̆U ͛~a{>}z۶mp y;Cc+@9?fҋ-r;zh}͵ߓ400{oŋ7l2C ҙ3gF혧端+͜9s֯_o_^b%4tٱc}ԻnUر]BlXU ^>|OMM-**l&$$iӦ111=@e !w8 8nX˖-ϟ?oo='OBƍF3fL֭CCCFɓ'oQ7ߔ*бw`N8QnZoBt(<Ǐ?pŋ8i޼#<2hРL P@ 9m4;&KB(P@!B !B(PgDjW!C%&&#S&O}mٷoݻz뭐rO1쥔q %ڭiذ>;";y}xm̙3mڴ;vl*hν _R|1 /Te!gӿ? ,xW}||cܹۻcǎc?_t]4iRj˖-cǎEu'tս?f^^ުUbbbeoСC'Nܽ{wE\~9sfxx?dJNN?~< 𠲕:?9!j-m6|l&tڵ:nذacǮ]0͔R|T*U*k9#d.(:uصk޽{ׯO"33399f+LԊ+js='IZV۷Yb0f͚7S{ձPK 2dȐ!7_t}5tppFP@!B !B(P@!BZK.^^^ @?jԨiӦ!+ ݛyf][!肻%I VQS]zbI9bWxFh#5ԀlZ,ݱ[:{,c2l2l16mt^隻z }||xA)7 Ǖ;5ӧ͛dėڄЬYxLJ%L|U6Gej62h4B47/h%I2LFr*(>>s}EDQ\rZ%%%n\Mu;AuiZHf͚~XպLJJh4Z;T* !ͻ^5, Ĕ'"2BD"e$ `,z(͔rbU<=U|m=zpv{)BH۶mc;v }q,߸qcO>$𠲕B Ay> ǽ?Vq4+߸f_\IL#0YfD)^*bdZmQROֻ߹|!6QYc4R4g ouvaOƆk<[d?JB~IbdBn(jCR J^VhTBy<iq%[a[ՙnJMZhY-Val6+CUfz毎 6v1))e=ڄhJNo9]r!WgJV3X/rEd\/2ωW=ufq$Il6b6 !~k`z)ar"p%$2D&U KPpR ?Cۗ5J)pK@gB-^؟Qqbkƙxr-TUwo׋gӲKdFe-va՞+Ckڳm(@MbŊCڗj5!$??? ;7EQ*3F !,3&Il#2eB*RF(!prp'pPB)_^$Ub *Vxy`/4SI'_R)M;) B*YE/m>dR(i׽uHUVUE7sͩ!IhlLYȧ5Y 2dȐo_ShJ< Y`5D( &*EzM(LbiU8Jyp2dbcLfLfdFlJ6BMJTqG88Bd,$N ZШBH/DF!jTQ}~F)px9-iG/B&۔5g|m, ;'`*+ ,Zl,6jIFTf V(L6E4lh0ٌ0T?}ĘUm6Y<8_/VRQEhyR@!VM]ep6N|k:S \϶j_\՛U{J0jCdeyE&-`5EeN:ff$D9O)&/sm"s~‰bH&_B(%Q!$9 _fl82cQ$[l$3(M/8A%&n ЄqKG/sjFk3ح*,cgZ<. .sNVQ7X敘d)^"cru&*/3&2oOEgd6_bNB"fl7ڷS?s7q:!dֆO^!kC4+;XEY(6]a.(*0f,91(cͅkjvSYơ޾^SB:7eRƘjȇj0wn8LpKa,)`KR}~Fx)HoI5f3 f%O I,J#sLBa&S(D1u( I7Z[\woGV@o}iʞo!j"BUsuK9 K,y!T8IfeVQˏL QXy+ IDAT+@!P<~ٱK9j\\rH4a„W^ G9r׮]]v3gܹ+|~xz0:f4%CդFwPw"%+x5א]Pf?qdJiL#ecLsV_cj=1~BupluQ8|F-/ 2e>8p_~?(ͰaJJJΟ?_N'ڵk1<#:x a=K.8Z-kB+?u9sԩSgԩ{5kVm>#Ѹ|r//K{ݺuJ4Lh{OӪmL )x!WgS_lV*xRQM YŠ:1u0wCwꯋdXG5wD%$$|駑3fDFFEEE9o6z谰0BgϞW^=n8L%0V0x!3JRRf.HLLt߿I^yBHf"##CBBuGׯ!~֭MwWKh1Oi:l6F⫎ Ն{FxޯluO nc g/r{#׮]k߾aF|||N>] /z{;!!!..."">/HVejSw.1uS3e3 m1u\XjN.Q/p!u`MW!5;wt`68R%J^_ɚ$H8uoDߦܸqrNg_P(vC=uV/r׮]X,\燲,?vF[.Yf,=ڽ+jI~úǴX,|KnZ죏>JJJw߲e oݔ(ٳ91jC;EH35iV"D{^4ԛPj{rBHVwcǢ}||cz{{W=V4aa,m. *nݺžKz_~c]_~~>$[n/}5SRRlmǎd˱l%Ciy$iѻnj%}GT\\|9؊׭[ĉ1118:o#osrr;@9rĉgt+m)33ӵ!ATS Tf&ɢD!zlkŲKJo4EFD{d+(,̍9"9IwpÇO>W^ǏWAk׮tÆ  [`7|b ^ߦMыH)225qn>^kw{}KKuF9JVIo2Bg\^(6 |c7 "P{j6(yG ?☘ܳgիWo߾===}ذaĥz(v»q^J7S3%M,N,c2+3˄S],eCٵeP:M0I7p ?qyuURIk:1e-4W?]Bd36 Bd~[BU/甞I/>r =b%Yb:e'BU7ǝ3scٔ_l"1Rps%D$/9Z6Ed9Y4ibVQ>U|R%ϛE0]XvPLVY:QQuJ@!Pf<cZ;}%Laҏ'_*d:a剩bP @EEQtC~o>ڸHoI.IJ-HN/*1(!&$, !ug8Bؼ +kknJ~<RAq̓!: eA&f,ͲVePT;~6CG9J([2K`䎼T3/t~w|+mc [fY$Vf˜fYz({D4 b@!pޞ8QȢwPݝ{Dr鏫|>EYg]+MJ7rm,3ѲP(GePܭ䕚yʩܼBt/7Rpt+#6M5DX.(._t#?gY,>qŒ芘TchSמQptWVG ,P%ͲKK/Ii3:Jk]7_&eP܃V,1^2 bRZ}Z3s^h@ U?~], ([̒, KPiQ'ƀ(]p$I±Ko=(JV?k!&աm1>?jFFFNNy9 ˄֪؞0aw}WVV֫W7ۻw|qRٷoߕ+WS[6>Ä9Τ>\~lڠhRTT ]aǪLNNFZ4BRZAr.#ORfdz!ҵMGx*mֳmhCڤ!rUDcZT_D2e>C)}oOWdTXE{-B.r,Jߓ|## 3bI <4vq̓p#p%G?raY6~TA׮]k3N59}66mmڴh4۷߹sK.rS**1{{+f]rRsh%FY׈ Bڿ.j%%%([liڴ9szꩴz9ovGw]qsˤYt~?v:td-H9u\g;4jSϣE."BrBd2={fKKKS(1 AXn1^؞!Bm4Ϟ^ !]G979J)7ͩjz={,W9?eF~M5^Ȳ^޷… nnH-nb+MqľAPJ ҲeKBȘ1cO}C:X,gΜq<,++#Ԇ4Py1)4 TĈMfD&G5ckk +d] zsΝ;v,hZOQBOv;fm>___{KOO7Æ +7?oժ;ڵMLIIٲeKMoO7Y5;tZnOo[\\O?!V߿nݺ'Nwۨꨨ(k9ܩ J9dff/!T(*y2Pj>E,"ZЫ gPLlp<0S&|#>WAÇO>=33h4?>>>^]vm~%K\pAٳgl0B;SRRңG-[nݺ5""6/a񨸷.6XJˬN\A7MBwQl&VQ>x>דqɬԼzU?W}c? Bs#iXx1cƌ3ʭ_tcR'|'yy F>4zёb$o{]0Q)J.jJEԽuH!31M7۔sIgL;  }[<**Y ~c-ho0Spu|{^e(d,ܒzۈB.RǝO8A)OUOe򑶡B(XK(1[Q A lP+5XCjH?R8M%vJ_Ͽ2-qڳ. V(;CYn^ k׮%<3~~~)Td9'TqZŷALjD-C1Ey!Yy%cyV1F~6-1ׇlb|j/ƏۼCJG(RCgpٱ=gn V(FR :o4 Xn,J#dҫmZ!&5ڴA4(e"عtb. *SuokmW6g-J()%s~=%.ެ(2|p !ݺukܸ1 弿Ȟ39Jt @LW0LXy|\TVez{qR$nJzkޡqKq}͛7?{l\\=N9$hVQ9Ѝ@9#ڑsh1:꿇sߔR",5jX,UۇWڱjVwd.-W=gW7:U'DIN.OؒHtӝ"}ՈUVB||ƍ:2i$*AFFFN~f fqļC%e6_^C ,na~.~וR'#,5RTTw lu233\~ ru)ye6(YˤndAJּlu?/^x֭͛7OHHp ּ%u<1qWOuQiێ]ә'aWl.WݯK~]*^efŗnhDlxDAxݼy$IgϞڵ+vK> L&,2DU$Iƍ h4>lnnnE[2zA)=uq9f \4vQ\ͽg+t<2!G"x(&Ɇ2ƤQF-LsU(7/97fQfA{;eʔ>|8''R/W8U(*wTJRvtHf]@9Jץ,H!կt>+߈@Za֜8Nf}Rᄄ?022{ƌ{IKKy+W̜9s֬Y8ķ^~W/%$:n T$2TK0^M='ik.L137fB!nݗqTٰǛwڵk۷?lԨӧmBZcVt6|V{a0PV}$Fdn nT^Dfs-0~M4 dYٶ?^y|;N\ "CNZABBBdKTE eZw㱽+x.eeey慅޽NKHH9rԩSz=!dŊ⵼z5ʗ|9Ư8\y9/џtn41mx{{B pzJWN2ȑ#y:֒vOH dƨE9Ees~=7sA|Q"\ ߿ >>>5nϭW^ǏWAk׮tÆ {wn8???&&f՝:uѯ{Dz;.rYb4f P.^('cód='LRͩ ~K"OLjfu ܱ> !$[UCoGĘ={^ھ~Æ D!AAAuꠓg=#pdkWrSǍZ}[lOrΖ26Q K<{|#q̓pw]^/XT: 3f̘1K޼qHH} ܑASL$ϱ Ja6K)pbovS9VQIr2wyR BeYEyܲck]I2ySDͭiw;}5*B* wxl "P3wvLfud",LG}daj3BP)5[%a_@e\\BȼͩSx"C7OP&2+[odNQ "B`lJZG)KXng^;=ߺU߄-i2#;`]D?v`SRvJNf1v|5kU!V(~?>y*19y/AX>>O.޽{;t耆t?iU_9Li&v]x${ҫm1])зs/"ujɌCi/&lI2fZ VZh4믂P"Ϥ{M#OAR h pE {~~>!dϞ=5<6ܹs֭'O.&EQ,**r<$I$*;+Ҥi#REIajA-))!dddEQk須(--%hZ־.\{#GիW;fXm.e=DJ¹"MQJLr4k,%'7К#똽 #[n!hvM_СWu}+q9qOcm'Nl֬لf͚jʾfmMnŊ[n<:3$ iKOR *G \X[SAwaeTUPPQrH,-m陶ikf>?b,7Niyf>_|qM7{IrÒCam DfͥO[V'rGc'"Jjkk7l؀FlV<׼yf͚aÆs_uJKK7l p%rQϞ wR=N9r$00sM6C ! _}%Klڴm[)>>5}\jD:&9Sr˱)wHioRPP-ݚUUUs.(444:::;;[njwQUU|~qBEu1.4$]AyV7l>0-7ߨ*#[!Tb]|C!"AcKM0a  :ujzzzUL&?ND=ܪU֭[ccz:lVmS8/M]3,PXD9]\ ( =[tɚS ('?Yu]!uɑI1A>p. !r*q" {8=ax:ڪoڴiUUUݺulwO?=㵵o&6 nzD;D@xY~ڄ(zuX2惥k[CV?]K]RCCt1Qd;ljCe"AH!>8cph̙3gΜzꄿ?>1NJppaSVuʚmkJK 7>&܈( knwZCU{Oo?\nsʲRU:+ N[Bh-RCk_$~"{7Mv[Y'EQ8LXN8M|^BT1)e?>^Ao:XSpWϘvKOA%+,+haV#؝2W#LQTh[ۅ>+NC!_~Wrs"Nհaj_~Ą_E+šmTWxxxz|Α84 97&PJ=Tu֡e9;~||Q#9.89.cS0~x}Ys!)17&/"ؠ[j$+5?}6 P.$@[RےZ8$P~նGMf©.qNm?.)+cvHmi'ΉYYzSPfٰI 'b$ B3fpj;oiTo;3"qg{tky[R  rq8v3syFVLUO{|M%&km9eNE&%s{”SP OLjαW۵1=ydqq1V,~0&0N{f./v݋|LDޱuvL,+jl_gD$: t#q7F>QOTPf9Up#F6Lc Ѯeȏ%aXz; ؔWk%vht^#RچD B' ˫ڸ"!qWKv.gs8vAIw Y߃+6o_uN'jԃf:攺%vM>9\Ew|w)ч 2;i22vewkGP`AՁO +,tZS$;X`:\lBfzkBhؠ7(n0GM;>^))qC""ZF`=۷ҽmU\{_BDIYʎW5)svؗg"@ÍN%9Ơh`zeCRT垪s2H`DMlN׽ſ,ec"RCkPM]Sz1LÃ!/wCHSaeYzvBk駱MfSջV;i*i5NIq:"ڟW[X(LjI xlЍtN1!uKMEr\0N~z?CUOVe;]YP.0ek(bȹX=X l/(d<_WjNqr{2K(|AaI]{y[R pnd/H5+lct"2SH>$@BDI)(3WڋN4`DD}O )Ueyʔ)F{-))AL`==[ t7Na~|\Ќ3ꫭ[3Ɔ  ߀B.\+!!!00pΜ9 @!*** SRRԇAAA{Ad6}jZ᪃S^^.b~~mDe˖'Nh4 6EQN(,ߐ:*((N>K}ιND:j? \]&s~-ŕ9鴈nq[dj@3I<[yh!$,rX,x>NQZFUtިM-\lZ]xT,չh4ƻuZsɲC/Z3f).9k.t͹ufZ[ (֚=R^^޲enGgdd\Ϗ{w^᪃nݺm۶qoh"uZ=.s>}zż W^ܴiӦM|9dzw}AEx /VMdilk.h„ gϷX,SNMOOo׮.|n pAӦM֭f߿+@wBi49s̙3sBW)44k׮Mze0|~1۶m JMMz3Bk ^z!"Md,4) gԓ8 8N>}/8`ApAš90j49( !BeiiiA'L̝;׫#~Ŕeyʔ)F{-))\,/XW)c0H7륭9){P!:iҤYf^ݴZ3f|W[n-..f 6~CL#kƌ6mvl"ffz&e5h "Zv/i4s…/RBB͙3'!!!77]v>NR#k…Çvl"ffz&eFhʕ-[LJJ2eb(,,LIIQٳǗчQm>vt6Ʀa6͖$e#B2lذѣGGDD>999k֬񱦭!3꓾Qm)פ6&a6ٖ$Y-[lȑd М}U'bcc,X^QQmvHDgf7:w/Im)wݎ>aeI ;5nĈTAt:"e[23444:::;;[}WUUkŗ;ro4nWݲ>aeI# sɲlٜN'l6ͦ>t҂Œ=iҤ>}h{[B9a„ٳg[,Sҥ>ֈ0aڱlMV뜔=Zt`dY6 -[֥K;wꫯysڴiC֭[DDXb/>ֈ6mmڱlMV뜔v8 8N>}/8`ApAš9+45(c4B%ԃS9 8VXs< N&@!B !B(aÆ###c˖-_cȐ! lٲ-(qqΧLBDӦMk/{c$򫯾ڴi /8N߮/BѺu8Pw޺s_zg^~嚚zjO))>SlݺO޻-\-Zlٲ>>|u !&aС>l~{o6..nҥ \KZ9rJvv6uܗ߾xb { hРT;4oޜf/6mcǎZ/11s[/~@@!дԨS}WFLJN(77ܗZnMDjE"p"l5H{t-HgO~۶m1zp!"ҥ P4!cǎ=vX>}VZEDcƌCXZ}w2d"8&%%Q~Ə]wLZZZjjZ&3f~wF7opԨQF*..nѢ?ND?$9R=DD6lp}%oλeZz;dɒwyg۷?VE|Ҋ$Iuֲ,CBBѣG_رccǎ]tix4 8NzW94O>&NxEv=oH?0Y wq^iȑ}Q޹|{UUUxb";vlhhU3gΘ1C=Vt._N_~EgB}G}qqB !B(P@!B !B(·edd д !9.333==q@p4}_~q 8l5s8hrP !B(P@!B !B(P@!B"(@*8爂tTUUFC3}_~+ 6+xl֜>USspj4ڶm[vVJJ,ٽ{Vus]=[jyܹ,/Yd-[:.<<[n?ٳwڅ5'ئMSΟ?b\|駯uD$IB "P âEnv0cvv;ϺfP$I}kƲM8Oڵ>ѣ֭[4۷ׯOLLBS;vx7#eee Fo#BА;~x×^zɓwءN3-Zd0|cGU kF4FqɓƍCp#իP͞=;::ZX,O=:}ԩ_|R IDAT5۸q߫^شin'L8M6X1ϛo)I$Ieee>̒)\ ,p=VXADfdttٳeY^rg4GynjӲeKV;y䪪_|u?ݿkӫW:cȑމ',Yr޿_}vj-Z?nwͳ`Gy$55522RkڐݻO2EQ|M6h4o±,aaaNϿ4qw2\ũ=+;̜9_`ƍn޼`ҥx {u)ؔP).?@=8Çwc/v_|%"z/>sQQQϞ=/?#6};wqILL3fK~ɯ5-t:/gL&Ӑ!C.m]sFDD\h6zjtd4?BZ uyWApuq!.W&.Eь3uϟ/w1 Hy.?5RCjj}KF1o޼u֕ӧǎziذaCmOt8C q&((tF Z|V]tbhfѣG=zE޾}{bb!CRSSSRR:vxnRTw :tͮgcaaauuu(666..h4ٳVȑ#O8vo(Iҝw޹m6a@@jZdYv:'NlѢ}݇UZIIǷoDpppDDDUUxEPP^W}t]]ݤIν+̙3'N^ ]<]KCBY|yOZ(--~zYst:z-/}vu绞VRvĉ_1C=t+00__?rι(٣G.))qͼtRDsϿ>|+++7oެj۴is;pD}x 7n4qqUV{oFӧO]ֽRZh3Ng\\ܕfZ7<Eq߷o_CdG]fp 0jԨg;_m׿^ڴi !93Є jjj:M\E!3TsR622"r|077"8ETVVbo4{lfdž \f̘quiJ_\ n` ̔ )l By^0((ȕ \꥽ttػw޽{ǻ>-..ҥ˅ʕ‰hӧOoժcl#FL4܁TzŠ^Mg{u+MW;l'z<'5HCBuyƍu\nl7\TTN/T%IZ~}tnnʕ+۳7k5~`׮]7lؠNǃЛ0k֬pu%%''gffӷv.uuu{q4qn=vnH۹skNyO>dhhhæwHypEpjx=EQgfϝ;WU$Io{/ד/E8qb^^}1K/C;wo߾;w={&pM95bŊg}LͲ{=ztii׮@7o^7tuʔ)N޻ws=u ,Wv=:CJӄі-[| }WמZl)AR\^8<:V^{""9.Lm666UQc]:;vdر'$ݻ !!!/?K S/9pp8nJNN4hPZZk^ttt9}4q,A_iP͙3ޟDDDDDDDz ))]#>|a<BФ }/8`ApAš9pj49( !B(P@!B\W˗/OKKEB$N4i֬Y4pc~j?ӈxAڵk @!BTZkjmNM$SCZdIvX]H/jtFoDL7hD5!zNiBI:vؗ_~(/#c5uVVsO TVVE^UH):+jdS;3N 1bD9#b'bq:'J ĉSߒqgN~,BP X5$yBdz̙3]\ݚs4o|ĉhŋRqI " SH`\  H!" ?i|fN&#E[@DjW&^`FYFV>(dp»e˖>-X7o9\cǺw)my61 qNd!D$H NDB{oqƈwvOH@ggB\`LQ1sʲsڝ@$\月 3j\ZuhH' Z@DDV "Q#Ωjx=]5g'"7hw1F7{l=WX``,FQmXƘVRPfyEՅ?99$EDĜF#赂F`e#FbAk?F։O }kNN={fII[lRYgjN]IUvSC'jdE:Ev)xVdNYы6;wovCYfq}cA8 gpE$iݜuNt'Ju ~9L)iی )3vQ:RݳÉ38'~?.Ř.TY'vD™"0cL8Gp.L gDg$0u?5FØ{) Zb5Jtc!zFЩg>(s: tD^^|555[WPfٸ$s1SgNV\{S+@!z Ȝf{A%TMayݾjN!mYéϫ<\XSv]R'ulѽm+OCjc CFF~urXwlݺu_[|)6K"RK);ϼ[38eET.ɮ9‰lvItZ qNz/ƈ \\`Ljt$ĹDqNDZB)0WI2d2DDe6F:o*#cԚPRDhmQ6$@A3EAtACVU!૮EDe7?mJNIΉD5h%Di*Yr\r`O+Kq!"NԞ*/(5+ gDuvsڒSX$+]B%G"hƍ7nܸy+יc^%/"ZӽR1"Xϔg^k?<;M:sZĉ$IdBFzF-F ?s6z矊1N.+BX5'1+#b4iDH. DV⯫7NsV~bOԊځ& ?z c x5YuYԳ2ñb%)sȒ(2WO,$@?8UVQ**II.*1Y6uDn-Sۆ5l3q]/ Gvm`twkbbNY-LZ䐔:zi8NlsV9'V );e998WO㌈vjwUJx5 0R* 2:$Vk5!z( Z5Oou~Z(4FNd+B׏CRl+:,)+1 ;[α޸L' mRۆϭ]pSNY>Us,GƇ{[뤘 PV]aZjT{vp:Z>UNY16*9%h d89\Ტ1FDvbw*5uNƈH=<4 $M0s`}d!2֬E_.&̈J!P\PAm?g1NW#V9n };GrSo\Q:}!)Nj?gm-:dIv:T-<~ };Eb5TMNI:km:$J*(l>X|]ꃋ~<<<=_({)@' F?1RÓ&9$dvXꬶ8/m4;LvVp%YQJiUV`ZQ;e1E CL1$@(}-֩(H!@Z&usLqxzim\ӑUVIVj,~<#R'4YIz P^Pf)%U֢:]ӋHeιBDJQtU(0V#+,+fš[B1ƈ`F B !)?,,xMRo kn=?!SdjuнmXaNJ?}+pv[; ok~؄?p<㺯b**il/(+dҊ^g\N֊ӊAClF4h*Y>&Z#!pPI_˗* &07seeyʔ)F{-))6zw/-JLO~96b%?؜H԰ :,-oTj~ԩ7 ^uS=viQdo:X܇;]}ˡҋkxꩧbB gy]"M6 рccmozN>cտ-{ƨNq{[uo̠hEOiYQl6* 39P{n񎻦2|-9s徕*sdE} *ҰiGFhhI˟~zw0aoNkZZg̘W_mݺ5<<|ԨQÆ ۰aw5Ӄ>'\-2*g/ֳ}{$W\& 7>wGuNXSVZ/o6"o6ͤ.iҤI4xpfQPn)VJŕ*VԈ"Sd(]>3]McIr();$%120upcVq?|L(ƠAhڵ群h|`Y.\K/%$$ќ9srss۵kEvX%نc6|憸rxz\j??I&w}:Q?1w*(ʊRmq鞎Auyc6Vw[l&M\:]Ib8 L2KVVeӊV$;dEs+`)^tʲVuP[b<d6m4k֬Lhrʯywy+b4z”a|||PPО={駟Zlyn[3@yqb5#nOQkhOk(5_S[+6/ȁ|q 񿶫OuP%''gƌ^i.hR.4>CRLfivd4;9%E6R.uR+2YFxs렎A1aUVVVUU5lE!Ԑ 6z興g}6''g͚5޸ 555D~IoѧOGy$--ͽ-JLy{H`wuo5D !*QU@špiWQqnحeM7O8ᥛ;훉Kjj9s|P `ù'NUϫ/(1sN! 8\.j鏓*&-=Usfo))ٝlW8'M5: s*^ۡMM"pq԰iw5dYv:NvP_tiCBBrss'MԧO-ZxѲ&L0{N:5==ݻ|X~e}KyŬ6ZvEp5?4Nڼ6@~e8{gׂŋ{Ŧqf:m&ZCzWm6FogB\7;RO;|h9,+ٜ,sӾ`r^SksFƇFbp]cg޽{7lE!t5.]:~xuZ=,,,lٲe=\UUUxxw9k,Z/e6mZUUUnl6[WX]m ?XbuƠnmn-8 ~Oj|뭷\ҋn9:e_/W9 ߟjmx=wiM`0{yfrEqǎ]t bSӁB|CR`ADucknNޞ%>2WIC|mE+ycۏwoK_^\TPf)w&Ɋ$+5Y(j]RCqVBTſ[N g~w0@ϖwylUr8 zoϘoBpĄc-1Y3d-fKD/jX K )(g'>8.05=֭c G|4ܯl:Paւ-K_#(lxwZee,;X`!Y9~ǩ_w;d[Bhm0 !Kؤɋv8\p\p5t0N=J~}T*̎qly/CpW+{zgkMq|'*H;0%wGdTDԊ(s_GVI+ee}q\q4-|qޗG|m ]H#O; 7V&M"pUd2%KR^c:+;[p4s9~W#ƹ#ŋÒ;i`JdWF-hzpo_RXn(/_S= §ӌ "z6Ȩyꃏ/,6 QB!QomJDLE#,MN^zb%5ӌ|{,~&w&X(fs漇8eDr!Pn+b )4A'ƅ栆ѶzgB Զam ,:xp|(!2p p!=h7?!WØL1Q=y(  #olO\x!IVu/6 ˇ333z(&6 kOLY8# v{p s.KrIQ#,8~a]kp8v$)"cvoC+‰CQc$&![X]+޽{ kf[gFh4{l*b>Aض܊3V pMR CFζmۆdC%&{OouHN:U=vv^t3V7⟏vh[ s>dZ pˇ)ȨI g?bΦ&Bp6g\y殤'GL\'&}{ց\݇; A☲W.1YQ\Ws94Q).:|B@Sy|ޖj\pr{۰͛УC NDD*Ŧ(9_XH'ovT$)Ort-pI1ƙSc]:IQGFfVN !㋞NkfDL96ȩ(3l;gBL.GؐϤ=/^1Uz}ޗj"gʡ`G;rJMJ o5գRnKjTi'٨.N-y&K|经U_9$@Cp&o88{cBW $@ȮoM +DMyٷϔC!N&4 U4 m@8+C-pڷjGoOiFTgsbswr(;"S ~ZɽPAe =*˧z~垪7/kG|L9Bp[yM ''"&I/NR8{,y|to2BBUDQ\U9eUDAk+"- .x*.*(-GŖKJi=ΖC zI4L'5qƸuBϷ}hƆ B@8W7٥aAOBMpЃ=R(]~8AMȠn*p8<3>ܴS +Fj~C"' N~[ԅ>yj@EY4u@&=CE(JƼʲ]5AWӭ~csͩKY?:qR=!BM84ep7un/PظCl!J_PRoR?pݩ 4yjЍRIYҍ &&2_7X&K}5Dt돾u7=fjk"u߆U0oYtojd-k #\A8c[Ee.]h ksV7>/rcjp9,{ox.u,B*N[Wn!T l9UPlP ])N-O*oNk4ni@RHpg^䴔r*TA|GsmP͌_vע&uo<2!NᨲmPeY4u[kq?zA' @?nj*/L\P),NzH!4UIޝ=Me!9)BՅӭo!5AB7k(\PYv6TEb縷$gVnrW#YFQ!C###EYxU>yY)KNХ~GFCMP;oVŤ(ߤwImFk+&2gbt㑳>;*M!)ɓSNm~ݻw TEQE^h޼b~\.g .ӭ{-u!{i㨉qM<9<<< `gdɒ@Mcx*!"IdÑSPکfV\\+M}}l?%H!L+7;jEZv={ڶm۶mffffiii^'&& <쥗^7n(>>>66655u۶mi웩e.!HA ӦM϶nݚzM8q锫hٸnC7yt{_yo65jvk pϘ7B"ϭAhذa >x(_^^^5 !D>}ιSN=aÆfq&L(((0۷{V5..>2Nۺu")))=='(9s!͛x_=zXw]%{_Ruf<ґx͙3giѢEpp̙3_n}>єJE't V\T1A~fA).>auڱj? !/_^TT$XlbaaaLOOBi8^z͟??00p̘1Ξ=_~}n޼9**{&MJKKsBΝ; !v*R w7ogK"B-&v ^O>~ߘ *S]n[ ]Qxr6MMjZ+N@?mwrRQwtk?sΝ:uھ}~裏Mȑ#yB믿޳gbݺuя}m߹:׌|]=OMmtiF 2fV{3MJb >SBLBX hԴmsV~_2lذw7>gu !^d4ƍVZy.0ofBCCm604W|=g;w94iҳgp^/;v7l믿j1//ٳ>m6ps;w>x d[lXlY+s ŋ* )ukǩ|kΙ3|`RTTjժZq%%Y\\|iwuiܹ{nԨ/To~yЬ%onQW 4xI&رobذa|u;v8/iӦƥѣM65o3rEaan/111GsΚ۷7nxc^Q.]+۷OqM7Un-Kk|M~勝&Ur]׷7{N:Wy .,,֭9x|Wn5SU588ˬ]FԹX'l/gr0VՋJOOo߾qu*((VϞSc\Mw  z~&UYda|_Z]z:f!ė_~)@ѿ!Drrً㎸8!DϞ=njs=C||n4<={>|Q|/1běoi<1bĈ#4h0vX!رcBCz?~z.B=!_}3f=zf= -[B,[lܹ:nvNݪ\Y;LfRWm59#TkV\TM77mX{]J"6~~ΫSG5LB=zv=4mtÆ .jbFi.\q֬Yj]fM||ɓ'm6c WȻvZhN!-Zh"m7x#111 `ɒ%fyʔ)3Vȸ{řW!-J+vE6 WԩSGDD8O>Ę_/]Ԙ^pA<h /"ҽ7=RUū_5FMjYG:J!T!M}?yyyu&X`ǏЖ +WB{ɻj_jՅWKNNf322V^-k7nܸEO\{OҷLKFDzzꌌiii5Xy겷;pg{iiӦՌ'%??wީV 2U6}#GH<'JǷ$kVZJJʥ%͛7ٳ'---,,,**iڴ'|b2*}Cnݺ?;ܽ{%G{wAAAOc*u贈)"j8k)CN6 8Nqmv;FkU\Dek.ϾcOWҌv_3fY&..nΜ9ݻw9r|jllaÞ|ɫ0FgJJJjyرyRk{iYIU=aB-yVْ]`?q奙SyhXV%ULkuy-.S5  !lЙJnW>]"hV煇QrL;NJ*3;p6 Q<+B(ovggV_әB TJEbNNMBYqcI!N}kX?Ee IDAT0)G_1O&aTZ6vKYds=(pX41ohR-uK8'`V AW)>ީ ţ{n<2^ѡnPŏ 5+hC]{dҲNNEJ]AݛAAr,:ktGPMr ]˟訨5)**ݻɓ'9:kР9D +9[*DJOOo߾qj{r1\@DDV\sj0Zv!}3f=zf= 猗-[6w #x#֭[IIIO-8碯zϞ=BuEGG?#;vܺukjjj~~qoꫯ佛)7&Õ!*2>BJٷoߎ;RUhY֭+(..>{uZ7z.0oܲlޟBPc AE~~~+Wϩ *,[B߿EM6Bȸ;$hҤITTnn̼]ܹioiiiBEQtbo>!M7P[<#4hвe˄F:|0e\fr-\e߿"99EwqG\\gϞcƌ{01gϞÇ5j/~#Fx7#F1bDVVV Ǝ+;v1S1tP㎓b]B@o/_<**j޼ywu1&N'\NSO]e{6maÆcbFi.\q֬Yj]fM||ɓ'm6c W>vZhj-ZhQaa7HLL Xdl2eʼy233322n^z JPΙP;}7/Ҁl6wg}VU+V_n֭6m1PAHJI|$$$PCq*QRRRbb"u̡8T9rD4?iɻw޽{AAnj3wKcǎI)wV[] kݺ+[UUcccLO^>4i҄'!TiÆ 6lu@5` B@ ! AB@ !B(T@ BRJ+%%%!!:PSgš8ZqTtP ! AB@ ! AB@P)T@ BRJ+%%%!!:PSgš8ZqTtP ! AB@ ! AB@P)T@ BRJ+%%%!!:PSg 44Ԙ())89Zq\tҸqc7zUU۽`~5jjZ,?3fعsg{F[ol6[F 6۷ozzܝ;w~G]tٺukM=ңG=z5kֺubcc9+6 #F(jE#&d2ǘ6L=ƍw޽u>`5g͚vnwNN͉!Ux.]:p&M766vСѣFjԨln֬٤I )Sݽ{ww~7veСg>tЂ ~aZll64hp뭷ûλCu122j氰N:M<_~躾bŊ?::߿o߾_ ~,{+%nn?ߥK0M7n|-L0/\CVJe_P]TTk]x'Nt|zn{X󊍍5j3<;b ;wv\sh?feey׌8j6|\NNNϞ=Ϲ^3o>mݻ_Jy1?QN|||Qem 2(Nmn8s` p8bvpɒ%fy…Cv}&:u88pBm۶m۶߿cǎ:thժsuwoڴ;GQ뗖oԵf͚5o< 4##BC:t~C}]wn'Oݻ\7h`РAVoއ111_iӎ?nL7nܸuֺ8qt\>-[TηT]/2!N š8ve͞=>êU~{Y޶m[oiZ-[zII}׿;BR1& 47l޼yE |-]W^cǎ>_;=dȐW_}^z}v-XAFyիW׿ϟ]￿-Y;=m4oxoq9R)|?7t j5&N8jժ,;sɕ{DNV*2P5Lt>}|~k׮-ڞ={ιi{7o^z@@%Kyŋ_>##÷b޼y]tyG?w/˗Ϸ222ӽ{>jw޽{9M3v\3̙q͛7׭[;HIIBΝ;4n#BpGBt!|ޙaaa{xڴi+l߾hÆ &M.裏ιҥK !\@^^^wƌƧNgϞiӦ]?]ZRRcǎٳg3We ;Bpԭ[rʽl}bLKG߽zѣG &3}G۬r}|ybȑIII7Veɒ%?%gĉF2lŊ :w|)WnA6mlذ^v~qj 7p co;i۽nݺ /]3>N:@tv֯_oL/Z_~۸oӧӾ}~W۶mfBnݺ$$$x)--K!(Kvڵkn<ܲeˠAyD\o;Ź@-D84{]}.F_!Cx|W\)x|B;V\\7j~׿]v}SO=;=tP'|OY"##cȑN2z.BxGy޴i;s{;ɓ}VSOuǓo{xoTt_ 0h;T*눮teb4@8I+k)++R:ߤ! Af1bw%%%͚5]i(Bo᳷o;(۽v{Qn0gM}}wMUvNq>tvom۶s޻XQQQ}F4MZVJ׿u /4PYf k׮VXq#۷oE|iժUE+9s>_zƸQp8z9s˗{?2$pRVZ3irX0L+W߿gyyyxM>ݻo޼y˖-SLիW222m۶yf|o\$p8w8ȑ#G}9/<|pJJʚ5kvt7dȐ꫊{˩ WOÆ 7m0 **ʸYw/.W:t?1"""BӴf͚M<955p1#x㍧NO{챮]FFFZVMBCC;v8iҤݻw7o^o:thlll@@d [^xo?)<}:Uo+Xz5Uw:P%8߇%2j6 !XM5NgQQ'š858Ϗ xY1g{I !uy޵Ir*U !L"rf BRoBExL<'[ ]Ҙ.2]+ @q\qE;/gNPPЄ 8KW ɻNn]hRHE(R!4aBB8PRx(JB+A)YPTU(BH"Eх*BBU]RJ!UQ."#=R !4i&EZ4UaTfBgX\c-j2rE~SuN٘wfQ9~\Ɓ*ѣ1u8%99*t]wiii_}b\`~v2nօ֥癛<I!U fIu (BQ)"]RF)"t]J#AI!0fKw,5&t#X wPZ\JE g2a1n,)B1vL;B(0)P5#*Lxv<Bn2f2v>謌d&Mg[Ǭ~fRV-_ 3ifp <|oRU@|PCq*WRRRTTԘ1c}Bԯ_|e˖)kLG2י8[uֱ;BL] 3ḁ !nwec;.BHL&!IULFRUQm()[R EHtR#I 7%$o*;d2nǸ]fwz9g233'TEUR]HZg6K٬aA?ɢFX Z45O 7wl6+R5Z Vԡ9j=zѣ+}ސ8%dSaRUzf ]UU)iEׯk 4  pg BT2㎍6Z N.nt*len]\;=%enˣ;lv).sY&UH$Pѥ GRR.ХR\*.u>UbRI5iK]N Ŀ^52?~@K~aA&ἑ!Vp2ƝN68nO~K\OA[/+T]U#u]v1n2ғejbR)J?sdD]Pְ@k +Akw1=%삲SSbDZ\[njBK.vHRgQEffRݺ芢Y 6drNz-tey% J'r%NE(fM=ҭKe|Kiɼ2c Ip^vAuZd_D?C5A.ʒ%KfϞQVV6e +ʢMRI+,t4Vhs=¬)up{<47+v2LUĶkwzi~T52?"?2ԟ^v5enw'O~KKK3gΜի7q܉'R \ÀdDkR~+v˱8N.+vdOn?jRU{<@83TÑS6ͤUդBJh0e؆p_;oٳg֭[G1dȐS. ַo_!ի)&Ig,w]#]j-{]cӈ74h/{o׫M䀛6 VBSBSrۯN=ǣqی]:B Ƣu)?qN?g>۵iXZ Ix?tǭ#6)-Wl9*XzukB@Mc] cKisw8\pϘ"qա$''SU͖-[LBPይG E1).UN:dɒ,U@|PCq*WRRRbbbEuj6 >|t..ed5kͺ5fXVklh*uNB<eMt]N?cl {ȟNM_A[hDT: \{Mz =0Ld~sM]}v~%P# }ޣR݇ ƾ%>.|t?06!Ph/o`QЅܸ԰Y?ӭS!Pci6G__bB)n<Bj9}`?!]}Fy7?3Z7 c1I!t)?K=:tƵ;OP!PcY4Ύq,*,\w0qhpfOIMPERg҇8 Bǡk5.C"?/V??d!P(2czR(R9cHM X@v}nc1R8ݞY+x&O0p̌ 4@-g?%,Aŏ3g} A@Uv={m۶m۶m۶UL6>ۺukVVM*_uԙ8qyTe/]أK"wex+lذa >x(_^^^5 !D>}ιO?}뭷Z&M,_ܻw-T9s<3-Z9sfrr˭DGG,,VY/v@_fqr% C=J԰@`1vQzq!L!T% $,R'X-KwdyV)=<, ꪜs~yx;ߍΊEscE̝;7~'NCSNK5>0rN&[o3g3^zq۷og0ɪҷD;N7Ed֬Y?}g̙c.w>:/eem]v|W_ (B9u]>Ν;Œ3r#vy8_Fٳ'0zny%%%D"x s&_YOT} xyW嬱/#7| ~Ņ&MB_b֭keee˖-ۿKKC+WL9uT*CT*J@2zX Ύeo󉫠ݬ,;;;pM7]qg3eʔ!Cl۶K+ߵkWCC5\3a„z .},^8~:=GQt=|q(o !?gҥx?}vvveeeSSɓ'x㍁_|-[' `[=K<_B칺ݍ_z!{w^vmaa᫯M2GR8zhE]%-X.d?5j<C{FV|۪͓@Ɗ'I)V&¹P,[lӦMW]uՊ+p.]-Bv* ijS0+?>e\7fӡ{V"dBظq2CS*.}urob=B]ɡŲ4!O{F a^L@VqxVV,3~>b!ћX쫖Un;􅏍Eb׿o|Ńq٥Z[O-Z/߅~Q(Dίȗ (Bx/g$~:$+oj d2#mfO꒼6@ɜN/+@P!E@P!i,X ':zhUUU"dx2jkke"t!=TNNNnnnfh}N8QE@P!E@P!E@P!E@P(VSS# -X@@OtѪD"! dd2)D8^]-Brz<(8Zuͥq@"(B"(B"(B"QF @[`ѣUUUDBdR pӽ***˻ZP999yPpޣ9=K^G!E >o޼K/_~ӦM;rHTUU?x\" O>k>|8}]S\\C=S2_eŊO<İaBÆ ۻwsĉC7n$ رc3fLСC: C8#ۉ'B#.Ě5kZ[[clWZ~EEm*۷o#FssA:u؆E B'OinnNviN'nޙ~q  ȆE񊋋KJJDFN 8wfۯ_^p\@KYYٲe2d2++W|N=J}!T*JD (B@[pɓ֮]߼yu:BXzu^^򚚚 \(.Kvvveeeee_|s !̚5k֬Yb23B"(B=[F @*BQItdRN7(//=G8p9åq@"(B"?M6b;tРAXl͚5/5iҤ۷ @&y.\إ-ZԱ,$ݻG5jԨ.-8~+b|!zX,VPPpСԩScشiΜo㎳'}owmֱ!&O#477/Y^ذa_z3gׇFڞ}D"q뭷8p`̙'OLڱc!K.?䓹s[iǎ !:̞={V !ٳ'=^Id>},Z(EĉڳN+,, !477wC駭:/Q(B9q?B۷ ^N1bDa޽*u<}jhP #曫Cw_cc&MB_b֭k@ [~}IIc=vwΙ3wuW[[۷fN2eȐ!۶m;kMĮ] &w}_@&xw,Y2uti[ly'o"ENW[[L& tr9s~p>x<^RRrkϢ(2d=Ƿpp{NvGO~EJKK˹GP!E@P!E@P!E@P!Eb555RzWH M&rpQEEEyy9phe.zEP.v  IENDB`././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/limits_and_scaling_log.py0000644000000000000000000000303200000000000017355 0ustar00from openpyxl import Workbook from openpyxl.chart import ( ScatterChart, Reference, Series, ) import math wb = Workbook() ws = wb.active ws.append(['X', 'Gaussian']) for i, x in enumerate(range(-10, 11)): ws.append([x, "=EXP(-(($A${row}/6)^2))".format(row = i + 2)]) chart1 = ScatterChart() chart1.title = "No Scaling" chart1.x_axis.title = 'x' chart1.y_axis.title = 'y' chart1.legend = None chart2 = ScatterChart() chart2.title = "X Log Scale" chart2.x_axis.title = 'x (log10)' chart2.y_axis.title = 'y' chart2.legend = None chart2.x_axis.scaling.logBase = 10 chart3 = ScatterChart() chart3.title = "Y Log Scale" chart3.x_axis.title = 'x' chart3.y_axis.title = 'y (log10)' chart3.legend = None chart3.y_axis.scaling.logBase = 10 chart4 = ScatterChart() chart4.title = "Both Log Scale" chart4.x_axis.title = 'x (log10)' chart4.y_axis.title = 'y (log10)' chart4.legend = None chart4.x_axis.scaling.logBase = 10 chart4.y_axis.scaling.logBase = 10 chart5 = ScatterChart() chart5.title = "Log Scale Base e" chart5.x_axis.title = 'x (ln)' chart5.y_axis.title = 'y (ln)' chart5.legend = None chart5.x_axis.scaling.logBase = math.e chart5.y_axis.scaling.logBase = math.e x = Reference(ws, min_col=1, min_row=2, max_row=22) y = Reference(ws, min_col=2, min_row=2, max_row=22) s = Series(y, xvalues=x) chart1.append(s) chart2.append(s) chart3.append(s) chart4.append(s) chart5.append(s) ws.add_chart(chart1, "C1") ws.add_chart(chart2, "I1") ws.add_chart(chart3, "C15") ws.add_chart(chart4, "I15") ws.add_chart(chart5, "F30") wb.save("log.xlsx") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/limits_and_scaling_minmax.png0000644000000000000000000005344700000000000020240 0ustar00PNG  IHDRm!sBITOtEXtSoftwareShutterc IDATxy|SU?MKZ()n BQ": #3O;( 8XMDDbZ I{dZHGrs{+'78&>|xԶoozK!49 49 ;tZiihBN %99;sHs;U^^n_t;4~W: \Ϻu=vXaa!\&֠jw.]7v7^"|cs =GG7:ul۶ͱ|…gΜi7vڟ2NJJeq/ocĈˏ9"|.]z{jžx={\8qbDD(AAA{ꩧ6oތ>HspyB۷oWo?cwn\k׮ׯw -ZDDO?}YfZ`ݺu{~w駺:^XXcǎQF͘1Ie˖_W۷o͵Z,WVV9sf˖-mh,ܼysllu]U_lӧ:W_Uy͚5cǎm\xĉʊ+h=ТE^^^Dtٳgm=~~ ㏣Z-[2dȋ/WUUu^Ѡf;}5 f=s 1ch__5}7W^ܹs?Ydɓ'%Iz}QttzQQQ &TUUmݺ̛7OrׂS6~f9p@VVz{ʔ)ZVKE֭[CBBq,)))˗/kZN5ʉҥKD4h uCBBf̘bŊ u4۷F͎ے$[rID=##063`QVٳgOkx ׌Ο?_TT&ufffLL ɲ>>=njjZȑ#+VRZQ3i#4hGuy w9$iذaꒀ,￯z]ƍS=7*ӯ_?|{‚ 9z&ndm555w3?j~ž1cFSN>>ٳg /_>u^כo=lذ%cbb<==|>zĉŋN0O_~9==G}t:]ׯ_k׮†N7tPo|AOO⺺:ιODDDBB¸qN8q#9z&`whln+(;@ iHs@ iHs@ iHs@ Ɠ9fhhf VHs@iHs@iHs@%Kc-0zh`4FcϞ=b4pFÇ߶m۬YnRfh1p'"ƠAHEQ9;?hOJJBk;q+VWWo߾jSqc:,FWoeA$Fs[u֭,O:CuM<9>>Vnw`=sι,ˢ(ޤ+~$ν^?~x__;|.)V`9r{lc)))qqqQ?|ȑmʲSOݼXQQ(fI_|WQPPpԩqƹGuN:ED p|}k]====/// =֢Nrh4^ϫ$Ij6cbbrssՎtСŋ7.vmm5K\ZMM(nSOOOwZ;z>...""},]h4~G7n4-R/\p˖-Vuaaa!!!&L3gδih6pL {ܹsΝt޽{Ojw9Fܵ@iHs@iHs@r*, ܶ%K|'/^9s5k L&SZZիW4]k|~=Ç;vヒiyl9! ""A~\/kkk˵uҜa|~[ŒYRR]BFmu\7?^|0W'8sM&pZܦ: m4c-L&6v{qqqMMw!Y*S{Z~ uQKĖ-& [e6:kTG:4رcbb{ 8=6,$$={$Iy/]z/wH 06psNZ!$k/"ќ4 \CelGÈH+ }7'[ a"( =ګK";9+7MHsp ;z4Ӄ"i*Ef>kE)}(o~9SRC zẅ_:QDܷg e" Md(}ƍ-Gϗ a\9y0ۃTYipS999tAqddvvvb7IIIΗI2W8ѻCJ+ Soq*'VZuN~!QtI6, Z=c2<==5=y7|sժU5?Á׿6.SYY^nɓZ*Fs.<n0ٴV?H[]awoӓ$fy{{GOS;tQ#GtG|O^nѢECU999{ꩧnTHf$I_~eG\fg=疏$2r\0C~ |DVN7n{SNрܣ:vjq4ju:TG{UQF}+WغuҥK7xk.دu Ψp o3kLvUNuKrGcڍSSS#4OOk֎o8-v HsVql11f  jՊ“:oC#4(F`L#0b\`?ϮavPf)R='ϓ:$|nłsJmaL\9TVm)n8zL!bLV%8m3ZA4h*EUf"֣S1(E" OLD&T\ՐWnR\_Ti,1"N\QA%]iZ#&q̽<^1Ǡ׵iԬW@8cʈV;ęߧ ՏTY/W مUf3 0bI\97[e՜Wnb d=$Ɋ(|AZGSi|<|-So~MRRYgثm MRVfMRLVl5mlH 0QqE!!2'"AsbFd#1b;DcDMtҖH+W[,o𔔔}>s.\ 3g7)\do'sвtѽVniz{ER&)&d6II-V`'"Ue]e]6Y$N.) @J{=h47LÇǎ桭[v QNܹ]*++O\`^oތbwdk.%%yM͛jժ>}4}>5ۥյ[8?nݺۗϟ̙۷ʕ+x;Җ=pdee^XXHDzAAboRvYaG5 n+,6Nyy]O?FqsNlDh7p96߰aڵk{ٳgϫ^ױ[nDf͚k2w)((߿̙3vFw)MNjH=N9G\4_RR̙3###cfͺѷsȇq"RlSN:u5 g̘#Oؽ{Cx"RnLmQEb79Q&|N#&$8+ WFCTϨщZQ^ө}==U5BBBꫛIˮeND!bY/_piނU\rfU<{fyjrz) A`18\!.L!N\QOfLd.Ɋ*9ΨjJc3vY!"/ J>ZQ W_)IXڝ>ڷo6iGhh!C0[kӉP^щt]Rl8Zm]V-&7ؤŮ WRԜ8,"V7ѯU8$q!WmՅ{M պS](eA^z;(Ҟ4j|mzFunjLVjVY :]Vk-ufl4c\lJIUCIZ-0FpEQC *0hΔń3uRWlJID@?'#ULbRUަ^@TYge O9""U6P9YJkx;``^ eaD\5orƉ_RPRmoV4TY+luz$Ic\Ֆj cL(zOm ~Fz':[LČA1 ͡ $~<6~G3c82W^mVjSyj5:?:eW-c|HX׀4oyK,O.^8sޱ|G&"W9kqu|KkuBG>x𠿿 աgWn/7痛])dE`&6rbɬrEᾞ_L!s:B\i]7/0\nE4]/GtVrœo2k֬qMFչ@s4>|رc}]EQyh3fpy4bNkʔ)oVHHH㱼:ـ敛^:UUXKɜj̶甆 ҽ]PG2JH]p>]lٚ5k\qE4LFOwM|РAD$BʻVGXkff&5Xȍj~(]34G#RǬyOKZ.u֢*3>."nαtՙ7[!!!n{ r4:ujVVVVV֦MnTfeee7`\IͩN/ja={ D|cf<ֳuk ;666666vMmh4ƞ={:PF<4GE9VlvqKnn3o&6-qdɒ0O>s^[[߱cGGG/] ~ʼn]t|7KQWG@@@ppp뭎yO^?o?f|S}Q`̘1/缢s۷o5}W}+"""`0܊zرcPPPHH m&7dz#G9rE7ٸqcFFƝk@bbb{/[.jPl ye;e:zC:M~l3fff߸,X_\368q5UYg,O>w܉?kkkW^=oQFGuΜ9CD}uݻ7..-V{fooo^6EQٳgϞMDG2J|SAz|eBB o"d~sl(B#Hs{I i޿NbsQd',@CA?ah'NTZkݖ|&%Ӳ+eѯ' S#"}<'^a"IQ4Lp\ iD0jW;v12n  T7Bt>HFIiٕ‰yVD+v3Y&2]ڡi༴'z2b6I^dˡXHv ֮k?KͮL\X~!lh%@=W6IQ_9ad4HsW)>h 3[u{/ 9O i=P=܆xazV nO痛9]0nPXVke샙)LWilyyyXpK^~P2ٹer.Gg>FˀS|i*ܟ1:sNzZx(X\-im“: ؍vd6D'<\q/^lfa'DuuujtSN1zjl2~:i/WBfTܝNKzi^]]O?MEbGu,˗u:ӾSEz"56E555fG6թ$"Yfiin4f& 8=~|ЩݲehРA6m@TYg}lW &kkkW^}2.$'''99mLD QM64hSN:^N$pڐKƏ>hƍFqѢEhpC2wܹscs@Hs@UK` @ iZ,YҫW/ٳg_ѣ h4={D >|۶mfͺI˗gdd> DD ( fFc|||RRZ ˗/:t1Xrbxzz444h4V{eKVݴi,im:}t7Ž;/^LDWV&''˲SgggDG#l6G^?hk7pO6Npz[jJx]pF={vW%Ij\h"JOO?rŋCBBЖooF8/\p˖-Vuaaa!!!&L3gδih6pL Mw^Wi+4:Vp4wZÇ]k4o{7\'`O ;@ iHs@ iHs@ ܮ]A֭[}}}jjWsss24p%cǎ]`ŋg̘1qDYm֩S' =_?sۉhʕ<06p=$srr 4pI/Rrr /lٲ-[MU` ڵkz?Y^^>k,պrX4@c FPa l49 49 49 494fp4lml*iHs@ iHs@ iHs@ iHshVi*24A*U@w޹Bjժ#Fo{X47a6o??n+K\\ܩSH[>|H`3CDD3gtDѣ\rɝ;w۷////--mƌps,Ǐٷo'-V]t_ݻV {'r׭[O^s]NJJr4 ]xOˈ#EQ9rDEuo.8qbDD(AAA{ꩧ6oތܦСCs4ŸgG0`f_9rQxŊ7YxGy3^aڵkZu;eYn\gN3f~ۜF+++s1c-[x;w6.;Zp!缢"<<\]ҧO|uټy3c| ,Ꙁ4G}:Ba˖-7Ns"ӟ4{l^XaÆ(~G~m~9JwO?Աܹscbb\3|ɒ%?ٶm[QQFQ>c~WǏ7N(ǫK y毾jÆ _y9k7B``#8Ν;Ji^SS.?q#xGEE52Ov0!!sη抢DGG j圏5pʕv&رqץSNM?TGH6 owɓw_\\zv ˲.|VupߺuҥK'N ccc )SR8ޞ2eoı[Q>f [nU򩫫S~en. R̟??$$$!!aƌ+VBïEDD8nҫtС]ǁ,RᚚI~l6l6uI_1v؀d 1c㮇/ܸ-eŊ@/--MII̙ӫWiӦSp"~3g8L8Q[o7[RRh4ax3 34z IBB† Dj@/--6ܹqw-_N4ɱرc˗/wܵӦM۷oco_v񴴴ǏڸqIƎ9]/zĉ'N,,,l\ ==gm:%[nu<ɓ'_r¢(:f pqNGD/]ޮo/j:{YY٤IԿѣzw}7TVVQ\\?bŊ;w6>blm]xx|0m4;w޽;>>>44l6_p!//1oCnnn||M&ӦM^z(k9rsnZ mZ3338p1c8v Ǟ~i??/ի| x԰̌eyʔ)Do߾իW[Dx1n~]&O\[[;rݻߎ`4љ.~曛AuuӒ0{o0߿1D4nܸƅ9UG?Î7?믿v3fLϙ97ocɮ]8$9~ ʺպ<7*ӯ_>ǴE9wkŲaÆ'|2**Jk4A͛7ٳwx+N:5n8zjժRaեK̙ӯ_?uﳯo׮]'N\spF?\i8TӴ@uucoUPP֭[GUX~~~ppo߾9uٵks=7hРuSPPPBBҥKM&Pl˙*u={ֱo_8qbK]^sܝFpADQQQ7[*Ђ0[a @@к-49 49 494fp4oh4f VHs@iHs@iH[dɒ^zyxx̞=Fm0Fhٳ'V$ ͝÷m6k֬Y|y~~~~~~FFV$qsA `%ؼ9ϟo4㓒"sk(⋒$YC999aaa&%%eW4iђSN9rEh4ן,DtM՚ϙs.˲({6M:OkWVV y*I4 c嶦_ wݪ5EDD7N w¾}~W>}_f?0rHyK}+ iHs@ ;iHs9 iHs9 s*Z Cs줳U,V.V{ZiHs@iHs@iHs[C# `ɒ%z={6"÷m6k,Br*,Kqq,ma hkl$IX9[MR}ĭ薭PRRr)]EQRSS\r^,r&4|^.??*//VbUUdڽ{UfY,Zv7ض:.<<\9?w\ppphhhkLz"V,z߅3 FVzc=ٜUD:tvwo77) qo ѣGk݇1b8b m1yyyFO>n9nY]ZJJJon77W=eҥF>ڸqh\h=KGϗ21(oOsEJ\ul>wܹs:[Zj& 3(f"zzx$`l/6ى)tъ/(0|0{4 ]{3syN_O_sFX7ߜ*@+ܩ,/cO ЊmR_O?&h& ?|mHs7sA7DD-۞qb9 (JeAy_>K߶ɸZFY7$O. 1M~vyrEBmC\RFwǼG>5L`]l- PZ1#z =='{Gsyמ@SH+W[Eؼy?TXXhw":G:|" -7}{Er좺DVOs4|6}h֭:u.qYQKu^XTaCwr yHHW_}t޽{O4uSDԧs`H|[ oNz>zɂY6YdbAMfa F ۄ2e5={ZQbbIJڕo,:Y.+\QxzNOU}1wҽ=5#]CeJQlGPVD+ lSN]eE!v"J K2O֘G0b=j!&)GϗH-JͮP(3EKZ6gC};v G@Pz1uFPYggIlk= )jFPWwyEJB1Bb77A{Nߩ!\7?V7eE2)~}2㡸Їu o^4w1&DqF9zM1ahDIUw~,IR[ohyA~'D uZhCifKܶ-ek}bl[{H]WfJ>WՉIVj=>؛٩Ϙơ=Bpt#]*gI ϶|Gx;5/>}FMR$YR\Vu1>>*(,;aZխ3ZDDO%h ZB?[dA Hr!R~aĘ$+~azcwx;;=4'"p2qNMcZQ4E6>qdYQ8/V7=W&hHWxA^Qgi~8k_wEk("UYsJ3 kk, ݮ(/\,0&j(ZQ^1+<4oE[ggޞ_a_@ƗIJIUCVQSQbAmeEYBf|.|~1QdE֊aA;f Ҋ> i~ǎ/5[eb|Hk,RnY}IR~ڜzh&Ɋ(5&[MB~F`p^o篋wXjZ=<{8w:k^JI}~rQ]Ni‰z$|(0Ƙ]VB"; \. w/ ̫M6b4.z zAk|gIUCqUłڼ2ӥڒFds*0T6h8x¹;H3u<xx z4`o&qz ]nRw;Jڊ+829š,&0" 0N.+![>3WaB< :B=6,/cO 팁quIϜ.ӳRYg4ZaD(\Dlv^Zc.13&c| %Y֊_]h:։=C|?<+[7q\Ov踓ygB V`&ž9rs)+sHG AR_\/P+V5^D,aF¡D0C(fpHcF"j&iD '{7$H4, CBa2Wq&YYy)֟VtMݱC,BY>+fL,㨔k,[F?OD=_)Ŧd"CaCFP߮\WY9WOI1Q HHA,X t%g}_ iDؐa#T4ÔBcFؐfH櫂iȈ)ab%36i\iڭV;ukLpryz\On񭬧C?u]_^zܱ]=u@DD",|f"VLD,`bcSDސe ""&!X 4Q zZ$&AR)Ea+伜㻾r=%3R)H AĊ.L+"V,X]O53tq &"qq;qA1/ AL+gLL=H iHfD !%b l#_`EkGzH)00]U)nLρT+_9ƏADlw'u(:16Ʋ\7䲷@P+dS4i&&!އKY 5/\bŊڦ+oqǙ<~ߕ`@Lڵk+++[[[Sw]SSg>SHP10ͧ~}і8w@$n._ @{W_}uw/$}k ksosFĝ6mG"P$I$ǧr'XeY~?t;9sLRq\?TTTF+7ݮUmmŋ>6& ffG]DfQ -J httTJyi/\a={?GxgDzo7mڴ{,/.\O&d7đԷm۶ꪪ*(`+{oƼyjjjJJJ Q7oN&oVKKK2ܴi? 'Hs@ HZ@ ״LgtkZ״4@4@`kmmRz뭖e;v,giPHVXqƮ{lʕ8p[nA@A0y/BGGǻKD۶m{'9@/Zh˖-Gܹs׮][n=xY/=U"ͱZtN@'hXZ iHs9 iHs9 iHs9 iWU"ͱZtN@'hXZ i`oIENDB`././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/limits_and_scaling_minmax.py0000644000000000000000000000152700000000000020074 0ustar00from openpyxl import Workbook from openpyxl.chart import ( ScatterChart, Reference, Series, ) wb = Workbook() ws = wb.active ws.append(['X', '1/X']) for x in range(-10, 11): if x: ws.append([x, 1.0 / x]) chart1 = ScatterChart() chart1.title = "Full Axes" chart1.x_axis.title = 'x' chart1.y_axis.title = '1/x' chart1.legend = None chart2 = ScatterChart() chart2.title = "Clipped Axes" chart2.x_axis.title = 'x' chart2.y_axis.title = '1/x' chart2.legend = None chart2.x_axis.scaling.min = 0 chart2.y_axis.scaling.min = 0 chart2.x_axis.scaling.max = 11 chart2.y_axis.scaling.max = 1.5 x = Reference(ws, min_col=1, min_row=2, max_row=22) y = Reference(ws, min_col=2, min_row=2, max_row=22) s = Series(y, xvalues=x) chart1.append(s) chart2.append(s) ws.add_chart(chart1, "C1") ws.add_chart(chart2, "C15") wb.save("minmax.xlsx") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/limits_and_scaling_orientation.png0000644000000000000000000022261400000000000021274 0ustar00PNG  IHDRWwfsBITOtEXtSoftwareShutterc IDATxg`7sfgn*!$$B ! (Dxi X)*zlyDR~DJw!&^fӧOnoݺh4Ck>Sz J2**jʾ}PbZjjLIIG}KhZ%?Sdc\.ј{˗⋉wyC|oS{w}\u뒓y߿`0t:KJJn:s޽{<ԩS-5y/zիW><@{}'O{_E[nyW^>QzG)3WU 81뭷Ng${"""s:v矿uܹ{~{HHtɒ%u,]Y:W\y=*<''l@aʻv>}zϞ=e2F?~qp@j{$u_j[dyo׮ݓO>yܹ}>쳞s&Ol4fZ^`gS(Ϣ[.;;;!!sISO-[sj=qĉ'ϟ?v/B5`3VXqCyyyyyΝ;g͚SO}Ǟ#ܞ=3^"<Æ 믿wߝ8qf… NKCմi+ǃ>7x.\߯]o߾ ZS3 'N=gl˗/_<%%eɒ%=z{= @}Xs>lҥ}=Ӏu;+Wή=2ovNB R{d2 8ЫX6xcc,33͛=;B:אd'Ns:V[oycIM+Mپ\].`0 ro`W#Bfw{y~&O>=k խ[{vۿO?j&ccc'OܩS?vz>CBH^M&yjQz`VPx~KJJJzzzRRRhh(h͚5Yf=mڴigteee~m:f#Gx5x'pk{l޼CCC;vx)GsssWZu7&TpM:&5nݺ]V1c;R"h;v7n][:v옓{l6ۓO>y7` >}9sjT*,u j1NW[rȐ!Kq5:uչsgPjMII<|j.[ŋ׾N5י#LB222Phqr@x$۠ zI~ghhhͤZ~Gj&խ_~OO#Fm\NZkCR6l裏FEEu֭i]T*ݷ mpК04 |#11ѫנ-D1||fr„ !gΜiؚZw]{>\7@0o'MD/5?>|xNzL&sܫڅ :Y4kZǏOJJi]9ah{~ Cx]zpz/վyͩמ\\W_m]ZZzM{L+ZjՄ <S-**ʫjٮֶڞ:F@ 4&ܕɞi#B$I  , ^i8bcc='EQګ |";III۷oG {R}j6`N{s7m4wܩSb =|5_kNjoSӧO5pxΤdy_x}l/Ν; tŅnZ_SpWzUY}MXn8q!!!-̘1\.˿Cm׮v:|I+xͼ{khŊv[+{msl?ٳ'󄐬:nz{=թ`oYzzBlΟ?YQ,X9gϞu5ޕטx[Z+Y֪U+ W?8p̙3=,^O>a6'Mn:0.4};j&=Bv4Mpp5mosIMMiz͋욿N+]n;#Gzo~KΘ1>M}+^zyN^ ZsgϞ8@u٪}i~.yo.!dȑcǎ]`睃?c?,HTUUUUUUPP}{s .\FP|sF9m۶+׿:z^Q<'j...~_222OX,'6f%x woѣ~GϜ93iҤ3fxW'M׻lLah.5jAӳfͪcyfeʕ˗/\|W^SN״{3_駟;x./`:q?ѣ眤|*b8vn-((۶m۳gc̫y}tGy駟NHHO.==믿ܸqcLLL||3g9(@v|w4}~fD8yիWc/ ͚BO<_^#33ѣGqO tҥK6>ϯm[VV{6\O8q=z8>p:4;B) M¶lel5@s3k֬1cԞj{7k&CCC͛Lbbo9+**Ž>++ QhB-)ՐdJRӅm۶s6 u)S UUUWgc C}>瞻#Gl6\>`+& ν"2UX,!u\Px}zSveʕgΜlZJKK7nNsy>[uܹ7|sO$$޶m9w\xx/URRyرoFp5[dE?~k&Gxb+5["""r9l(fddTI&!&-2ySZno%''#&-@}PƘ_l7|SXX71F) o?nWWWo߾pʔ)ڵZX$IjF$Z|)QZ@X o֭z!ڬt? Ν;hmu^9 W#Y<}5[^!*jĉ*},˹s 5uJ2111?n~>}zc q8^L&s"hux\.WhBTXXh4 -( qB5>D\=AOZ`2k֬1bDnڴ~ӹo߾qš4\h̜:ujU+~\hѢE?ptt4 LZ-[B!ի=>sq!W3s̎;5 @"ӦMQͶeD_4q[R) ܹsn~Fq߾}( grΝݻwGdK@lFDD* ><..gϞZܹs_~euuDe#lFAɐ!C.]tRڪU[ouŊ f ,4ӧOR5[_HY@,@@^, O֮];vؘ\ަM{alGeڴi۷?uԇ~u!^j@_$$$LvmԨQ}?j O?i\#G?슜N'tϞ= "~x饗222o^{ZQQ9rB:SG)VPB!![lARj0"!5պl29:.445ۖŒ1gffbo /˛7n8j222FP DOCM拚S-NQaruoBbJ1<2˨V-w׽5rC <$>sL5q[3ghxS )&TRi+[˫f` R#ҟ!BdwGEziey0UjU|X2X#onJOnڰ~הhVA;vltvoXyHnBC5`MaH \JiDD/x"p R JC$B? UDu S-1QJ8Jbw6B4 NGy- [䨴8+s*vQWkxzY=#o +c((.{'m V˩r3:\%6xDؤ4e<#>G|X-32v!B9Q,6bwIQbW,#g@֏ ӧݖs*ҨxE($• ^K6qyK PJcИVJ]l˸7Bf M%ӆu)6;SDYUTZr^FS0F(G<ӥSoٯ]}j+2T=f@1ڗU۷DYA%H-/7mN~i%ùUj+h -'Wy(*LSeqJ+EF<@)xn`Ƴrs JmN55s{to#@˱PG?g!PFd2|>}* 7n`Ոq#ƹ{l:\RirmbD/?hCvd%?)6^ =GK=vWvwB-]Z= j&}wt,1KC >xwXJl=Z:ҫ!j 7ǽw@~囬sUJ.p !%HdлSؓC9}e4333)~ev` Lv"e*oao4uU^~:BIC$.&_75^#&U}\M-)U"hԩAAA~YYY~ޙ3g EkU͂/䦌iM 2-gKTذ]lnգ.Z-Ԯ%b+ ]ʂ9Qq1-~ueĈMf VY:!R).K rV#$DMHlr?>..N.aIBHv""?Ʀsrr|TKKOOu ?~Jłą(I"оK :_n.5RAA!dȐ!jQQѢE Ԙ+ր9pI"c2JU EaI-#R_ulٲ9!C Duqi%u֣FB(&###::!BsVp9JJ Czmdzi|TmfΜٶmۦ]/^vBfq}7*N+'Ns"R򬳣ݴČBU' 5>$Lwy לf0;jEAYX^kcTm>++ol[ˮל%9C4<Ђm=V*1&q$)`-pmvڥP(ek0"%vq҆ŷwBXZ~I{wj5S 喘֬61VVV拫0whܷo_ڤ>UVO|úX f ᖜb#!1FQ+e#16/hx-Uf'2B): l1zeL%I딂 /5O`sAi<Ȕg'iT$B]q{Z|YkpY[2J$G#>~W'(--0aBXXN?~)H//D !0B ٠nmn;u ~ J!0;z.4X'2d2є[lʕ1115dm;Xre++έGKfrUcL.)%\U{ -):xiP*B5JɂDh9!WBF}ZkSn=#1Rir}LLU-=)Hls6\WW42;9'%%e͚56M]Da0 jS+7UeVUn"#J#B$1B$B9Q.5a`<4qZ>{ gٓ_arRFj09($FǴ҆Qa0MFJO^7f M *%MYKrK*//3@/͡J+0SDiT R7JeeeϞ==焅1ƪ\iuJ;mv.=Cs(#(xN2C$(x(Gȩ2FHjVOIDeScw%ܛv宼u G-6any%H0ƈ0F=Pv]|dv|KlPm?]蚻?FtmI? ld4333e2u^"NLd69n4( -$8[Z%Y]]eRBaJĈ!RZ/V(45lQW.nI(11qĈMf9wژ=g%$)sAhj$jfR*_eKeDTsQsvDk!)U+}h/ tMhlPûavI$ qc !Bz抢EuRP59SQI]I-xr)%@$&X%15["M%ѻK;ioQ4JJJ|Z\.BwܑzݾtGۈ!'GȩdZdE=-L{ݻw+5s6o/7;;{ǒZBy*H)qvBAP.&]H\6>0/Rt4gϞ׷ !!BͧJs=8\MFFFyg !jJ C,]bFU +,!:EtDA.j-iӦ5s ҴOwlFF,Ry ##Gtڼ_OWY Q _goÇO7n4h!`ӧOwWL.$k֡Zœ&",́\._nݠA^x{M66mBdЄC"liݖٽ}ȋ$ϴ7O\w)6:]NDN?@tR$JfG<>{K!UfF􍋍u8?*"絙 &b;GG{ćKJ~:( JB5g1\8 !B"T;ZT6 +Gڎ(DdYMNG/Ur ґʋd۱'ti4PJPRJq!DQsF) C֪F;B"& q\xx_l:d\i?Yw!B2K6H=59oR$ #_}U~KAPF i/_|Μ9.\2dȻgϮX"55o߾7nϿ Vlk֬ڵ+Nd5֮]`m۶TϞ=E&dɒW_}`ժU3f8tЌ3xu.hBtPN;S~ÑN8/R~QUpvm۶6/;o/6\ۙ.$3g޽R:s>`8w]TQ0ݻ_~0\oY,;4蚪 oqZlYaaѣ9FQmvB &S|҈&o+Wܴi8\B2.X-Oi)8f2 'O^hѓO>d2SF~JKKWZ5|,r΍7Θ1c̘1,..UiӦ}giii[K-z衇:u4iҤ4mx-ZGGG#CzBţ&ΰa""">eʔn犵ͳg}ܹU;gϞ=ftkuq2 C K\+-Gi^Vʪ-J&?5t-gΜ)˛|NAr % tCHs̙6m?_}Unnw}NwmvҥGYl٨Q>_|Ş={^}QF <?lf믿~=jX[nn? /|{~ cZ'~M÷܈d*pCl2Jʕ+ą /Yi=11q/!7hBd/Џ?ػwn?5j OSӇ "U|O6 U;~'|ZZ4}#GW%!Z'1`r!$v_4_ll:YW@&Džu __ !$\2&&;k6m㎕+W"2<'SSSQxwTTT޽,XMa-xL#D*L$TvY/PqbcT*.]&d ,Y2wܚmMhurQQwä́nݺsرd9)))gϞ0Vڵ {Λ7w)m۶{K.ӧϿ>zga&Ƕ32uꫯN:u֬YH\Tf sqTP KNERY]'%)O?wG_QmuN-ߣ`0K={6l_DQ|:($$+ٳ眰0XUUZ9׋jOZ@i8eʔS&%%8pwyg7ʊe3IpMs<!֭ڵkG1o PqȐ!h7,O?l6dddB\.ב#G7!xwSU?_9$y:QRr.\X^^>zh=//oܹ5۶m#̝;744ԉ'222)ŋoڴ'?6˵dɒ|C'xڲeKNNe˖BAhS0LC>(9= oouͪSsfoE v 2yA~aJرc۷oߐ!C7mڴ~&LXrn0&ԑE$BOI??c X<\Sé ŋVw܁ ITGI*~ɓ'~m?jPBbӓլ > і-[f<{۷o$c޻{ кuk;?;w%B a_DQQъX(Z7~JV}_uU Z*TEKȢa ;$dߓٷ{nMa! L|!s3f9<Y,*U",V9/4f_ܞ={f̘X]]w:W-Zv?aÆ%{DC}zA>n-//Կ$齧bBЎ;nJB=ܓ!${mzR exgMҲi&e; Jv>};mO0NJg %79sdff~oy衇n#hǀkҥW_}uAA'UVB?`xs=D-[2gXb󙙙iӦFp:qy!B78EQvvoDxniv1;#Dzt7kwl)]rСC+Ղ |G}Q'|'Y榛n7;Wj.A1%%%1D >SvꫯF/duAΈٳGQ5e /)>38}3ѣ?sߟ@=:f̘*2L'N\nꌿCL[&+ H*vu} <I9rǎF]XX v=rHM^b6_ANAAjgHN\rʕ)]r.n?>2dȿիW_z.i&O_3xaF((Tbl;5D(ʊ+*++׬Ym,B)o{5k222rrr&NxO>֭{qJl]-fױ?C>͛7cx曧L3m=%nEES=`Įoߎ]YCkk[[[c< &LXjUNN68믿{uƃt;}3f3:n 8w޹1DqNB?_R?/02޻[l IBV^fջ/=ִ35bjLVK냏-+^|@~`j<*t9}W_}U5 S 1Y%Rl6~+ܹs̘1aÆA4|^\G !骡Y.0`~ʕ+C$W,RVҝ@D_ö r*G%,@)XMei%^nq!A!ya } Ar!w)8ڣ> pXN tzhD17asGIěŒ3\ahL/OZ*ť;)?3+F.n/^^ $~_ i J֤Bo}ԩC^{οyl%@@MAwwkZ>Ylg@zrHv#zEohTR~uJ/A$_ It-))O°gNpͶ1I ASCq _pceh =V9tߜk -JE18 h?Ӌj6d ?O`ӦMpwZ$ȼiUdU{s1lp$E{>T2oJ4&_/ =\9tfN8{_(AdٿK}h5q+HU:ݛy&uRߘi)vch``Tn ~I_Ξ=;//`0dgg{ <}=}̣Q խ{wCʡ{0w09Hs¢L5mEnzB'݁o,426/?Ty .8~W$uP/U P.HDă.}ي ._|V4i^eAg%S~}n0"?I=A(Y*.+>R  hTUk W !;nUU ORO7U%oѯ_ÇϚ5?08ұm5Ma_?30ωAP9t?r{zXTAR@4|k|9zBgE08{uEsq7nظqe˚(< I2(<#r!UU{*}>4w" ]ruˡgo nЕ"ɓ'_K ǿ#Fw wՕ_<#i)wh"J >C EI{%U;Bf̘@OpW:d.\*trضm6 'g WqݲiwJ7l[{h" nODTeFaܮ|C<RIl rx_dYwK~zO<ĨQnVt](%SG:yh EwU݌[4ld+RXmtG-APvo[V,*4pc6PJ/w .]q!K=ž7ZZoD uʲl0ӽiZ,?4'}7xGIOO?o5M;"3ZQhITQڊqwHBt`fn1 Q \Neń rZE!,{Nc10%ajV4L$jM!VIS*;]VzFFi\csC4p3ft+'0 tV 6ZH[tPiRy!e4{_x[wީ_paVViråGZQhIn-uVT*V)Yc`\i ul+B:BNNwrr!b8j*X*Tx(U𠁖|[r$90L H4s̺ofj ˗/={vnn. gnEFKjjjVXn8̆@:d Qg"C7gÙXdIaaY~_,Bʥ<1;GtJ"lEH"/ .h}!Ӱ#T? =TönymMiDJoWoYtې20PB7)軪.O5#GJ?qH#@)(j1sXmk/Txh_3Q5zڿpAGnżAۉүUƯXM5#ו4>|z@-@t:QEob⋫(qLFC6>ae`:sΝ;7;#3/>=y?~P(խ9qv>\Lbh^-&'yA/APv8ﮯjIQ~@\cBK;0xyr׽1 b*P`߀\3b'##`0` s&"!r0iX26jj_8&) ,\mPkAy  )x18FU5!SF5=98t0'Շ(*=\3" 677/^d2=' )gkXp ȥ1SFLp?6VRL> ji[^e>SF`(t[/=^II7~EQ4Bc'g 7]'?ú1~[rcĆ }f힆yMNJ/1AxOo>")*? l9ܲ|]Ѡ^EEuGワ).> ABwUﮯ}p,jXcOؿuuugX{Td"Tl,G]{֡4+$By6SӴhx뮻n?ϩS>s'h$^e[^^wYZQrh]L0%D}DijBv}-Wf'f9rkE.~q8 ^(8D7Wj OEPʲ5t`&3?g3"lEN4]bE͖rBv;j:2mCJ0*@IY 2lذ!)&'vJUrQB]LHbOKMM+ϞUU{95o޼aJ)!RE5IɈh- E5 LWy0\Ř1c($nEdh5rBOMIɄ0\H>I$,G(5Ob.6Q]^\sR IMM0`@ǿrR̈ҥK̙SPPߟh]՞ reF.>8n-Xpt9 ݻ7pҤI}KJJjjjgBа|;7'n.fŊ}IbCŧjcr '2(y6@̝R8ap楖+5!VԕlܸqI%Kϙ3YBTTT4k֬KM,~Hm_5!637gJa+J./^l.\5B7I[g̘q!/RϪ&qZ {9/y wHN n xYAӯf!5y[;o cOUUeY6m۶mĈ.PgGC*[y閂LۡhoL  L,]?鵭UUo;j3qhmUFiٚ7<6(uM%nO&"*^ɡ⊉^/H]h(t.2]~_a)"Z[Y\4EqݚW ͼн>}zAAQVkUU՛o~adER.[A4@ hL[;ƢE_>$"**|GcQ)** Hkq;am|>VDP4UMOoOm/!h}`©0]K {c45DtަGMyO˴i{{/O8;v,FIF6ozSUuk8>ű ,hЌO5e. =U}f/ذ -~qThs@X/FΝR8(ωqCPv YVE{*<.aB NQ7G4Y5m 'ʊ+7V -HsrQE7ixetKvC)CWjB ɼ=m֚϶2ñx!EAqɪ/}~ѹwN.D Aq/wWDX2opL֮,?z ATR̺j[]RFo$xJ)T4^ SUC)ǼU@Xt XMFTT7sk<)ho#HRqVնF6kNRTIdZ2}noF$ ) ?@^5_7ҩu4{Ra@߹r9e AwH읕v8G"?Omkd |bcmv 4fn ;J=ene9' ɼndnDNEϝ[镕|  (V_?Rn O LKZBHOz [n;j^s)6e̙=oc#A:O\t˻1 > @4Ka9\M,upuA.. kjwAv/ @( +**k_ry9/G8BUn&tK|[YR$=wR8hr G$E߄؄@gLnr?qU5j?:n8$Q9oO?ݰa*NE?o,k)&l4{RdXCҭ;|LCMז4xN?d~v26ʁX A{{*VI@ ! ҍ<[4:}\#q]3c\qη !Q1bn? oHl{;jLvho{wop^dɣ> *Bn=RuGB-&nh05 &˺bP֭A퀹S ︪OEc軃-=AA.*>a0M9uT.DP~/WPBƫ& q'X^5kB9W;W6WCV1F}Xlm$]}ñ̐Q9d%O?t~~ߏ.ұ3/wחQMƇ+pߙrBL-{ B ,3(9( __PuYN3Ð:w$ɔ0M>5mY0>_ڌqx`3Bgk_I!@8GN,T@Γ^i{ohߔ4}{I4xv~Lh{+*}/||(3<ڔ9Iawꫯر #NOx-,@~z!),K[R*IRvv`sVmn41jtG Qa#Tї/ l`2ޘpLUʴzYC3(F!VӒ:$dggw^΅ K `+^/^p8z衮HESۃM;K>Ḛ"@P&TPt ʱL/={PȾX5iɒ%}錅 tv!dJiU$n28/0MN[RcͲ?(sHާn4iR!C_>ʴi&O_Lܑ-[J*|^UMk_m2'uy,2Rшΰ2 ;! 1# SGJ#nJdoezLZ *:ud:̅ˋaq]IW=|6(p+SUl!7؄3웊imܸ$WIX~5?êՍRw/d0b`{o@)ȊVZh ~adm+̶]54Sp8\sMeOtW$E;P;P;XmD9a"@ a蕓jI53E% Ff>uY6<Xl߾dyI!bIOfP*ֺ#aQt&('=&`"+Z7R|{O86f,Ȱ L|.#L:$f,mwcj7C|5#Rϒ>tҖ( wڅ1ؾwjfPz`R|'K4'j D oI5lm+ʱOcrTqikq1P4^&>PQʪ\V^V7,6xi~iy閑}SqB.JIl۶ rQJ1g' ̈́]G!_8f`' Ű{% e6Uِa ~S'yAč&#/n6k Ra}r"JAQ0ral bMU#TI8&"-~Olm9om{ʽm&VW0~_݆ k 5{ iV'U&Xbn  z9k[#z^;AJw @O8\8P/ȑT/B"J 5%(@T TKo&8ʹ2}29yPwsitB'. 7|Bmڟx4MKA9tc o866'}@yq?,$ 'vKRTQOuph]pWG xWNH .XZOr,k5qy־Yd!>>U6=A1& C0=Ԓcٶ+Qrmk$((Eٶq3sR͸ \R+ φ4@Ot̳bD7Mi va@/נ|')t. `KcFM7U#VK7 ,KMFbxCU @D:TP⧇YXM\L[8 ӆio _X:TnkߩSB1!e@RAldUz1w@TqhomH *A$iTB@DT5+•MC4& N+o7 [)+ZKPh O c5q٩sTˈ)2͐.P<kS4U|FQMkOf֠_?:w@}X0=cX4K4 s.'{jIQyk7|a4UF< @X _4@L\˜nj0O d* /,$k!rڱ LF.7YQ3m hX3S$z IDATi{NAnK,jʳL$&I7RH8q?&mOnT(GkGk C<0٩4?(ǁ+.I!T5[ր(H6Mę^n1Db$SZbWFe/~@\ If6i#!D4p&F#)(F}hXb5qeUNww1ҫ˪&(Jj7*TwJwK{n B(=! @T.A &p9iv~8G@t o(V oM *C *8%!PTMRpuK8^ڔf2͆bN5ufӱyHHeK+6!AdUh D4`ф3YK,4J(62(5f3  <5_/Ի-~\ Jq@'rb(ɘT^1(! ٌ\h7sNS~5?݊ }#`7ZuE_H $}C@ `2PByb0,30MV5QR}U1̠μtKˌ(D2Oxf*ÕM2JEYaqYx9FR@T%hBx*+#ְ>1,**ZUl2L)i;yKjZ"M/$E%"(Q7UpLԶU}q:ATPaSmF5XRQRYk 9LV#Wc AA~//$PLTu$(+ʻ9KM~AV4IVc7xC'>j?!1@`F#g3! a81d` ,l8,̹|96j28"7cQI rD9&!Ad-S "ʪRM$EkT%QЄR 4!`٘:|Q]Q)Db; FD1632gLy_a<4AX_TM= /&PF b3,&B)ZqWy 4Q @ z"E1 !&b2Ycxc5q owy`6r)v_\]Yr4S=!RDPC$hLZTcjTQF5 jYm&(zxC(*C׶@䋷Hb:o(!_#iS3RFl=np/08ߕx1"*M>wG}an7=dK25.IDYD5sdė''Vi6'S5P5UR @<{(aVIbB!0 8%x4JREad`)Ek[_;hSch@H||tBlFochpx ϚyN1EV/e8ۖ-F6?Ú2BAXXM% +.~QU5-emffxeY"ɪjBLbYrÀPIVN8D*mm'CJ$z'±acD(*U]\R۷;R +B MInіUqj SO\lgYQMV5A|OGL1L\v&" .r{h5qE9x sݗ? w_Xj p5G`U8EvfwH*Iְ@P8^Z%Jr:TJgma(şI8QT-15 N|I#Oy53$nҨdgfZTTv OPUMQ539Y)&Őb,}hAIW\N/1_XsGT()ZDTLiF9YF7QRO>ะ! g%4a=DI9?ŕиN38!?{TcoJiGNmh'ԭ#0"!ϒ^z6$kG3mARԈ(g>+)2.M}aÆasE@12Ja۟Q/FD%"* _5IYLn1ycHUKH\h,!1UeMTYN$E޵LC)O>_*9X3 C{>h7rF5 1EMTOPT+)…@KF;v!ƧڌY)f,  }4JR 1YmQ6V`@e-Fd` e$ǚBEvIQ5 te~i[ӏ"&b $Xsymg< C8c !ʊ@DU4lY)}FWP"b鮋|r>L0! Y,osQQI#٩Yp ˗λsssXDT‚PTJHeU `"H ab5q&%g Q2 cRU jS4s̍kXWıK8Fը% !J#<8ߥhј 48P40Ts %'dY6g3RxY0\9W_^PPm AA9 %>)S4kMmSVQ rXTʪ5$\$YWVFU19`1&eKh x(A5qDQ>eQRo0d#NMMҥKݩq8iiieee_pIe؊F Cto!,:( $I"  PN,)(J|B{X,&I^9\ + =]⡇Nl(뮻'Mtڧ}yꩧj ˗/~ ,oPSSbŊnva.J0J~~ܹs1gbɒ%EEEfP`0DG[]S@zvQQܪuUTT$  BA@ 3fիט1cf={^}_AA. t7+WXBŜޝU׋e%{MEJ+-U/ ^*r{ UTD([ЖY=d9sNiZ 4m&zGΙ=9/JJJ Htlo& >Ma@Ԛ@0_ngfE cYVkkkܹs 7nH; fʖ)dEn:`$iȐ! 3#\A\A\A\AY^3gx<3fXz51.TBbŊ%K,Xࡇl7onoo', `9pwy]w=/&, N3e{1˲ !L$ ŠdYU@YfԩO=TEE(UUU<@?}<~BLU,hٲe+W뮻=Cp$8=-E"˗s7:5MKo:N!~~ƍKo[WW_O4E$JwܑNjjjΝEu]'H>OmK/=sNfXdzx⮮~;v0aTٲe… ӛ> ?ߴl@'?Ӈ~r"8v=ռ_EEEr(/////6qD>WJEE[o4 cĉӧO߲eGjIIbرUUUcӟDˁbxٳӛ555B 7y嗯UV 2 ݔtO @}s]tM7tС#F\_ᇙ+.^8* $=swc>_ G㏯XDT~˗/'|5\]gAval ***BZz5Q HeS< o^@% ́Kx7f+++++++++++++97TE+2$Io}[9T ^x=#xx`0xw!:묥K@ J*!r~^{mݺuwqG^^^ww~gdX wSOZ!ă>8~x" ~.**Zx11dUSMMw}71dUP L9rԩS/VZEd@`}A+,_jKK d$^(9_O*n6!֭[?4Yf-]T$V,(*555s%7w}{/q^^KxA@%3TTTTTTTTTTTTTTTTTTTTի@,(*555s%7w}{/q^^KxA@%3TTTTTTTTTTTTTTTTTTTTի9©zj@xOEe~fx㍓y~@^^Kxe/x0×Ș˗/NΧ>tuu:`4|wgʲf^>K"YNgyy\/_UA~~/~=ׯ/y3nd[/b@,+H455֭3g_OذaCf+ UgUW]5=sOsss,[oM&=Æ [t)`0y饗z0^<ȃ>;=xfwwgy&_WX0{c奯ɷ^:oٲeڴieU5a„wyχE9z^yyen?7x%\d>kO7׮];g0{V^M"OrNun̹sny죖e=SUuĈz?Ɵp-\xᅙ{nx<.;@zAAAȽwy3f3ׯ_Sv3f…>lf!_$I^_3͛wc?yWoq߾}I"^q/RzO]]/˧zOG}5I}iӦ%Ԟ{?7oSO=￿pz~ۏyM7=s;c޽{3L<'<# øy>?;F1K,LŶƍ'?ɍ7ޘ/^~ǎw[wkx`gg9szzٺu9s6nx2KiPhѢE `,pl۶M>z7>tǓ8sQF۷/sb,{/_Q_ʕ+?ԦiuuuG].W7^tzkMM~񆆆믿>s[[ۛo9/u'o}{>OM2g< ]{۶ms:B|3^c?VUU]~1c {=!DAAQv 8p^X` Iz/}K'|rGkkk{ウ>#f}y癦y{ѣ<g7?F/ݽrc+oo?3wn߾ד}ѯ}k7lpEx[nEq 7p 6lȬL4Rs. 6 1#_A, !IfΜo|g}]wE^ ؽ{]2w>쳙%!ӿoe>)9ɓ'Xp! of>z @9;o͛?+?1bDEQ~_*^|ٳgg.k6m:%Gr 7SG3' &LٳVVVSQQ^|_3k֬s97@/bҤIaHdՙkGԐ^w <; 37nwfSŕ: e9??E[ zvΝsUWW[ڹy[N< X*BS5EzJ}}}fqq1Q^CUUU؞!C>qP/^x^{^|ͳ:(@/bX<ܓ߹{8P{ݹWE =U?3Ϥ7y^e]F?14& 3꫏=XzsӦM<@z={RN9reY .|Go߾g>ZYYz~ ^~ٟohhS?bM6544d>dƌ'Nn| IDATxu׭\2M7_zMMM?ңս1bfK?g瞛M74en*2y[;NN7G>ɋwwwgv{zsŊ~z!ڵk׮]|?N3sng>jժu֭[.y3\\{x<>l|{Er\=7ߜ޺+O'M[oZD ]Sx<Uf[r3<3o<߯(JEE-\~z%I媪3f~|8iEEE=ڵkoiӦ|>INѣ?O[l6mZ⬳ڸqM74jԨ^#ի0(?~Wқ> w^@SΝKNIx_WӦM;A{wz //%d^›@ @ @ @ ZO>a޼yzyT@N @ @ @ @ @ @ @ @ @ @ @ @ @ @ @V^MeYDT;w.q {^ 2Z/ܘ@ @ @ @ @ @ @ @ @ @ @ @ /̙3z<3f^`p$7HtTBbŊ%K,Xࡇl7onoo',9sHtAq;S{/^LX0hs%E?aFc=fY=!i$U Zk֬:uSO=UQQ(JUU<`YHt]f 466666G?ZlYeeʕ+D"q= DoKItOl- ;˲$ILiD"r?Ooqƥ?cuuu-rf4mے$ 3Z4B4[o5[&575[Z>!%DTfE(N^hf.I]>h9fr-甿rv@*fF0| ?˖-Ko>#B~9Ô)SveFAAAɺG"\˲Ld!VzPVta7S`0Fزe>PO PU BIBdщC$H]t:?y;8tuu)Ds Ч`0bŊna0P+HoΞ=[7Gi>ENjO_ Ht~˗/_N(@ |$- WP WPXE` CKP9*̫*D8*!@6z***R?;]*K.d$GŒdH$= `;^o>]d0#Y&//﮻ ^M-[vo޼yС$IY1$ >n4XH]3fU<4cXz/3M?A"7l0Zڵkܸq?寜MguuuK>%=ߞ={SVX-[̜9ĩ@*2uuu">h}"BIBDp[,۵kq8P(:ED"Z!`f8>%`.}hZ, … +++i Ybߞ-N{K_Rzs}>GOjO<ŋOqšnd01-iXa&Bv| 'tU6E+NbS$.slr! =ӃFHC\p!q8K=ꫯ&h`H&H%WI#_%aFiH\w:d"h%Pd]veWm\SftRϷdɒӓfe˖Ӆ\ |cu]Ϝk߿?;u6]x{(%#dW$b #u݊izuE>W6]ZЏRU]k3jFWXČHˆ%n&4#4㚮V*u3JuxT_TF(aZ<6 KfpdIY%llSeʬTCq;U" wr^umyΏYD 7aÆ{.{G***=?Zb́؞=_ #ISKeY%t,!0N>{N ET:~0]&ti !INaH**.ⶫ~T=vlK;ݑ!~qT8wB FiWZ8Gbz(4L+Y\e$!r[=ɕ,IdBJ>M& qrTE6LS5ZѲ,!\%7I'_$ aIBX*DH"Tiv5gԺd?&Y;ɴ&U /gyСC/^ߛ;jh2K&uSƗz͒>ۮ5֑%Uu'Ȓd|Utdt(ф~lhW۲F,DCGfo\kLKeɮ(nwً[ijwP R5uFڢmh㺩.U6!Xǽvh K+CLNt$+2ObGZEd!Q5 KaWxҲԭnDRH4tD*=d@KKdY.T^|2yiձ}WRRBU䨖@lӾsZ 'Ƥq믶YBđlƏG:H ˇkսϴU".˲q%5.GeGa !dIe z%$C]q;>䃦fz"KvEBH)$ ELK8l´,E;qY&TeD0I3iiEz\3ҎKB5áiZqS'P`kEvem&Q-4z]8=\=U+,!l4z_[Wdq.."K"7vDcؘaynOM$uݐpX,I^ͮʅ^GQsx]iWvUM6Ů6UBx6!侻m)ZHꦦn !4t3yx3ׅL$P4%ɤ'6E7L!$ElBf:Je\vUN%^W-iG1'05\c"O !RݑXŒ^JIBUCqdMQe)l%-iXkF\3aXG.M;0A2M+עdKW̡*kwU)ڇc,`Hf,?za5+n 7nH;R͡}MD0<3EchЊv v]ih:RaYфiZk 4դa&tT6Us<RuӮU)KRu^:ӖN3p\Ǔ֝P"N lxR2uE;UYHRwD "wL3:CcnOLӊiCPgT%5JQ,)7q9ՠ$IRIII4iWCp_S;Ii !ɒlZf/.K^$vU6LRWT` ϩhm S ˒^S .؋(,TyXeWRi$hBOf Eɸ&y{1kc-v~NKgV'Q/Xulf c@+&X"iDzᲫ6URٴ@HM2C!ВFSW;N!MQC^Y3ON8c4|{[떃{C}-1:jyPU׭p"Ha45$v(e|WiqWolH ޔ8Uk=C,t]kAkW\K&Fefb aYnQV^ev"jϸay3O}UW/[kvwq8 gZ$SU$ôBd4w'Bd^^.sN+J<:gLq%dmѶxK OV"izJ!KBHR"BZ8;#}²6^ܬH) 63~ұAP޾}M@LKa Y'XR7ZHHhEIðJY8QQ):HTgZX+Vm6bi4eW UTUƓ􀁤avGjϮ9(mE y3ǕLAQ*p O& 8|L~$ϙﱙ׌@D 4!TT^*-prĀɦ<>Pi7G;C ݰdI-pӲ"ZG>,cG]%tmkjR;$ݾygC[#kzfܮʦscܶBՓSEzg(%˜||giKNTK \iX2Sb фfZB{'Ω0Ch׎TB* ț5Uocӡt5heɒpաE"=i#jx,7]5Gl>h%b H\3R9aH+3 v"aԵ";TEw([ C8=涖ۣDjJﳷ$Y"@q96EhBoEDS fvU.9r@,$I Ŵ`לtB. ZIU_7nx3o& h`ͭ-[vtL$,!I)G9KMjI0LI,&#4Qߵ!;u,K]&)RYXI[eK)?{TM*͡]iOg(Vz66~CKeYi9r,o-,,KH%˒iXJ$$KbDTN$q ~~v\SS3w,ҥKi`8Ѥ 0S#$a$Mnٜr"fJ'J$_)t"D?vN/dtC m"teJgq&ϟ?l6Igڶmmݖ|7;::;c̙,N6r)ʑ3X,֖jL2V4iҤAYV}aHBr3j,!,K]9qCy[3?hm۶h֭ġH7i$Bq 6̜9k55J-Kvv]VSs3*gO.n֭3g̖ g*Dġ_?gBqBBtԪI/o8T=NJ !)-ȍ@l\EsGPZɄ,Z$?2;6r 9MS\gCk7uvU^ό={TaVDHQ'wLR䞺u~iBbwo\3,|sĩU7h|>ٳ3L87se͝;;c(-p]>c3}|}[dގ{:IiS5O !u=)-߯*ykiCp {foLWZߦȺiN,P4P&?a*ҋ9UyZuaΝjuU*bzVb~]U,LL!s ]@gBb~"M(4Rg )Yz͛GQ^;э5w휪tl=Pmr\ Dz,Mѕ5clo+ & |^f\RRP ' ?+ & [V'>?qQHBLh IP ݲ$D"i㷿oJ;_\RTpR4W]1Mу),j{(>ό>LE @n"ηFv˴539%aVGw݈vg]Ϫ.jvUn+oꌎ-3)r|;s,igsH\l6En%4ȇwꌱ_8op&N zg%l6YKZc }]7wb_o~1zhJRZ.n j~9NPL8,KB=`$)$냃jzy?U/o8Tj5BX:wtaX,ւ]6s$UIcTE3Vxkk=kS>eFbz-onmmN*fN34?u&đc'6y֮Y w$ ΩvNU}[䇏%vmWq_Ĺ)#4o* 34?v^c"iZVUcJ;ML.~#Mz[*ܰ#Um݉xn]!^xRYAy'$yqx$9qr찼"5;KG܀ӯ3^?zgY羾yVS,MhPi i1sUН*@MMMkZa{3]HB3="og}wm[?su`0HkΠ2_u/U^ퟛIP:c,ay]`D{zgjL̿‘["׬_ngfE\Z5韛#"}!89]UkԶ ݋/Œ@HVʒϏ_~Kj銹jKW, |o;Y뒳_<*wX:w܁7;9s;5$ KS }wcP/e`J/Sy݆PEǩ4GU !,aY[k.:oJٗd@N5kϖ@V i֭:I3B2LKHbhr+^Pܑ4` amgUݥ;lJ,GbzϒŠk ԿNŷ^65"IRIIIŒG(vxagmkXXk=kCumySrB.x`pnܸ/)já`,)Nf>'5mջ^x,uW̨ tpbnڿ&e}kDM7_yM"fў3wvo1yDmgej_swK 3p-; _cx}[wݸl&`֖%+֍,&ps4Y֓:cB2O̷ AC}\t{С+V׮]{9 lZuBM7W榆ϥf ,+4l۰To tWm8iS'䩴5"ogC0jҝ &2 $CE__Ժjg0=bcoc[3"8i =A.VO [Ӎ-:/>g-ZhѢ5\SQQ*p9嗞S^ysk maePv%M>_wa 䦆o_vӴdIB<}TObˁNE.)\p9 0@; R$ITwk~zPX{JJJl6q@6(,9U[tqζ7* /9|ˁ_롸n=Vae/?↋G.gت ][Ӎ]$\q?عp^wɻK֬Y#2dK/4i$blomQl9z!]T}|iL4|kj!9ByjeW^rv9nf)6pͿ}iH"e 9C`ҹcױ$˲Q+V\.EQN/=UʨaOe^ͫjn%ޮy9zU4X,rdy|ki&ud,tccc,~뭷,Y2rL&S7[v`4ie0biE1v VؘS[ndÓ|- $KCխoYq555qtREQ2lINH$(@dwڒn!)%)䮤c# .,/gZQv}N~4rwvw%n[0BXh1 [EM-ƝpT~UQQpBp<˖-aK?5g}$y]T}! (-]-Y$YڊƎ{j/tGcMT -KOw`sgf[$dCIB !HU ,4E{,>E}*6:*( %!)f7{ٕn޹s;:m+DX C([H NϹ>-39t)Zo;DQW7L999zp[Aƾag/'&)JG+2qˁoelX  N(1ïѫ䛆06,wEEb|3.߰NO>o<[´`ؒm9UNǔQF+L<ѣGYf͚5#<<+O33312kG$L*XI-kWZB]o{|0YBb"| Չk%%Zft|{Ϭ1)ca5̪#UffQrU¿bZܹsΝq@H1:ɌSijZ NTeVM]1\ /Ho~ubj(6I7?Z`x@#nk$Kܔ^RcTa%uQ+^耑-yeN_ 39|ʱZET4Z@߲ {G)WUr4CM+D--d2B5oP?$+͠VrۑDVf|-S+ݢƱg-2b1kK~Z,*TS (6'yj,ByWw9D(%jِH#>S|G&+T .^ty9hgV>xJkαpzxj3CqO_ 2@D|{πwB+,M4( ΩVpދ#Kd-5FwCwQw.av<[މ%} .L, ZGfqVua/ҞS5S^۱ag! !xAz{ӴdX(kB {I,fa^:HrQPe}CV'[1Nμ6嚌B=)֡=]f >1PSz!5*e/$ @Xz~]ZOغu-'ɢO^^^aAO WNQ7´rȯobBχΞZ{H0(G.񃃯ˌ(!n;z}ff0Өdnǖ B?%~pHl!q6+9stӯzvvѣGZ s]fQ9DUZQS"Gom3{i"U@mCFRB;Wջ33KA =61}K&(ջ_~pҚ8 sÆ k_b9x`(4%R#瘫zG?tc<~|{سg &_~ƌwE]DMw(ҳY̸&ix T0`N_ >999-g[|az%D׿ LҨd<]PP> ga#]“+^T Wc 5`PVVAԋΜ}}^װe.H=^\)!'Jk㫜 %%C{FU-/ Kawn\Xj]/?dw b@L Kǎ;gϞ .uq71LpCG l3%"ExAZ=17i!& S3&H(!dRθxQdu?V:gV.{wlyKh|G222Ǝ@rEܱia:J~aR(я@]PZk_) @w @7f2a.^$ @5|B)mb,Y?j=s%C7\M 8Âwǘ?&K,=|W|? jժ3g\R['hjQ_(K`b.2J͞=Wl% ,ֲ q>(4L(@WkCbxK[6E-H&ϝl4qHSWW[ IMM?~|?o7IU, IDAT~6> z  ( H7olV:uF8e*v 7feeyy~ԩeee_W\v=Og曛n)""{?iE7poHyyW_}`ZSƆR b'&!jVqFCLƍP%Kty̘1'<邆o*qlV`a(ŋ&LIRq\݀iEFj2=b>Ɲ/%j+MRԖWN}qs 8oz|b"F/.NpTo=;;{˖-T"1́wI;^8$Qj8.EwiE0 8/CtGyoG@8Sf; ~֘T %eJk$؊Z/gu @)P"RqCH]5LrS+ 7WT5kƍ 6xLJJӧ14=knɋ@)5o5&uLX Boٖ3_\YWy  Bvy㺽1v~¬4CAUԊ@AJ뎑I ''-[l2ߓsyw08x|9k\DQzSyݣg! /H-[Z{aѲ. YAYrBB݀1[4CΩCJፍ 4 ;;Pn%huai'09w\B!' !y IK(kŦ1nm:Zq,q"-qܿl_ɉA9J]owzp,O Yg!:"5&U&# [nr{[N}޼y/.]}&770uT\wٙWe7 *k BꝠ+bՄQ[̚Kb!a0,@)[hzajuqP5OtZmnqڎ^HII=z4[j'|Owu?FdIΐ)!tQ+ P*N7n`cH:}K*9yUO,? J06,(%N%{&Fk1>q0Bq^xl6ۚ5kO?ݻ]8ΖY*=;.3_#9f5ɷ R4Dc@E@_Y+I btGC^BB%C:<U֓%o T=zҥKyr"c_,Ba]£1p`}W9%13sl={'A^]B>F& Uq p :n~8r? Z[np=UI:|n|V'l!ԐOK&k<}pߟ[9 ꀙ_feA0PirDl;TU2eJXXرnVZJn"q-FxG`֭֭L&>}zyy9^UUUSL޽>;iҤ'N`Lںu-K/=xի[ # *9~)|'LFEEeff`.:ֆ ҭ[~+;r4Zph z)oxrUJe)///--={V䶥.{e _& V„Ύ6xWh@@$7[N^/bذa&);;[Ū:#s)+۰a^}k. /f?~}y& !zm]wCt:oFd߅'\zϰ4oTWW?& B=nǠ[ ºv^{s͏ `|G4h7߼sNA^yݻ񲳳*j O>9hР9s|ӦM#>n`2'dHzwl>Ӿ K08uKL\.& vvK %")*E 7xf͘1{fY622n7] RZQQ/3>>x=+6S!s5C6W\\.\;SbŊ/.C$4j;wKnv)^`w"իnJ裏ZiI?%Š+*** պpnaѢE%BwA~?p`prqRJ *w͹3^lx C3 3dȐٳgw}'NV|=^ꫯ8MLL; qj7H2t`8逸vR$a(//9s&& ?>rZxNBSjN_hB)=~c=GLJ/6նFҸq$I2l6k4T=z_>STTt:??#G9r}]tfs*EJ@F@V=r?appd2>䓢TAAAwRVoOQvJJJX5M]]]xxxx8p-]hƌ)))~SFlذaÆ N]~CY/ CTWWשSPA}n޼l6N>ݯ_?oE)8.!!ɓ2LVc|vj ]LHrV(#7JNQ걫˄sξ%9W\\\aa ; ̸vZ]jp @d)5"otxݺu֭۲e˵^hUV]"ҧ{|ƍGG6l?ޫWJ~|Сk\8dȐ[j}/jNs&Mҥ˟HDDr2g+ҺumWt:;6p@e٨Çk.,buz@zO8qwIII}%aɋ-t4hÆ }rrr`ٲe˖-5kjAq'|2L)))WM{Fe]Y;˹;޸[ !-z=OrrE~l<-iӦ<^԰.ye߯QWbŊiӦaA;alo=nOJJܴr]oN۶m۶m5CZ%5!~pbYxIZu}O) ,K%=3}͞=[v*oW6oX^^riӦ4V\\vڎp5?DNQ6#z*eCzFι> Cw5hU .4i6gV>xsRg_pDC!j h9sM맭(55u~pL(ޝ9B!¹h2CS8s/2T<$<ٹWg&œJj%n<D5Ge(`e׻f :GhwhucLBo902 ["io;aAml=Tp KҬ1jVi:CVG\0 -U\5j7Q2 \'! F&Hj%7G䎼'cLB9*TJ2&-ޏw*Wv NSJw*B5cG)r M/LKN F 9UĞ|j TMd?C 2TVl"=]fCB_AѡފF6Nl>j>K8Uj 8xh<+辱u*=j&9 !<BoΑzhj1~e҈e *yiOv/! \s5?ӛorʚÇWTT\:pqvqZB CJłqsF!L;b+j3v` 9w_!;.aWR~,XfMnnڵkMv7~12!B3[^D.?%(wq )9Gvh;ۅM6 6066ꫯ޴iF!!!a0E-yӵ,!`Qg_V~^7 ^!g.)W7}=zhLzzz~~>B!0E-Y}% x^JN7P mbU/kxk uGL!gLzJlVT뻜*d"2D2&LѫzuM뵊uVB/b0DWZk{\訩wxQ) >sb+jm/'6ƺ #3:%0BD"///_jL&S(mDGDu;5@EݮVY q?2c 3۶m۴iK/:A.-Iuix@D (#kCo+R(<y>(((4 Q[L:5&&/>pvvo_Xp!TX,BHCԞfZx!jA3DĔkxEPz$梄HTSAs /Bx-w>ҭ\H SCfϞsd2<|) )(%Jv-`P*6exfB(M|W)m"eGZꘕQjC@iy@hJЪC<)`p'K =&Q'C%p7P}o9Dxا; Vp0HE*NV m_LX,G;N{_^,ɛ{Oƍ_O#F~aܹ銳 q9hq;yQRowlBk`Up IDATH@ tA2jl;6gP"B4`)999Bޒߟsm\L6^XSs&U{ôBQ I )2Uv8Ln˛ j=ھga?'瘷mnd,ynїeeɋ-z[.::/Vr{wm(gvR+9nJR<;7B!ls.@% ,K´J+7:&LյՠVl߳s) ~<)$ޠ~qj#6ϸxVG%c|Rdd5kZ-Z{D󱊍9%6G-neH)9c҆o!B(|w?a*Kfh- E镇kA(6ϼ6ex p)Q+>;c0DG1Ǝ{~ɷaa:Uڗyr93[ !Bȯ)A !a JD<"!Pǁȋ?8p޷ؠ'^64pz^!;0X# Hq;LNOKW$QaN VY.~!B~LeîB]]@`-4ݺ |4Gg/6?7Ѐ py f W+!Diob|cˌ{GhsS  BryA@ՊZs{Ϲ> g}|AGBPB`dߘ/L e_P33"5f'NEoO>$ Q71LBΔB!DU~<]=o|W{W+8J!#VZc^m tS_ۑsC"CUOJ,(Ijduu["BuUƄRpeL,wN}Zo!`f ہcHxdB>XVrRSxiqf+%KXei~BOKwe$J1 Tsn28\'LeTFc5vv>ôʀ͒ڌajJfw ެCgky{{KptJ$#A B!$c 2$JfVbL}[ }=0:C&oJ9[hzajN+)2TpFYBz$Q(}3S^ݱoh9RT8="9ů!B= R ICro]t%zE\R{v s۰ݗѨ !95W>;6%5v TaaaYYYǰ[ @,S"CfB!‚TrV1@#]m7dzdyWw,rEa a'͏LHiZ_u $ޠ~ӮN VuyQK,yva[ TUUyq y@)duybT B̔0'/ U+8!n>2ۀTPeoާV]"uw^AyH$o]Ѕ’(B]o~z!-RJ!$H) Bw-x<ҞS֎J}K[ȱ$+͠,Cޘ9kL簡8V}WX?v6 :wow!^oPc[ys e(!UcdB!cv% &+ߞ5H] cWޅ4 *@+J־t{ߟs+Wp^.-6$-0Y5R;̔0 _8UZ+ T  ! =12!Bk{7]!?fB_]El ;r %[d4<8=u-˒%Kt_ J!/@h]ER,ٚNJpùKk׮͛7?裡 zocv=1TU'ʊ@]ީ{Wŧ6lw…~0 A&IN&@wS9P`!]~VǴ #E`~sإhOݻƲ4 99Y] NT3KA@#By "eJ=QebtF؉v ;|^^^zz\.|QQGFF?p\MEd2]wSd0FJ eEȯfZϞ=q4 Q+ܹsVhRRR0СC JΧn* QwZh@^XhT%lvo U*bN(2v %EfmF dP< OCtVzePJ333;u } /H?ظds[Q% +tQٌ/kb:t\\j'N!CtrR^^r+"&&~{B&,o`Q"?ZUqqٳg;΁!jaZUhhQ0V  CtQ; Vt^@[Uv3\h4wuW+eъ/WZW|>&Ei:q:Xr7vxƏU2 :b8\59jtj17TY_$`-H-'L!B! $75Z5G%r 9ץJJg; uPah}PZ|z3Vi- 39<39ƾqOSfﻍ%0YݟflUȯ}qzRѣG`˖-!::+lw+2ɒZ;@$!Wέ||Bpl!B'39{<A MwWm2[X]) 'JYB;AA*@vvv<d uc(;[fs(IX V5O , ($AEqĉg뮻n-E[ԻPXST]eųb !|{"U@]>Ȓͧ @wA.ɉ3'\yDBENjL^$8pDj%I*VۮɈy`|@VJ)n0 Z,jCs̨1Ɣw@#)el VPD,WpB)ccG^;C/q\k|IXƷ 0$e$sH^ BU 0h%999B_cxds[lohRVXi{n>j62lW?298Z[Sa(HH>(!JSo*5)q!$""5:`pC:,6xrA!ck]PH"ߝ Q˻Fjw rWZ?:'/x3D 8dj-:Gr[{"!BҥoրW~^$`Ro s+d\V|0t*@tu-$<2:< QVdqxrN䜮ysIwtϖKOˏzD)PBhn4N+:D)3:ePl!BW 8V`rwR^0ٽ7l-I`?he4-1Zz/Hy_NT(.wja 2,CDFUFGB>яM쉃t~;;JjٹOՔ#t*294LJ7+&ѩdaAɱW~~%䜬>Zd:YX_U$ !~@P Â:G+%)-+B! rX*3;]EJ9jFgVQgu7kl6Ƈ{w -"%VA"2Ku.7Xp, Q)W+dC{ra57\8D^j-.[ \(d@(,*ۋiTULgО]Cz{^j{NW,29E`"5l@ Tp, UZ܂HkIG& 7#B?yHYNpE(sfB!tx] /2xXI.cu*YIi}km\* @4J^#7(:GjiqƟ(6ϕ[,|@|Qh:=B!LZ\Bj;NqA8 U L`Yyй ˡsS%@F&cwRVazb"bQev(k~cR)Xz<\ Uɹ0""Di]zW8+u%؝-)>Trm7UȔ+FLWj|܂DKIa !jV&EkHHbA!B/d$e$fWYe 2ZZ .@-g]n(Ԝ?Pz;_fkHLNF@2",,XUô*T+שd,ToVwYgsm6xcwyȋ$JwvP2LÀVnVF+(f[Hѥzu k .L %fnVrު29UXΖYWX]Q1.^hmk(HYN#P[]fȯ*#{%! KBcY%C^#BD(J I6`d =&˘=ΙT!Q=j 5v>!(&L5iDhN*jyLQ1uA=W*diV*NGd *XB ,A$|C_`/,pZVoH}@&B*ySM5A$MG5 1|HTOek(z`8Ww$Di}!B6P!]&*y+"X5 ċbq#JڈĎ> _ -XAlR\iH•rŋ X ^>0J+ոvAs, R !J;V`4+ujypyDru>'bf{u|lKj=ZjdU %$'/x8\oN 11@.x,pq(/%*QdYƒBuJp zuRA!B0 ޳%+gJ-&]B|J!d)dY)8䝼\Eojra#&O6MI|NQ e2WZ;y%Q8SQ!*؏UOZw)k2.6uLgu5;{s~s_E8,go֦2l:ˤZ\][|.*Y՚ig>/?|{zzq?2ktӳgt:}olӕt\)͖+t*5{Wjsx|uSk[ͤnjlϵso5۞ϬgWf;2 =d)JCCC\%U"Wק[[[S}ÂkWTFGGwڵnݺ%{hkk[)WdjӦHD+ё \, BLӭ7s0DQ499N| MLd2 *EDf\n ) v㎭[^9I(+aeT*!|j?>};V^=33\.WkMǘ8qoxr.z.6[SD-m6lgK'kSO~}ݷx̙'^e\Ѯ~OBh#ò[p9ofwwO?- h vvv˴6mܸq9nUm۶=zȑ#(قر㫯?>󹃷~͛4'NDQt|W?`-M6[X24tZ ŕ)}4ɓ\.)64Fqܹ Jlё ¼wxq+ -B @?~+ɬYbf  rԩk޽kttthh衇n`-Mo<̭zaJl^@[.-,<ӵZٳC2IDAT|_ 6[L@E?<)ׯoN`MznW155U*‚&&&8}뭷GGG<_{wj:33sϛL| &H7`tj*"hU*3g\|$Ͷ,a5E\_2 ~ZWh486WP~5k_58Nƴ|>X, ;ZTEQ^_-Nѣ>z]wZm_ȓ'Onٲżx}ٟ~_~lR`>d fa{%\`ff\.^ks{-mlMCE\n3HޞSGGޞN珌6mbtr/M 'yW6jmaYy\$ٺu zzzO:Gf Z#<222222255u7}=#lܹsΝrf KB @( -B ;&Ah4pB &++^+^bs0mn^@( -B @( -B @( -B tO<ܑCqk&Zy<{쉢믿.JQm޼yppP>RF}=zĉmmm~iKKp4%pe2 .Q7n `s-Є|ɹ׮]}v6ͩX,>|x޽[&@{mݶiӦ(#GH9h6/ӧSԡC{Fϟ={V8@8x_|EѮ]x\.7<cǤ!vQX, ro߿޽r0E/6+ -B @( -B @( -B @( -B @( -B o4ж IENDB`././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/limits_and_scaling_orientation.py0000644000000000000000000000272400000000000021136 0ustar00from openpyxl import Workbook from openpyxl.chart import ( ScatterChart, Reference, Series, ) wb = Workbook() ws = wb.active ws["A1"] = "Archimedean Spiral" ws.append(["T", "X", "Y"]) for i, t in enumerate(range(100)): ws.append([t / 16.0, "=$A${row}*COS($A${row})".format(row = i + 3), "=$A${row}*SIN($A${row})".format(row = i + 3)]) chart1 = ScatterChart() chart1.title = "Default Orientation" chart1.x_axis.title = 'x' chart1.y_axis.title = 'y' chart1.legend = None chart2 = ScatterChart() chart2.title = "Flip X" chart2.x_axis.title = 'x' chart2.y_axis.title = 'y' chart2.legend = None chart2.x_axis.scaling.orientation = "maxMin" chart2.y_axis.scaling.orientation = "minMax" chart3 = ScatterChart() chart3.title = "Flip Y" chart3.x_axis.title = 'x' chart3.y_axis.title = 'y' chart3.legend = None chart3.x_axis.scaling.orientation = "minMax" chart3.y_axis.scaling.orientation = "maxMin" chart4 = ScatterChart() chart4.title = "Flip Both" chart4.x_axis.title = 'x' chart4.y_axis.title = 'y' chart4.legend = None chart4.x_axis.scaling.orientation = "maxMin" chart4.y_axis.scaling.orientation = "maxMin" x = Reference(ws, min_col=2, min_row=2, max_row=102) y = Reference(ws, min_col=3, min_row=2, max_row=102) s = Series(y, xvalues=x) chart1.append(s) chart2.append(s) chart3.append(s) chart4.append(s) ws.add_chart(chart1, "D1") ws.add_chart(chart2, "J1") ws.add_chart(chart3, "D15") ws.add_chart(chart4, "J15") wb.save("orientation.xlsx") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/line.png0000644000000000000000000036502300000000000013767 0ustar00PNG  IHDR-nsRGB@IDATx`EƟ\@B# "`T@D__+ **vDRA)"RKJ$K%\6r9efgs;m%c>Kс K[ S;aH.VK10tQD^0==;wUW2N7g;' &&F]pFvmmW k.;D?"??5jrss|rz 酅O;muԉ*>|/vx{k@JJ RR1`Mtcr|.CpEE6f>381lhcܹXwZR߾};t邚5kGakiӦ6oaTTT4}WD( yX ۅQ :&97c$<5jϷÌm1{ Dĝ}A iO ?Ȉy7+xȿ]=a1Fu4??rd:ke| ={byRoPPMEM >uYgԫWOxyV>9]Mr)rIwvpplON־}2-y~wm׮l) N:>Y̖m5|bu׾G0zh6y ^}9Ylw<{5*шY]0*xu zm%=zbTm},SsL&=OQQV]G#p>h!Tr'HBB 3qt#6,hJ@vܩ]'nI#@6.iii8zɉ'hvezqӱcGl^l8p08?~fM`8wϟr'bӦ0l5/=yv%Aijh߭7ڵjw 9fgu""ZJ&D vϒŤ/?gNzYg<ܶm[‰ _V:eepZpu!##ɲ0Yiymxy~mhuzlN:Ė͛pj4fWD2nff|)G޴AYOְ @~kPqFiDhE .U:,QSNpVꦋxr<̝em ԩSGybOiCkL͛… 8j֊baw$NtIYv X~ٹk׮@ULd ?񉷐} '}G W߲c(!S4%!999^2y||}il10nܸ[SL|͵|Ӥ|O&{w A?u?U/9s?F#@ŬKO9mm_dx""PK3dyd3.=WL}s>?u%h0wD] ĖUg ɵI;>3]>xc$:1_x<-3aqul[oj4Bk}]*)[`D;smy~Բ[ac=K,*gc_7}[b[liwu}ڥl+~8We=I]eqZ#Z_T]GyhxϗO']q< $X&WWD`.w [Ķ-1oZwKmO=gЗ 35vvnCΜ%|op#[XQ뇣8o+8 "ŖzUN#$`"\;?W52uq-[v~'Z@d(J8-- > -4K,.=1),[?,<}{GqfSnI鶲-DYRʰڊH,ƕzss!GwlՅs겒IN"zԲ1;DYau&|W}e[u- _$8ؘ;xuSqlc,~ Mߍ&1,/P}%~Tr}o,lbI(D;d+ۢն(+|_ViwLuWh[>I"}~vϯS'|qs'' dg"N.#ͯ*n]Z> T.o ]j7EkYwm>G vCmLlcWC 23_1d2~n!6:6961o>W׬n~ƊΫ;};34ӭOABAHDPĮFqfgCE.o]zDxX[""]mr&O8BUi쇍mFM{Ïzj8oVf<*WNj8^@HSWs"vw;^ys>_̘oS֒D,)YL ib_w1|WO]:ץt 7#쿺Xu`צJH/9sjժ)/ǷkԨ|Y OS7FeysUES4aۋiypü.$*ʄǹcOVos;Vqj_6=`Ez?bo9 ٳKC*=Ř&k=Ex"N[d ޲~!;odm -+(,վWşOQ&Ȟvfu,}]G qߠA}2M)9lp%LêѸE$uܮO-S`aew!>ϯ + Ŷqz٬T?L^9l9;迺v[ۯ̫ +Mt .?o@C'v`kRZ/58$*|SVtko[ww}"oHq 2+|e f-f>R.<=r9=Qr>q9R}U:/#aQ?s'<"ONRE(}DߔAfl TDHV23r<#l8'_9y&¢|;uz[G_6+D!"t^G n 1 =ٖ}aKos̫ieϝ?rc/&v9y9&†m+K(\!r;7?HO䱗U:/#aQ/s'<"m")D+_^j>R9ݑAK4@4TtNj8^^PW;#AkV@%)Wu7˓]>Soɔ/X+8eEi"La+ayg#)񙃳/KbGQE>mU+pSiC=E_m.x",=|2 g^Z8+~.y-ʱ3oڊ:M-/M'qa3OG𑘶v:& jo0en~4kA,`m9sO}5˃'cǽwvEˇ1e:#݀V"u=ܱf|l1=k~QE檕l|7~K_v#K @T!Lr_:ajʀq(] e_a xbkd~w-do#Cqj~ۓ܍kJm~ʿއ3Rp{G`T7pi}tA|$ߍ-UW݇PCk,LJ8^>V7-`K޲c=+ An ͢`L<]JSGlSM:?I5[o:>׾1LP"#=n= iυc[h|X;oF`XVwe??`m{{JBsQ05wYY7BnлBЌ|:%Лي]qbb͟Z(w F32Fҷcxl]z^ɳܰ)`"iee.awa!&blxo8\s X7 m MORS͉b/kyao.*Ƈݳ/nۃ /'=DqNVP]xss6bt-F ?G[8&ӹ?Fx/ɀg}-Ŏ̯,/e1w~}XXn~#cl~{ BU_15׃:?;՗gG@yKe^ (XR[+7va;oo8kR t3 SB'4 `I|6Zd9e6b?3xWkfxe۩)]8)l}^noIGk) 2N~ZvB Q26`0Ǟbe 7?݅9=kmAL63z|->Z;F﹣P ǡ}`,0j%KL90eWZ04BzѸ3p ӰV^c`㜍}=?=d'6gf[pc}({СCpeJKGN(ԴWEV|4 F @he+\MHgEE_%-&F3줠:uKik>bZ Iȟ+ )Enb;錟$ߛKn//Y͸?Cgf"T,ؤŸJOAةn\61F~KcQǍ=n”4b*8qyɴZFh.O?Y9ȓO~GqD %crCh"<[&a~Ʉ66V6ab Gcjx7(tR~kԿ +3_3^f/ԆBL |bKaRSiqύ5C3 D"Pyi 8y ۇqas֬4%Ն]%݁N(04^]RG2a7Y~ˊM2gazME;}q&)nƚ6F0a :=7ʧ6O5%ְ(~UZJ;"|;&a +NTY_qL,碳NJnWJy ߱?nɷ>wlzVpK/}m3)H,lln{~DdK 2>{!c6ݥC.Ю]7j5=bvjxҺJ؁-Ca\:4rgkא>}Λ`ƕ<_{㣯}zBzz I`]j߅ڡ͵P NeلTb)[ΓNϽ3}cvӀ} !#bccq:sY\8ZD{$RPR-?zֱx-tG`#-:٤.h ˰bZu"Qq)[;1B#&4d7 i♨%$7_1y"FIڎF?C.w㤜TNǣbQwt fw% E>7 2gܻ?$a:=Qj}"qJ%.fkNrM; L|!XE]^阋ͳ_dڵb$,l"#[#ɇv05KlQ,k*;GNc9vڵk\^[-- $cɭ=`VsʪPNCN&Bzz7ϸņ×;ٸwG42_>{8dVas$V;H05?L(`Q:Nyv66oN{ }k\fZi - )Z y > 7ˊ}ۢAqRVU6{Z~*&qrbm!Cz0LS-o rԖQ0GGT~[Ě2 &'凭{TP)x醞X:*,&d_vٍ\#n{]x,⍪LI~z<LV0.y!L˶Q9,c rf" _Ğx:xERԟbbj_9#yk2bB#Ʃl%S%kF`枝)FEsm[Yɐ; 7wˆؖA'6$9#LC;㠤yȠ?vP DT::ݻf D%p5׼_> ,OY| GfwK Tw ե}yB]we&YbJL'E$)~&D"@J ߵc`4i㴐$BxJy²2nӭIRPGwA&FUB_|$7bӎ?h֟H\˩Y J #Fr),mc:|f^ ?:Lq+[wsC2.Q |oTR-m0(|}9A.=Hmi\I IYYLQ3y‘ҚRME9ŗX)ᓤ4ɌLD)Z_f>%)۽AR4|:\.eQRЀ&S>Sl4g$)PpݳDwEN2%VUO@SD+Þf()h:#";1Z1 ?$+lgHC$!*UL; CP`[oaCOo7vb 9e]i/eURдw6ށpX[*5,I Ϫ\9}+$XʂBP)疦,_ҙϜ .-eER0$FoJĒ;U>cx`E3'=uu$&64JfgRR~۟,Ci' $$ܕ5 $I#SLz}R(R˟;حZAZe}X2yd=V5vY lP5 .dIRsѿ\+6b2{WFQtȝd=s*4Ц#:)_Ɂ)WF)3;ϊ$sXӜ-yd=Va|ےg& {ƪ$# 5#IA/ZQ/IuW%;HLGتT!b[vu"@:zJ L$+pE=' bJL'E$)~&D"@PdT̋ HHo:5tw˸=ƞCI/<ϖ;ݟ:KM2ga I|$gC2җ$Ө9@5h|3.ķBOWt.kV$}c=O#)nF_H;slK]ڡ]nվ9jMp:N|*tgٓ$ EXƹ$`/xs#,ǻ!IA I,bZJx{u[|)%w7HuN3J0=RiiKyt#ITCfv/=Y=4N,͗L/$Oۥ;\`Y5Nn(VjKiL-Q݇?sIR7}H%MHML@vQ0"7Bq94q1iEG0U$)&߹IL$ӨK7-x궤`iMH;? y!痒nԜv=aNēT2$I2>YWQ DT>$)X)"@B൪֗(j!!bJL'E$)~&D"@ЗdŋhSU#־*%)X3={d0Ur#;t%ud P3v/oeR3'|*&)hEk1tt$=_+GsDƋx=-+jOR/cZJY4~WKRBB ;㾜 O$2W.$-YӖ<ޯ߱?]i@RL~Aw[ l"݇X9d3Y3W\8l=<3k|\nʔ)D8 Ko/&oӁ=!^"GoicTil֠c[&]SnOv! p6NHS9BNei9Hfu *9}ޱu6[Z'ڈU҄j#fN% #"[bܓPϫ;f]:uCQ=bfםZj=8v6sָe3`<=Kۮ9ҙ-k/]}Ctkw 9E) y0P\4S:=yP `><^{b n*..l)YK!IA+I,iicHT)V3/dY]$)pgLIRpOR0e@;dWƦH+򭰂CY3\ahR7 (4Je7ІeXv-:D)Gv/5Ѥ#[}#~@X,>zf]/3--b9%ro]kntE lj߹X&ىL#1-C˽'L]ܫrU=%e+vJ,`V'ڟV*dܕ 2HԵOYuR `x{DFFʟC&67bͿ B{ <K7`,f:<kG+^_f 48 ;Fb!O^S/g^4!ym*R<Ӡ ZEa\߉Y\m;"= J ^݀ &t`[ ypc[2 MkydK6hS Emr 8'$&ֶL1Uqkۆ3jLL@'ۣ">)l:n\ۇdܕwG٥aׯU-yO>/w|l2;,l=;&)K iٮ [ k0~L9؍Ivr6NXn+e3Fb Θ{,]u# v;͛q*713 &^uNFAN%IцUU0l6 AedyY___?õ;e \gL nOQ=Z#i[ PipIxAhYR?z-e]H C\RK:m|=lB_")(옆jYu v)[,=󭛰xzgoB`(ҖU'*KY@o/3Y%w ,2Ew!xL{>R! jȳ.&KObg/6JIRP!FZ-I <(ĭ|hMQ I-RoR'K RN~XRڼaKly\b?S3$Ei |y`gjا5C9%A C]wv[ugΡTK <{&pfVlu>y>Nr>k;ǯ_aW,W\~*eZIAKH2@w"''YGVc~6NT&cgO*] @ b2pS3Sq1Λq=V'cɭ=`VLAɝ=snkC Cҗ6jTx.ك5GRq^Jpnuy%i2eRqʛxܷrL}n"&=U~Wx'Yy3(I_J'?W> $OsfHi)/`qa O@IDAT]DgUH5wsG$pxZ y > 7S}bpnPIAu7HQMJmC2not̿|.7'3Fv?)l?+Ho\lzw%~K@Tc%LRqb5FN ͵#C:@OL=$$E ke,e(2_ w;RqnIp ?+m/puS)_2_-Ɖ(Ӻ/&ݳ榀L 48t'.vف?b '0ٸQi2A D#`%pOL[X}㘪gnW[򥨠Q DI@rϒ8\sAIzE D73~A^Ts3"؜SOE DhA@ǤCaѭ|< dWO<- "@ D Ump0ZJ@k,+)̖ED"@&`xiPn ~E6VV|65L)^'D"@@Y!Obr `0TGd 'X6/"@ 0d' B \**, D"@M(9#'D")'#DL$|V#1~Sb=-8%IA3Y$D"|7q%eBm;6WrZ D N8 +NزVwø'oC36  D"Oax_d]NP D" y0Ğfנ[9_nĖ$G DhO@|.ܯ+/) C jO,"@`m /B P"@Њ[yG:jfG.kGf5hU !D"@ 6m6-P<{=1MPmD"@ D@;?/Z1/AR*,"@  _} KEO[)Q"@ g& {(35l&G DT bigϞ lf3}Ev5~ i物4Ͷ)1՞KJ~ ׯפI:~LN3 62 ڏbJL'x#$$D[^Z3=KҥKѣG"@ ZS٫ZK^"IA"@ #`we]AK9}F|CM4 gr"@  ٭Z7J.lE[KKiaDQ"D"@#f}7;HW1{bWC@ Dz1?E:VL^:::9"@ D@baI.AG6fCuE65"@rŝl>P_ݕtWr"!D"@&`|uM[%x' h^C D ŴLdER l[ZK996{YwGcN"@І~%!zS!Nx"Y{܇kH+GjC"@` Gѥ8e!%:|%ddE6BQ'Χ("@ D@CX9]qNEpH0tR&ҋHU D"@4"\YbRBQ!Ո/!JGbv Fza+] T+@@3I+vx@FGb1=; ttj1L wG問5yS$x6f"&}u<_ Oۙ+#׽RMh/U4^QcY]v3,O=XڮuX?<?u1W&`̧K\/٢ D.i'>^ٲU$n$+[@#uDzl{cvm<Wan.HO_''dyQC_dQ+C4]ӏslbHL^j늏IXy;ߒm\i X+ڕ !0aWL#ĠEi!lI,s_{RסH`ܒB nPH Acԓ㉾Mjg*H*q9] cENL%s]2e}zqHWM{WηhЫ&ĠX^LKN2Ca}v!9cD֊r0_~U?O'Ж}xW '}zw:!ҎR> JaTstkV5 @WS#CSF/_FP$}v7>USW7|0N-]\~Y3JޮSKUw]H_dC;_=lmi9_e7nἽ<>j5Uh[OUXg11,_/Sq"PMlxy> hc`f.wZvugeUq|yiq+DwC-x1aY)m*clk)/^U@Ɉkre^.ZjZ~rNlv KCvk6Pnc0z_ <{x9oWWg<1mS̞𘀃^ ,_oĵA6 K윲a)T٥k7bumrx8Hg_cg;c7f ,z_|KvQ C*)늳KyJ]>ғS鐊iY%"Ph*fUMfЛ}4_UM؀[vMSeE͋k6\Mĝy׭ɷSx\^2mb5t2.\W]d"@J Ēr<- |rG@{AJ e`bd}Y}yZB-zo<soS]03p}[VG3N&͎P7D<7&7hȃywx>7g{6?qVuG6 _CQNNP1(_\fEV "X̟md&`ZiTH[jh̦ie 8u<{X,Xf']fj\ f5uKs1sx~8ȮLx#??868:>)kM~zz-وg3pO`~[qG1˰0+Q$D@E@wIm^~=x i$UɈd#JY5"P7#vaRNGًўٰ14kuJLo4!(< M[h@\\ك[N:_/?22>a !`@F&j0Dux&Ű(&JZ ]B$+˞~"@C$) %"@$)X1\* D!`/LFqkeJ Do ($b!4=şZ]ku݁0"@<j"1Y#y=4&6y)l:kxxdQ"@@ 36)B9nWKT`4 DJH@qGWBAn Y'Cbl ]iJD D7’ l}0f;Z7 Z DT6Agsc3 #ޕ "@ 2QFM oعp 9,[xEV=зn#D"P ϛƣ&z,5m[Ah,'D"ٜxW|m]%&uZU]qα0߶T7y'jRO1"׆qz{6~T"@@ yڹ+]$eaɸfY}셣~LJ}$ 5"@*/)h;ONKh=Z&-\]QQ 'E"@[HR ,_>},&"S2Q{!oʓV0 Dw ٛV3#طovEr^5-`5qkUqBѰȱhfKj8 D pq7P"ٚ&s5p3OGC~p!;7]tGx7}+weP? F %DTb IAc5gKJ^)sȳ/ vH`4aac#Lff%5"@@1qIRp(|OEjW&޲BX{esS  D ؜'1eH35U_ zϊ,"@Є]ˆNxqc0D|Lפ"2B D Lz{$0['iB D@KVI!Ÿxr4Emz« DA+~‚Lz3Rc DMX%$KdA:"r"G DhDK?u`l-cI"zY!"@Vl^5$x9"@ DT~IcG D @QNKݓaj0,[ָ:}@@$v+E~$?x#7* I+o;gnD.EHt 옉>o_h y @ʊ'PRRSy~?ZaSU|T D@E%U7~,q$D#qdv탡S_aߠx2t ex;=9` ={L?b[?~Og,Y"c8u$ٯ5jcǎ3 H k l3{ m:Edq]V3߆?пGs pgqKqiR;N~F@ܜz  \+pf@&4Ǐ?WH 򢆼3Xx“RmD;-._W6+³a8#:jqlY Սz!gKMMERR> xW,y˱dg-^4"pČfbۼj3<&.ƢTs7oX lVݮƖ7 G)Oz~A?c=땫bg!Poa!3{fg/w-k9p\$ EEPWEH$D-Z?gvfgvg3BUl tǕx=#'ޛOMR!=;9IRB;]Pѝ7ԥ#'Z& 49& *x<1 IQ?+L '71HI*2c7|iҡz.$VuLo"/`L4$"c!|@ZfnDQ/7Z*.P!5+A:nRvpw{]?4*,Fp!L\PL$!tc.!;7dѾ 4d`,*Ȗ5!i1?OsE*~!z9y$U~.nHv@Ⱦ<KM ޽ִ\ $n6! hJ(3Ҽ9p2YIHҦNɼ-2 OIq0cUDM VX#&w34z Y?MĄuܥqZV"-ꊧTJUg,N {~';&:]D %nğ5ʑ<˽^5tz7(H9Ƞp-_2Ab%p9bV__3GȤ]^br)r;^Άcpvi5$;;;{E/_wzxI;NNDj-[P x;'VeÞz ifAl̊@m!`dR0?V|ܨmOO‹ !Kq.eZ[kwBxy^q4(hΌ%A/.^I C M{%!i}yidJ!홓yJRFBոÎ-hUed#ϭEЫۀE3˂CÎ8܊?fs <3&*z17'']Z./уTTh~霺6H"n :.AV#&t^VA栄FA '3bC]&乤._M$(q6( Ymd5n͛t5|+!P쉤?d-lvT=0vy}=xH5shYB:X -|>psm߬5gDK˱cWkJȜI-rȲݠ)/Vj`49Bk `%A ;ӂXSq QQZ=,}9OQZQ ^5DՍnFWӨ""bϱklĦp0:}gNaxst7բ +qX5f?c/:FM%6%MBJ`Z.b}5"Ƒ4&k*:y4Dfi+`qUG~ l!4{wP[ Bazq`;xA.Ĵ'C -!5w{iմ?mCVI҇rBuZR⩧/j"稴f7G+ĩ=QTLM2LgEήc4Su'OOOU,XskrUQ眼,\nmQS0skgFVpK]Ly})( aB!e/ƘH~¸M,wͭMs&9݃ ך5t6*d7oL ̍ =ͩɠIKF=*t/Չ]k.V9PϳLbٛM%z B[|nW9.krs2ٽ~L H}㠶w0sy0Qx"1:n^-DXsDy7l>mXlO¯:*cԓ>X7w~]Q?_'ԌZߒ + +5ASomϷ8Ɔ c){@MT Xkᖬi%f>o T{/,_Db4/B`گrCI:F",V\*!xu+x__wM9joel]T:A;q#4hOePe"+' YZ 1Q[Vi6{06)hۦ~seVb>NKW2t)kZ&sWNxlwV@M &x]hZ+V@C no99ztѻO KfyKƉ ۳,C!,J*a{8Ca:":U4?EmEƮ. \5M:cDy8)a1AR)Tw֗lmisRU)Ka=JlǪD;<$cJF&Úp:!$xUi),ߨ*`>oZq: q#F&ryvD ^|BTq'5̥o=)-G@h nZvz $ ʔhcDRF"7w@ i4 i/J}ME(_FD8Qp.M6X~BCX:n޴|%K&`1&3q_q]Bo/+ &% .l_.#u}n.72/!FOŤ%*6~mFQ';, aφpt\RɓM_:z_ȣ\>M.+' C6ב\ZBd,D63'nbR2^I;;JyL8RЛ'dHvbl5E@ګ^%mϷgEk\5t4U5vZ_J$(-UHP"$XPy^09'P QΐP|j5Qn8z-%oQw \xꮋ8Jt tkW't/R%&f훬)8(k+.UyҨeVK!խsth0Ik}mTe!F7p; jM+j]SPo6;*SMSOeRV 'ӡ^=;&`W}P3ŧFh)|B\8䎤G_)WtqU54za!~r/򦼄P y,SJ}(:~+ WQk0.zM Wה($ŭ_1זLJS'B@Cx2.:xjW;&oV]@x?.~Zp$&XI~X?숳ʭc<3Mg8vL;CVġ.Vr_n ]ܦЛʺ;KBh7Y|A| M,8f\>=d]N5 ӆޥUEZ ŝ5΢W˳rpCZs.d s͛++dbq_vr#έv T*4Y?tN]^~_/ۤ/|7\_/R0_lqEĵ9s^Wʱ}>2;ya]\+Vز9Io: jG7K#';鈥ڝ޼9oaT]ӛtq A7_ nچ-G}A GʽnteeJK~rOKH7{x4<l&|)DzYB^1˚u KҞ뾦Y>A9]y'ӳ z4z}I¨# 8 \z \m}Mzȡ!+^&aar¨ |Mķ^n$`*=N b:13 |dwgm6nfg}?# X~6ox.>RƦe"Ds>5?bgX }8-zP[e"ü:@xvٕ!fX3|R; ߞzEYR W3͝ U L z;o vEuYDA<}քs ò{;&WlY+W4ipn-:#4ļ+X /7E`mFJ_Ц]xx8M.`]zM^X!xT}*OEL%m@"{Ny4xM(wH,sղCvg|΢m8wSC/&S޶oRT4 ; %W^BԄ} ^]yGĈmЄVQxҩݰn]7z9ӦAI-T4w[`X 0,Z' u4l%Y-~A/J1r,y eǷ#kLޏ/^ᴰ4wj9d#kfdfdRF| SJ# #Z gu"9nCM|_h\H2U?t}j(dn+\W kͳy W`8IN1iծZYXb޷, ' J$$K)hzlKf&!Ps҈y7c'B1[=xQ}BஎR|K7MJ[ShРT-ҭ'{Qb΍kB*}pwLfh})N,r4= F4_m~AͣޫӦ^TDv9e4lG=q̹cNWeb/VJyWq4dNk|؆sp=CbQLUdΊe_w\yowBm[ʞмt/n˓]H.wXt tBV|-bdRP+wNIIt|޻ =IZ=r(Mi4,u衛=!(DU7h¾鯝V<99S n:{ cbaK*4:Ҩ^S($%)X,{%\EC’}H& ydf ͧܬDY(lI s,ؕ\\N6Qs_K&Wsw)S$`<݇bXtJt(k{BBxSؕ^tK9Ђ)72aEf.lrii nMѓBG_^͏pzakZRDͷ#ZB2N57mO]l pÌ+k50py(Ѫ3=P< y]w)]J(mYIAǾEGZXW޳amҧ6W'DEP;ϐS<RmGl qxu-V̌H-pD&4Jg: +D!BaB48/͝aAk͚`j:v\@o7oeBu>=zIޱͫ[說psWh`ru!>pËbԙ$L-a"ixEk;\vwû[ۚJ`c;\i5>:S律j$6q0 f#44[HB}@qsdk# ̘Yxp=v!o IAw:͢u')a ނ0K E/~AJK^ 2`]ld_BI`?Ec^mgUA3R yt^|(oAԋf&bZ0}= if*Z{1/+\UԋBބc%M?hFV\1]S·C;|'W,тBX=N Q^'4.D]1<0&4]3dHđE+[U~_݊A sƾk³^N0+LzDMFC#}':XhRlnx4FzA!HXoPuK3#gP,寶զ02)L^5u}jJ[Cfwd]!v+^v2;K՗SiCH8,R_1'#Y'ByXXxHB^azDk\yD"̹ S.MEgW/G^բYF<MIGK,{z5Ù63B[Ŀkum j\Iɀvxؑܪ2ݑlDnÑ!xc?] ' T":W[ˎ 0$S I < N \Bi9 5Yo. IAwi7q@<쓫(]͵r2'{n Zk vC .og'L TUV5aܮn/2+j(H |iI `uM͢:ӗ'qm|xOk8t3=-g1}+t×Z"G eO`LӉٗ 02cB !lxo3bZ`t2@8~@U02)ﮈ]]Ue!_'49oQҹbЮdҖw%#ӻ 8t^ȿg:g[ xX^  Bتn;ʢsՈP}&XeT@C~o)v3Tc?~ɿT@o@ h!ꏁX¡m,;&y;q讍c`H@?y]꽧~_/zTy*7/_pB,]Gn=vڐI**CvW)kۦhlnoɘWt7'QFS {o:UL%֯O!Jl;bҌ1$<<\LJJB\\03&`{?*o0KVv:C%Vi[,:O-lk]zU(F<ؤ`(a ?ʷQ lg̮;ƣ>7%[zb7D9ʕ9e4,Vp[v>/UK2m9ޢŨ³Q濈0 98-t03<]'^dtV{-{4:QGcø~+Xԫ;[ؤj-rTmز!FK~SO&A6eL z+>tWܡq%uW=ru`$ e n+{һZ]܌'-q7? ;2v9>k{ZD6r[88`Mg-LH'DEnz:;ՐIB,#|@& uZGPPts777.H;4K,:~^0ɦ?2os oZXd ͇itN3{41 ]?C G-m:',4rY,9[0WY6&>SX ~L ǜYE{x zւn=H*MG`_&j-XڒVBViW'ƮKڵEw+ix:.akZRoG;dkno 1?`!Wk&aQFvLw?O{Ŀxe^W}c~ OIW7}W's}mȤ`Hj'z.zjLPAn`& z/l*\$aQ~?Fo <>00l6BCC6sw9XU;_7r!Sp,<~(v!NОz٭Vu/0kj- +e%A``vw"+YI_ExfuUM'lûP|goq%颗g?ܠUX‰O528 3 ^A. nX)Kj3zP2uq?~r9bdc-7('ꈽ0 g)2j2/C8EF ~ٍ]9_yjO?uKmOY[?%&.X8r-1TQ5NߥK䉾cWc"yz̦}ƆUxx嗋־K?SOig"j_ EL 0P##C WWCZ<'ռ&::ZJ8tkEy2ħPI_"H.?W˻C3=ߏ_}!\ha؞`L 0w" \u&=% Oh픁dW;7Dњԥ_&`L& b> ŋ;]_.{;Por2&`% @Jcp@$g 5ܼs5i\dه 0&m02)NCThٷI*CUR=`L 0+!_pUT|Hx^^m[gg)q}'j-Pm`VN0)Mɼ§MqVÀxfv+y\=&(6)X6Nf6[wwiv4rY,9V8|mkduࢼkwl{n˶rW(?SO;-'`L ^jddj,@+lp㔼ȀsFGGK*Z2*!MfRtdёNדfcF&\~˅:$$SvL 0&J% [tTtP)ISJvVTjmaL 0ZI0)X+o7 0&JM cL 0&`!lRB +GJK᫨5jNIiK`L ȋo"'ة U G;Rmm0~ RƎ 0&@P^/oU7f߂1`ҳhYv6.v ݀HFo eM4a,*\ ݵ0&@Z*CLr7P8NC C ⅈc;χMε5E`m088T|eBBT\ky&h;7 k,V's1 Uti [ HYm5rFC/g%E IwD8_`]iSF *T9bnMKBLw]޺l\yl c㉭ymyFq?Y@pv"cP";SJBѲ;2M[2E1рVHs rҢZU-֛\=-rdl޶,Er=rD@N6}65j5dHsolzRLw۷b"gAݧO깩\M +T7F( ތ Ѥ[$ ;E,sqRiikט 0&l|Ǟ8&)Ǎv==4DԓLdXi5Z6߱ 0&j8G(<3=vh.Ȩ5eL 0&@ޭF8!.~ }SӠT8A7`L 0&`AF&eY#iҐR[(Ί 0&L@<ZYE6RK^{-݉UҔW[mfʩʆlR|}csχg;mG6)X9~It tt]jVчE T&?̈́(cw8?GM,Ue۝Ǣjk2i(O㵰WlPFM1j8Pݿcnx=dP(<O*iCk~*`@M S"<_w ormIX}zxM!~#6Yg{R΄/6Qά){T6zJRݮ¯$nGFau3۰eO3N15&y*hm II0`hurrj$ck˶Jskg$}j?/c&ΆyTiMGעSˑ8Bf$w[7WNhǸw[nT&"oe1hf!7rpw铸|'z/џcUAIAQH~f2]R6u4}[zd{hVM*S Z ;[x-81j _ U}JraR0p,0̞_~v-kuw;φ6S+#i4#Aމ@má$Ȇ˰p'OIO[ !k[?@vE`}w½+ۧZ/ᴤP(\mIA'y4Ó5O9ܴmmUo{G[F7mlLtǝLmx虆~6}dXLU>m&F[ykWyX[;;?,Ǡ^?wlbNUao,WCi[hS)VE+SNzœBgœh!m.<\N24g*Au-4tؚ 6! ֆ҃nKN؈ax=RW32vG.fGdlNs֖4XR} qZ<ٕ~9v^ӦI?yOvu MקIG$,1][/h[30>;cbZ_Wx]j bi4uׅy5ϋ׺uE+J9dWɮ\A_1+AJ}>|lիW56l;tL%:hJGbA3)(rs FW+CZ-Bd>j М? ~'i/3e ?@klrE4 Ah 4w6 Bz`馉R_stC .a~O՜!M2L΃@3)8urOEH1apsJ\v47} y> )23۔ur<- 0)XssWFggLyf*-\$g*HQ,I.Ĵ^hXVMw6ҷesEϲ˱p_LSz`CL4.'C qUVͯ>1 kO6poVЉO[!d:Rhٱt ^i!; DWD9G#kŦĢtuYp4}<v&9k! n@z컝$=-{$m6C&sÐj3_5 ȷ>{ {vixw^1Z27]Vw(C=x(̥k/ wowQThvFNh[ti]ƗL52&P {" #Z֍ IulXsJhT$N*I '>L{aSAëJN 9hNRL㯦/ayXupz3یcYP c՞_bU9{PkW}FJ[ff<KϟCѣФY{r֩ڍݺ욲ձ%PӃT6Zʰ6K^iM 'ǟC!2_<>)VO71?V9A1%rr5榉+*g" YԸ~_H{KJ0&P{"^L$ޢ:e0;7zs,g?044 h#H&8S~r'O4zq$4 _'ȎOA2-fW8ӔU###vΨ0> T!_WXdў){/_b-[&f%q8v4iR--i׮ݻTobxM̑%k៫6lVˀS3-CAaF Ea_0\W;c Im AZ]Ϧu~eb̿Lv6 aN`L 0&P}BYnO,#n"!+ ^hظ+%1&KE3\uUp#BPt*:VT`2&>&a)|͏jkfV_$&`-tFC/1AAFSI8Ć/WU41L 0&BgR0v2./6 Pd0ȍL)% P. 0&@'`dR0ϵ}|0y<S) 0&@502)(W2;[๗zJոHJ 1&`# &ϥa|]CZB~R*ŹnΉ 0&)~ՙlAs{bSΰ Hmz5*)Y1&`"n]%F}2tȂRBQnN* '`L 0 P:y e2h4U:6`LRY@~r>L 0&LP޽۔?1&5N."IAk\&2֤ի ݘqAAr*k33Gk|NIIIo)`L %`dR./ 9ih/ =fL 0&@Y ̏=7J$ذ_0&`'pN9? 2W7xAlr2sضQsJ&`M q] R<,6.`L :9JAH KF.я] `L&EƚF}3|KdGn[LΏ 0&]M@3)(Qȸ˗/r|?䕠VՀL 0&,M@.L KZNȋ˷Ҡʸ 1&`"``RWva!K<;ԮH-acL 0&,AȤzx2rհst<7c-Q`L 02) {eФ%#^یIaL 0&`i+ pfL 0&,AM Z"`LIA #ewUp9 !tq(5dL 0&NȤ]Xt{t\ooT9&`L 0&P*jW\b觳۫2aN0)q9fL 0&@ V#g4r}Eʒ!C4ډ˞dL 0&HȤ$c?cE\„AE|`L Tޤܑlx '!H<d`L 0Л&Kq1@#sk m΅ 0&Лv A7_ mΤFHw+bL 0&,F@~ +Fy2t~ tqO_.p+3f{4̎ 0&*Hϖapj/w9 Bq6L 0&`dRPJG ;C4$%`L 0&`a%L ]̱cʝ'p-SKeieNLMs/3 =i oT{nӵ-Lʉ聁s` 03S fz'BggVZk׮ATl( VZ? <lWg[wKgL 0ZEȤ ux rESKXw9c8ժ&sc`L ,IjOIz"N+`L 0Лe:d0xy/`L 0&`!zqp)0}rnB8&`LޤRd#L &v@xoQ>cL 0&*Cy-(Ⱥѵەɗ2&`fTel6Ê`L X ɗ3af e$ 1#NeM)LJe/?x}u-3)h[ӿ݉y3*9X$ t4W捸i3<9'/Em,Kdk!*}> EM ֮ɭ)% Oά ;It_{KaR~uTB"JPe*ù,[ccR22d@U*$oBSnum.o=Ǿ<,D3okZEK,{*}>^ *L@S,,?C'NbbfPd!ktڵ ^GnoNtфLZf@ßLȅKycIT̆ a7;Q7RQ?'h|KRcW+oǬE5IՇkOԈ5^]S}.—T?w!IdB>vҁ0Ekڄqb6AaekA4G+\^өBvv~+yKxz-ývzAs=~:ɨ_w'y>gL cKK.i.Y3f /k&>/~h&K,Ѱc 4'*ХfҺ= ɚ\ 5>+KȕDJs{:Y͓] }G[q3-Mא/9UMD8M(¥l(փ6>kCB/C$][/dfg"ϮK5"HwmPNe.:Ϡm'Н$ E~)n99E\ >z=2KÄy?{Eх\CB C *R)*HW vJD 4Б!)Jr)]. iw lvvvʛo̼ykK|c]"##͛7&k>1x~tt ti=;c)UPHA1xxOHLtQQbQ#`|zB% 8#{i$y<wƀ.!&u:/cQ+tغ㏷HۺCTC/@'%bڋ[.B݆_/bڜ@!Qa{$`ӓx[g>3b{l6.1cHsNdE◗Zi()Xt.͕t .6R@XRcQ>h*=ߺt-Ѽ)C0/%4\h0CMvqA? 9|è<#`Q :q!IS}:sGmP}˕Kf=x=EY8~!^Z-w8~L>X;uAZTA+11PTB "J1]?z֊(y/@U3ĈSCi,fJѧ)M*z:v!p囹?bCF7[J/¯T5k"668R|bQ>mEk6M&o٧(IJ5>Kʪ&nhT{=tC}XRy>jzȸ~8,14F<2xӡpɸ{6}Xm#3e?xٓmmQqad][+ xOƠvp`,oݦQH<}NJ$b[ԞDn·$XVxb1$hzh\\^!EÖnHᚩgkpfryKD2#b>KMg# [zGM.ҥxcH^Saj[|> x<"1'KqX4B=uqG]";uHs?.硃z^k+ڛ;SA0qWrXu}E-fis0l0xX,vQ^ks6j-YUjm !ZhY[EDG3QUs4~Aϫ{sx7XuƄ\$u1-si3G1˖lrtD}ly|\6hry++xoկDŽsd(W',' iJ2IPϣ{x`J?S>fKW"+T܉Wx,~Jm5  S0l n@R4~]<;mV﫭Erq|I1ߞ3w> ɯc)\Tѱ\M09 16"Kn2>KR#PR ۸&XaG]=Vt8ujuhE\Wh;'OTE丶81U`D73uRJWΙ%7TXrF&^hi85m?tfmMAb=}֢ eCgXf}ibp1?9JfqZWfk˚L"o+rư*9cGؓӪ+f'I-4R0I0LKG@K)oWGvзw"[ӚһHd1*MD{e{R' B{7]ոۖ衞T2Ovrp6@U0s 6lXw٢̿tɥc~'l4)MʼX(8=ũJS=Kxf>^7Q_+)x;9?̝.u{`$h^oIhF=ӵ[oxJMFɶ`ʺd%I ך ӋMys c[ƬӧapX6z,z5餳׮zOYT9~>47#`- Oq=RP$!))vVf TLe|on2g&؝mF gͭ>SWT)\ Wnϧ;s5+}RɛT(cYUۥrfl.+ԅSpsb35{ukF4`E@^kM}FӋM%y]0>V3\}s,Œ>'`G<ERJQ mc+~ oQOA _!G\.8:u %,8:LmФHAR28z[4ڡ|Wp4װꉗS=Ti&MifMZJ$T&' ^AQ,بJ, fa4ODEE̙3>|x H4[6d 6֭gvҳ L4)ss<3CA@L4QN28;spG-bEm5(_̢zdūҫb.s<~[_rQ(;"1~f G#p jA)Gcxau@IDAT]Lk^ǂ{}x-&(B)<#F899yըǖUN)X UMuqEcO>c|pMQ!- @ xo`w65BBBjԨGGB!p8^*N)X!0k$Yg941squ. y?nAǑ~ȸ^PVc;88X̜ooo4k֬0q8GRf$ }NL5ܯ>>To=عy>ل's8G-XO~^4/Y)вfA54PCW/Hty:1'N?ۦ^j 3G#p]zTtB $/*g 9% 7Q0: U%˂'@BZZ_ 7p8@iBhM=+ARhqW#k Ǖ*;l> tx2G#iOTyYrdK-+2U6$)1^#p8@zv,O@*O RRĪ51=G#pptH5D )^(6d!Qt:|j@ͫp8 qFBmi[Gwh 8mh7R_*Tȑ̎2 ps}M1 tw#Pd^OQ(A)'s%8Kn>A<3 )蜀ld/*0e\.5TdG#(Kd{*J rq^BYTlR!79M)~|e$GtRµך"Uk99qdjnK2GvH- !0^r, 6| ɩ1/#BL"v opJز;#`uP 22J*x |QJKG9!g<w$diSI s?eѓN`ۆ֠Z~:e7ZwE4-N!.&ȫSv互G#A@K)4"SHCB9o?ke*:"hkx=Вv+[j@Vl&Y4B 9-W#!ڿmkY.䝪Efk :,An`GAt8G#P=K0JA$yHLAF.HOÚpsҟJ^V$yyJIdtzY{m&4=I#, E卻S)XFf~pRUs+ '٨!/7"){xqk.j#A@65)^twB3Iό!oƜ&G#PУI dӏD~*S~5]ӖF Rr4KZ|d2:*NQ{Zo'@У<7 fJ\/(.TD"ENFM:R5S}k<-ۦR3]`XÐ'NKLmC<X!%ZY c@)N& ŊHe ^}"Bt= bf4u=U)ū)ֆ䔣. REćc `T[J qY?cХQ8ZJ*(1脫`~ /M϶̆p`)cm!3[I/&w/!\T#"N5ܫ0kES V,bk(cyтA& AG,O'.W`wOЛ@PGRs>_NɅġ0%1_|MLAbet h׀>Fe zI8 %|_8V|8`%oRH|-XX"~RPu+$IypIj%{! hCGhWu:&%: d,I 3)UyxXC{LNg;IF%l{E <̪>`t-s. 1'5#YFn^~`Ovkx_,&nV)5P$ܜ<{_f+˕ey cO~^B:N/\2 E'uUӶ7һS?xpSC)>f7p`\ z*ދL@ATk)#@*elaC6tU31,t[T^{dl/#;n22I yq L>Qۭn!BY{W5SK\kbxHޱ5H\jxm⊢Rleriou.s6 Puw b˅hIyꀀ.=Y|\ml W 'ӷF`X,?^5 P ?dO|&D)8V^#5a/J~̷uû0#l`m;Q5̞iu yZŚ͔*Qf "/>O"'CŌx:$6Hy R\5YVy[ uS x62ʡttF r R 2J4ljkPOV=兗nl[rI(!s3uhq۪M`#7G;'8; vv5`O6]ͦ4pzdgYfeVA#% J{vU)҂˗OG?:;S5iwCoB0k RfTrEv̰Y?I}U󫦝u'bz{goS-l[`3"-[  ex#\A[#8>KVadrJ {c{+kЈiLF [G+~+?GQSsdtCYհs&73k Zfk毝ѺXekzi~m$l"| ]4jFy4fgi"8`mяrpidt/>36ׁSD:,rY5ͣ>L2 )YreS\>:d! t2JAI^4z+Iz]BA5 dKI`f9B_Q+ޞӰaGx<9o<8mBj+5*fSUݓTuz2%vԆj:{b[Y+hie/ֵ*gSv4E.Gvj˦%?G.idJd cՔiRyWq'Azŵբ̥p" Gʷ*N?k?sJSȪq T3 l, -_hf@^W-iZey^?:+K=戆fSȮކ+ IUkdYa/*|>ZՁG$ZJNV:<( ,V܊d1kOڰ<~^T>G#0e;uq/㮘ְ%Q`dhuE)ށ'NtN+ۿѱ<pkp˦5]Xڷ!قVO`+ zi}a9>sTO|7Lk[`|}?*U 4Uα467`,t-5û'* m͗(_1hnFFFa |9` f9f%# [fSG.~?coV{~UpJD9`QxF`nDdժ3%ա3x.%nP$ %eF+ךt~.?I&l:Y! ڗkأmy6%4eK_}S=JA<wb`R0!sD,6;#ߨt{8\v)uҽSt<F!K#jrJa.3URD8m ڞܼɦ]k, F0v6 Op)WS_[zr2B E1RUV*N G"L1%擢?R@H;ak%5[\}_-ִ7]!1=u<;bؽBv^_ѸBrpJTE)*V"$=3wMi6I*\ =`=%<:P֮*mem(T|<O)kȶ1Yu}񄽃xxq,/SO>'g/]A˓1Yu,8.:7"O@TJǩR|{ѭ<7`Yd_c1Z}_ XU|SW-W܃}=OFUsjFn.V܌:^$oK]]6m-Vtv6C%3)`fլ~frJ%;P~JNF ^о}Afp8fС$# p3RiC>b;U䙩nyƐGt([[aӰ#㒊\,[g2RWP|=h+LLHYbAeH'pAS]n_wYI+9y~O+p&%k(Dvx4c-U] G M*?qⅴGx:Mu8:j#D@(ms ?3|>e<`;el|f~zdey#4Gp{ߞka,R|WS9qwvhcMbŜWЈWWjZei^Q!%;#E߼5Mo|}T}LQiy]1zWO^ӽ,q MϮnNꥄBKp/3l"-or8 SQ ^Ki:-'}Z`kE [y$,BҾŔ ~ρ7ӑd=fc%&WT'm`2a:FW/bN6pmIoƹtxZp? _"^BV5)\z.:a$|X8}t2W~VG`=g ^ ԋ`+}0hz wWbl=MZJA΋W>eS`jN:YNYa'Ag'(ңq1zDf3Sbv N)&g-n .0s?x2E4vmkzCxqYoSHRI{zu \/jT¢DS":dcpN+9zyw4m20 n͛?mj D8ΘڃCeX:ٗ42l񌯟[4"8onZCקm F|i{Ά1Fh_oy3Zz6.kd@ʸ(yDN.̞Cp'*IkE En;[y'Y^uZHճ97Q7_L߃ tdAй3HLAM֐|FGɦ=T;?9SVBݝn Q')qh}`ɄaʮͿaL+* x,?ۯX/V8-_Il=n-Żx)o5b8g(CtimkH,6eN G82jggi/EDisUDz928q{g5 PGU> 5gg#*`\ǫi;$GCG;\j>e.ܧ}Rv0[Bf`P_r2I5}ۍ)eS473-TFv>|{]a6T؝˽ѩF .A$~Q {`wLmdo@]%}a4B;sO.%l'A8"FVC7Ӧn>E}$ۡT`PF`Q.iRnE/Qjois1> }+"_k:۶%G܀p"I\y MҨKLO|ڝ>dvk7 6R8ڰuU7Mf49v=@?ki AWşm[}ťF2y&D$0z13vczeо驤=\dfI}ACob2612re{ʚ:h{fP"]HTKys: ^ķKJπa}F ߢ`*9%h@'-mN%EZ?$殥m6)8:f zm|UШ /7C55Dkf ӴT9nFf'lsQڑ1n'`NG)c>KG)ȄeƆ_ ԂGQxrb]NxRq;W51wSڶ_yWeun,Qf㙧|3soIr0| cS*5wL6.;.8̅f|IԥN%ݲdA)x 7a,?6(2<2BhDHMө8o8נ?^GS,qIsrٷKfҽPY@ASFO j_Q/ɏ!**[I1-.g>kVЫ/a^Ev܍ʰakƗbB<ɒmq@R+6tfh|_P+0cZ`#j2ۆ)kF40:Y/,*U/!_neiĽ>4J6߷GZJAi1,,eAe]5{OL`VFF֯g٢}_Ö4 xPkN{֋;E{-=ޫNfVQhEWE)(qrGmw d>-_ϷǪL*W Q<婐ԃM1+ Ƥ=ߊSfM]:mrq R^^bzJ$0f[Ds*F)덯ٗxoS>{JLmZ]bYn,mnf{P-㖼iM9`lFF,ݳԗ ,P4~."FcS&o# 0_՛H𔻾粲?|boL/RZA-zissnF"~ g\cĻ{r΀rtz_r 7C{1v)K[0e(X|2~;& "$1O5ZIR0/ ~tVK^WvAW."g _ *9d07W4jWXKwY})N7'=@۴ָum>/uˤb S&o1ijp}`-ޥ5_)_@#ti/#ŞFٓb|ֵAx8٥Du D+xe*x#N?vz[4@)*~ЬY8|[5&.l ^b{wdU˺%K@|[ęE9O>œvJd*"]툀A-G#\\#Bޏ[q_(C+ooo4k֬T0E l^E(}r=T&YV_R $2yK_^#` K,gF̎Զ τO/LD? ŤS-Q, l@kbX7]p =(>>To=عy>Vs Lک5A6y!J8l0ːbQ~;jm%&\[(#\q"ri4ʕW粉i 4卞͐>xKTRh :WG1Z&vѩE,!uz $:AP mSaFAԋ36=&oy>;^7G#@SuꞶu"^N6_p!!F5I1=RҖv\qtvʖvyQ+(uivEd„^& \in8{|!zNu144oqSv&<+9shiK\ɐ Jt/ܕ`s#F'dkY5j KſϷ)-.G40%$旜$Hp(1rTEdA&5Qy__'g'3PmnTq?[ =NNIz1UZo?Zz7Tsվ;̢HjH^@t R ڦ",CN^ls;@b:WԌ+RRc'ș= HsKGAx#P0ʔ+#a~|EL4ЬS5iڴ6שbfy6<~|gaRxHw{H'a8ל7]mxcjtּ?# ӾB ]F7?}ri@oWlas|,<~jqE:W.!<Lk8:F\~܏CqiycaRvC?@ Tz6G&jHRpi6#]KfnA;JLAM֐<ce^XF,zzAq_ͼ_'Y?,KA4> AȂ)x6U*sE ;ؑ !>_+ϷJA;_ l) τO/LD? SQ, lZg'v7_#$G`Z65n-T%㕏J\tl0+ ))ļt#o}g$^ZZp8i 8Q~G݁aD7mףps՚&$p0+wSUU,P J"v8jQG徏c'Pźͻp ` V;-Ju&LĺS`w c/F^/ t!F5I1=|xYZ:ʖrCٲ %½؇41@V.[6bW)D#aohh(xBUC͚5.]p8:( OI&ɂ=lUۦ(0HÇבǦB4_O뻪3fٲHR MC-9l䡦mhG#PVH񊫘f*dy"& #h5WG#p8e,{LyG#`apJA { \G#pJAKƜRҟ#X=zyHH嬄 \}\tpJK3l#,Cl.I8Ih*FN~K0*Wb'!tNth[cledQ]ģ ƩqhIo a&{ t_◪y?~éd)Nq? àHB$ފ^ ӿꞇS VO@/Ǿ?uؽ`?-:(]1h~4X[%s_`MzIPl< 13tLʆC*pix>WΝœx™v6ZlHѯR1H=y ɝV ?x-y\0K@(c?ӖXA&KNlH'M#PH$q98ţ>s̵QF: F¥aR%oTf1WJ]GUCBx$/?v loѽ@IDATLʅd 6N W~עe; 4:6lÖoL.Xj}_/]Gpغj)~R& J2 xw9VRn κ~XeɆ;(kuM:ç<0 uzڵ`zy%I[W-3!JX3Rgz="X| 71ɷ=JwD(tw`Ķ||Bkw_HڑEFg ꊞ={k'QkG C,--_{A,R+٭EkgxLXt\GB@RЩ Ur CnSiD6RhU~,_FRq˩# . \{ggVd:rCXG0spvweru}&t?[TH4蛇kK#R⍁^vSa곰Rup8@#@T69wpf:W;<)5DYmc[p8@w3J|Wq`@6r$wcrM^9G#0LC)Wy`E }PC˩ y2G#pJRP9R ͗!+9prʳs8G zʇqv6\@ry1Sp8Gt[r(y G#N)X\*#FPֱr8%D@K)K'B$S2d)BJ)kiKX5(*HUIA MO^׷-›Q^ĺ*"vcO]mᣧa}d1]ʌmEM ]!'b rMHUzFrL4 kůg̵I˭ڈ {~ gif)wј1F"TmwiG9"0a©­KG/MWwp5*F8<}0a¶ J3u,[-EE 5ڴiSH.R3vmcDG:pNK) ?2wd!nM$5q!,H#ڗ5jRaec1Af8 t͵=åAlUa$[N;^4] fO@ڟp" ~xb;LX-YVunIm`X3UqW>X:KCz 1@R BD6v^r1[>E\XZEKkE$QZ]\㴥5b{E)h66|sF>ÿ>a+5p.Ro ݧ8 [lMjE>66عu#/wԽU#zz]\ hȳ82E@J3JAxA @{P{18)U++ЎNT}+_G|/bȾj,l%NRV|"g@̥XjM/@珃~ 9u,ybGj&oInIKY>J-`<b{D[<^3;KZPxp~`Z-]xr}8ØOc8GҏCq[kh93㨼jTԓ4HI3.{@G55SHFSbbFkì B2_GHg=[ O]% д<|,f}gMޮoXUs&gglجPO=ފn_?XNSrfj=_>?)CQ;֘$' yB2;{ʋ4 o n똱Z@6LRtWb"'@ T5)0g!0OK[qa h$/tV|? ۾NI0䎷tں3v׵^W.C~LaLV@-曶2@ $E!Up@F\l*rpc$FMNNedK^ӌTDũ Ujz^6qB,\eY,|$`aÆ%R6mL<$;RȐŹOS :~ L*zxGN\3Himr0Jpu.U'Ԭ l Bϙ@)%P\ ;AL 0&@Pƚ7*\ &`LTWv'fkEbvB/^aöe4&`%e;\dxT$&xlO{TMCr׹ 7 0&@qPBſb>ׯcx ^"O?`!^iFYtD-hK~rBۉ&3&(Jh(Uvx%n)<;srÁ 0&]u:^`DF5s16*0&x8 (SUl:Wܳ-L 0&@Tz"eG]r/kgL 0& .\ejɿo֭bqL 0& `p)8`L 0!`p)h,^󵄅`L LDL|,"RhY(OdSE"̙`L d#һ;Baӆ$VcCg}C0&`E#`R-F-sɑogL 0&@  -32&`Vx8 `L 0&`Ųel'@N`LhӦdj[}@}sf3]5L{2SҘ)3=K,ϩ*&&-eL 0&@\ W!;GOx7ޥ`%&`LKDz9pMibzGUxw ڰ@3h|`L(TɞpUy Sts6&mAЦC͢y`L 0&.%((AZUIr>dL 0&J@it)(!-9’C)|p0{QL 0& .Bcޚxto^ADr 0&tWxt`+m}.tlV" bL 0&PxƂ r [6ऋ6 c3&KA,%:G/î1wz`L .Ӝ]+\'Qr`L 0&lARP;׸T`L /R0/:| 0&@1`E2&I] ^]`qn ?LR%2&ȓKA:CK$dKz ꣪]"`L 0&P0&.ëndS#AV|vAwR`T95`L 0<j@I&%#6N'"q;::_}`ȗ`L KA K0H)Q8/ WBrb&`L o*KA@ތ8Ʉ`{yKL 0&\ 6cU'm9AqV L 0&@d Wz ҳ젨/]}%;1r &`0 \6j珜8W`wL 0&'`p) lzǂ@jޘ٣41%q &`L*pKV: P*I090&`"`p)d -UP*а@&`z*[Bp@sQ|V$Ƞ#LmR/Iڎ^RVY*eA`*)hvjԨa;a,I&Lm 0Sfj{xm(M5t"~gY `L 0&`KUTmݺ-Y,2B`L`sF#$<)r$`L 0&PXիO 6r2|r5֯ބ+`L 0KɞpT)7qamT) 0&( =l}o<3Nz!7G)(} څi&aL 0&Pz(.3cNnSz]Iҥ]zqM`L 2]HDg&N^ 'h{cBlL 0&,WtKAEuTqcV(N 4|l 1&(,KȄ@ ٶS^%F %p>&`LKA5n\4\L8ѱ)77D`L 0&PDzՂJh-`L 0&4v/̣ 0&6a, HET\, UWc"q?YC͍߷p۸9̥`Q:\Z EHW4,ޞ&qDJC8gSIxnyڙ^0+#׽j1L3g@D̥ĒlJ@C[r lY o>,ѩJ-?iݩrv>q֫?׿cDZ$0>zJCnLa7e*&M_FFg$GEΛuY.XĞƔ~޾8C,] >76;yǤ^Е?ᵭZN'"_C7ʃh;Gе^p9έGV#q|bG|RWk(;vH29Q jÅ8n2}Zxㇽ3\ȗboag_9y ;LƮ'5pQʿ0̿P(r9ώo\a^ߍ >Q?^#[ -x-4tڨ/b۝1dX&/DZb >ޘkZAXx;7=&JNy>~p߆Λ5}' ުc(6kwĦq&zFo'[v>:^}=t% U+g}sϝ>~;իs4f?j|-[&q(˥h Uz%=q]sMkC߿rt.S+΂axqM.cqMZNw5QRyVsZ듶'ag qr(R5{k!mӥ^"S4)ǹɽKzB>Z'^zɄ|uZ1?2wF[} ekpL@HCm #+g7r},5J[͛7Xy,|L:}^O/OcTl.:kSV*ݾ}[wz3ηk RoT)EFFw+CGeنsSq_kҊ޺vytlkՒt>䠡cv3U*L Di۞pQZ@[wN H8%"JWPHi X{#{/3闡u*WR%"Ï -F:VSm˥%vQ46=?#yvpe&>yL=N~:"Pws&c(^B_)%) _vzyٟu2 ܥ(..S`ggMP \mg5:;yduKA9#p>P9gw2JzS_u!fsZ֜uCgn*OGmZh݃:?o⮚2);DYsVFa.I͟cGGԮ^ M@t+gw{v$T?%D[(*?bO]X <iGjWttj=vgip+{ ,og {)VQ3QΧ{2mM.ϭZH7ѳK/<+Iqy3IȇL ޘ14=CŞZ7O+dqRN ggžhQøE9r-۹{uqM4{v8WչM҅bɲAXFB5F\}_1͆;&~~g\u8R}/BxxE}_uX8?\W޷Z-eU%QhB~l=}] E[~rg*nn2N>,-%K&Ʃp]N_쥶78+F9SֶBV9ݿ?"OCZHDk+VſV>wr$2`VۉRzb#ݧXv.{{ی7o5zWn,RƬc>-[WD_#>#[`"֎.qNJwo8ntdmQYvtdb_c}2ZD/禬L(IҶmm_km~jIʇCvJEi>-6iZJ܄[IMmitɬažf!J~j)6e(m {KT=CT]9dMP >(-JV#,C 88xyy+AG4$Gk%oq.rd@J$PË:·BU/T'{Q0/:B]#KU6gI`9yu]K̺6Qj摠 r/-I|XJqL4L 0&P. Kry[QL 0&P K|wnL 0&J*46ޞF xܸtQ$ZuQ%%PW. 0&@ Z7B7w鍈!O{ C1a52NPC#,0&CR0lWXjL2y4־Tۿ 6#sm(i|֥7~׀@3Sg$\'NJNEHlc'[]&PHJr=/T5]\\ЬYBLE'.ΰj#v4/c-цWK{A|LStEs]ա;U]&-CݠFaڎ8uѽuW[ bZPT\AȤ H&`@J*y r Sۊ 6&4Hў']1F+:~ťShw/MG@lԼ[;:Ȳ ???Y`DD7nڵk (‘$e!N } 2&`F@Gpw2&`+f.3c;k93Q8.$v !hODh,a̹1zm7?i2g`s0dB)T(!f.u}+/F}m?Wh9rҙ(<a 3EĐ)~G0Rҕ= ﬊2&`0q)1SSTprJi; QgS-mb  DYM`L ؊Q`:u+&`Lvd*RP4-TGZL 0&\ j Z򭎎UҐ`BX `L 0&`$`p)(T)#ׂ1>P+|1 1&`E!`R]c*ȻL 0&@.T¥>(3pO6y7`L 0 ݜUq2`L 0KA!`L <إCxӹL 0&` K˟KgL 0& Q$PWYTqy 0&(O\ fǨ}(!Ix{6-<xo~YT#森39?V100PNW"<<<| 0H͚5+M6K݆g,ܺr\R<H_>MM* 𬄌C, }u'z5E-̔$7S?@R4d?7L __~maZr ߍ?Ơ7>c v&ۇ + _ #4醗h@`puM9u"xuEsޝ$s|Faڎ8uѽuW[ ~~~r|DD7nڵk[LǑL 0&0Kcܪ5ka`/ .W.#XS,5N@:R)~elIQ FLOz+V|[,+ceį o7`L 0| \ fٹÕ :=WΙKM2Ǩީ*NmR)V\MT9hnҤP,n {By(F:gRR1ǎdqP=l˹)7T(aFj}VCJlmQ !0=*gqxX{j5R]@ f]]ڊ8=k'N' u@uX^bΠd:^}' }Ҳ>*;yKm\jN] V5=_`L 00s)q? 7 H\]s*KnGf] MKp_Tlk|iNEGg)e|y/40C0&@Ĝ MzfȒD =!|$gfaܹ f>+dժS>*[4[S22ѬT;%{_`L d#.)yUqZ{R}kV]!P__?{ƛ0*}6 ϻ 6pwmÕIb>dL <R@/OEkАsspWH2R38OƭwB/ h|f<ޗP[~:DB̟q bXw/2&`kRD2yByG'd*+B/7?Mnۦrk鞷Ů93bfG` uTƕ f zQ0 %쨂ifK4bOoz`e@wpnRU۸):<4jO*;Ol^]CX2WfiN$^1|ň״5'䯙[q3H64Ф)\{2~x+Y0s)>+ N-6da:{=S) sIE#fp#"_ݺ)^kD䔗&.NVK U.܂˃?uЯ^7&0\ILƚZ%FIA,FCXJѓ R%Z%1P] `9W`Ƕxtt{r'<P cD}CʃWw⎅Z-GpuN8R6cld$Vn!Nhe?{;h?>̮卉͛m$BXJ2\|)x&9™.G}X(feҞڽN;?Ձt:.'AO,]-Já|TxE:9ci5wu6}S;zmAKg\Ǽ u2re~!~^!~6xEd4K-46iYX hߨ{(*}cO^rYh3%z^3#ti+hƦgS|=Z+'N(q``cExS[=8<ukIE)]M.h၀NO*i8'UF76R ˾+kfs^DqR:gUcBsVPިٺvzvZbm:2'4"uI1 \Oa'"-n nR8y/Οt2":,l>j 8֥`4TEw{sP[ ?jPuy!ڀaXv7 w~@؃CY57uwGʕsxfN:9:IcklP7v#N=MawfjkjbbHC 3O6NEh^>vCAh:~߽{f߽+UvRϮ[^ 8NxhL^O{!V٘XT/q|Ja=;dw5sq.`"(F@H&WYt}AS"F9džш:缂W>?*D9 Th+ױM+{=v׵Xl44&fCA gG뙹\ِA;cy_z>i#Pl#gܧ*5 O_O=_׭q=i8-ګ&9R۪jd,N֙ W{&DyKde6SǏjꀻ1yO[3Sb/$\\k"\[gD2@їp,^k6k-Q*"B(\zxBqHwKp Ykִ꺸`Gfs5*n"yhD=4BϾf+ApS*mZch?5,vC,!йh̋qbxPu^\Xh͛yPR%߽U7%'11g"g{[4BzO~2z3Br "]pv;C#qhw) S$ի'_5ø/:gnafglWH8Ց\k [&O "&,&#i&%&H Ssvf'nT_T&'8/ZvQYy/^D<*8)"V跢PMXߍ'e6kCOZXRq|UJdOzx_t.4ӬYd@MD2 >U\1/PGT֎ * R*?Uپ6}7űp)E4IO.u ?h[ŋZq@IDATOIB IOyBy4d?7@%ھ4N,`5jl~|[@)~%o044>GWZ[d4NXĭy;kӺn^ueVC7/ Aσq}K@v)jI;'assMFfQ'3{xٮ=.FCar[M9u"xuE|ޝ$s|Faڎ8uѽu\eEt_ƍQvm/˩Ct}ꂥX+8u1,[8r3g)M <~k-L/S](&P KJ _4^= tK22hkIOl L,HOn2]h恎_~ql(Z,K5o{A(K7m!CSUI9I(X3Yul Gժu"Q*#pR[%XR\/_ HKx國Hfe,ma`Dhd kIM ;eAϧoENG-]>Ŋ13cǘH ⶛4309FuD|M8=>4m-> QTG[sFF&5͹Fؐu^rR B __Ln2IyLGL *<< kxṲ!K͛z[^$d\DzlZ4 uC;vW= <*_F u;M0SĎ\iua H4{06 )s+Ye) ?LJb4:Gѝvsrf*U`ߜ\"infQ_Z4oGZr&)L 8r)> _?lĮZ;%h*ѣxPjdq~;+0@S9&TN,‘W3v&|JgjAlNQKxM%~. ؄. YM..(qԿ~ ëH~ˬ6)B-36b˻:\ Sôb` NlM@to6i,5]#7d)j$VBND}Se* W}wjW/Njɮ#b(E2&({Ş :JH.IB/ SQtd!.en8^XR1 0&@i АeEW}9ݭ)/z.gb-Wfˢo-Fr-`L\;_HP!րvwc'N5_1҂i] [[{p璙`L B@h'I2h'閂Sb +CZaŵK6:/u}9 ZU.@8 0&P $&!N^ur,$2I*Bطemj5'2 EC>x^+\?h5}ȭ`4َM5xK]#.h \f.+OӍ8H`L$ĩɜm X]ybR5T&#^Ưq88{P[O ag&`2;@ϏN@њwc2aO6~OΣTtòG>o.HG^x 6X!ACZTpi=CGnT%;uU hLqZ}l# =rКu)~إ|窎\t2i+[tAηJ!OŴʋG/cӰ dbؐ'v);W<a+uh_  G9Y!JTƎ,N-]*4(D qD_Xʩ4uT.Pzgچ0s $Qpd5@S hMMF,hq+ B*(d+.e c^kCՒ2MytVk,,d݅ㆥ͈ Pը ;RSBYkica@S࣎pDW+qXws9]M+y/5芷5GUACbّ_&ˉ-T{7݊b9y+J[`R]rLEHX<*4kMnWk "eVukCx1^o#l=N a|@/a12w׵HR ;%8T*p Tê"R]ExnmD)ooD[@ ,߫ź "Rrwf3û/&)ۙx3KSO¥I+(ŽcW_a7?`oAV'K.mLK0#Uxx$X"gL`H`XzLFAT&cp9VbE ?:3ƔW-߹:@!F k\=M I9HE(?..6NYXW*I-M;b>;C#qhO r$\zeHᦅHFQO$rKc b[*`ַDC\/EL->Yf%LJRPQTnջQjIFKs[d JLAo&#wGzkE{h5iE >]ꐒ]=$~ f@RHOk[o F/D^o!###" A81-Bad:GYhʘT;HΗ>|Xvva ?L p)8MM25 ߞi{D~DQ:YwBlǤ/ʖ"QcT \D`$tEs]^H)/LB~[0gzk8S[7ȵ+ƍvڹT(hљi ZEPUߚ5єQoZZwH4M~ѱT(70&P \ eo+f79DbtW/_N.5X#4L  jh$=?6Ɩ](u@/V`q/XW.MǦˈ_>4f*#1Jb jժIc閖)g,U릓aWy[3͢CH@" }g^5Z|=I9bAִ~)MR|MP*Fş,(Ԥk" &ȝp)("3щHJWqQ_\t*59'kmE _~ސ9iAkxze ScNE/ecR?8a?r561!~G0R= ﬊2)1Sb?ogYkegW1AДks:&J7֥ДLdÊ 5޷Z=Tg( n؎_A*>/bdkR҅ڃo҉dkvBul*14Ar;=յN' u@uXKޗ 6m(pjBYkYś1&PvT kLލBe&b=sBC /ȳS1)Y#YhZ9^s9qL#PFzb\|ʂQ} 0#KAkjR{D{ُQ;ebee+ˊQ} 0#ҡc1&1{YQS"Ǘ@)!P\ .\ &Pj GN[VkMRMe>}FY+E/_H։/R9G zH,#7J#yt08[\nTg5.JP{5Cƺjdgړ-F&N!D'H>ڿz;&me{}`7(a˙{>H#W%gkQ.XBk~Z[^,-kX8`J*aS "MiQoa54ܦ!M G֐#^a?)jmi%7s d8 Z0hQ;9E>v;nP4vsS@% :W1駴i9QoYS+E T<ˉ?GG*9a]tp&w[[st#}Ԕ|=ǖIW6WB;R6%fwm P:?mZ/%/Buϵ!zUz5 9yFGL6Ui(%0&P*#iUnx7BO % f ,5ź "R2H36w }e:"1H6n:c6M/k<{a%B,*]CEܝY`4?LKTd`ˆd*pQuJsT=su $".K85C+=_a-a)hc24#&@U6[ {hmRR4#8tGNđtYXO?oj[}7^5 ^o^$ʱXp@F nA+@@5鲤-H*SSK{iyH{6ZOy[ V_{oCꔅ>xo~YT#TLzġ9grXz*&JHFkm_VG{z-Y5vqqAf͊*ܹV:zJ[z d)uBg]H4\^JLIB '\'NjtOo!5>fL #")0H>q7h{_4 yi{fzJ &]\̫Cw/҅U]&-s35 vGƩCeO3|ƍv&W 0M@3SnMj4s%ĨՎq`"pf=HbDL@/V`tj6-h7skBis`e~{ yYDV:K3+zJ'ٳ a=ŵ:S:3K?s.0vIXv&C9{F1t|M8!(;tpY]vȖ6*N S`kL }'PFF&<>„hz:`l2RV*ʐ([ږEkp)X\iiS{LGOkPU:GS@ bfpzz«kL8]qa-z0g-QbMWh=NV2Ƕ `R? i Ed .;xq ʉ:ޜ)kIw]449C&&ѹleАX Fҫ&ecF>OL41`?ftJ-Hrdɺl%`L.>>wt(m6=\2i+O';ݠ@-r*?4S^ @&_@rڨ?woy&&c'۰iN%uBk㈾S= HHK w{mq* :@–p?V&^g)m,6lB)ҺJNlFGMzcf:4&xh d9>Ot|a pv6@xAW9 @ڪx\Ɵ-al)v0f(_EZlNG:NB*ZT*I0$fa7|,O ܹX 1&P.d@aȼi"M Ia6fiґҴ<{ߤy99s1" E)\$@ϩwRn3&(EKRE3&`Y%Z$Ү+_l&:/_`L] :#vXFmAȔ>$\s Hd{|5L 0;r)h.W/O^;Mʞi5'gẺꅏ{~6҅M 1v7BW+O,tW [.d\ u< 0G͛7xJTdXpk)/>tj)G5ꉦMhi#NKzLĀ٦0߇h[su@>j4 DVkԨm-/U*O\CCC߁Z}O@,$i N`іt*^RnEOa;%fF41 QOf6^333efϝΑK[K;gm-oxyS:rI KLDmZ=i-1}RVؕpHWUtxbdm_<10t[>mI߅p>T奭奝綖sQ)w 6 {r)>FWYGJޘK<+%r9 {BRغFԶ*'ZVn ;?_teY>աhEX~uqU|zz72v9 G6P90R `RPXN17pJ:A+jHPRi]*BxxiInRZ`~ c48y]6jZ[`жo.ͥsX/鑚g_/^v\ZCҳ@T?m(&@l#&ߟx2]j/A|۶G۹兀Rv)x˨#`ϛWUBm>r`L\KA9hn!,, aYhxW9*hԖ H&`bRP]d8P'[j %,L 0&dLDƕPl1G5$rd`L 0rAʥ`ЯTh2 pr2QEGL 0& +WqC 'RRb l۶v2&E NLR2_JʷL 0&=KA{P2`L KAxqL 0&P 8KAp)Xң"~Pܧ&dgecL-.[m1-duB $mO4e28hWd&j 9rg.!&m;g{I ˳ɽΪEA/ay$- $&vcwԛNyB> ѥP,Xt?U_G?0mOj㒘@ xJt\Ϙ{Kl;wv5!^>t]LRIм9!`O2GVmuEU9m5&KhiS}Fg>XǍz,r{S@ :}-Zn QsqiE?%]_.XW8f6(Sp|Qk)/֮]{ϚG1Qt /hHGU:ĴR3e8گ5zZ& oSL hN~ʍ|kHo%nR[gqJ.17@+!E@jWؕ~k$7u4]%BVGϱr}ZS4/3AI#Z:M~fM:8 T|ӧO#t\rn1 .G^poQCc[Xf9=~5.&Fߐ'e(KA/LS1Ln缍|U$P*F >'j1z7iY3 7wfa֜Ϟ~VYyriL=ۃMjrhֱ|%oO\ZZpS;AX?kj"}YF,ܖE EJmnn7@RйrEZp xr$eOFy6gg8ӡPx-9j ~cwh9o>$h4G]4jq/FGF R;t[56E'G/zPI1 f ffJ,X\4 ZLSF@ 7mf/mADbcoyݎw3R'|R+¨U-I u\:]Uc“y*,^o7άÌ0st/,نU,eai"=91ϼ;r3d h +8m- .2&?.{6 {(zgLYw+ο|~ P=Ia cU. ޢq[u52cCqP`1MDĩ}X>q ߅Eǣ0I-Ap7{_K)I^Nʐu-r>oNy.TqZd*4^HfzcL^pE%+H 3,·3gbyX;$E,un.(kG93gCN8]mRz`HVg!xx!b4=Rfe.? lJYS_C,Y Ǘu*,`v#vLAOFph"j$yٌώL 7~܍^w7y&1xD,f?^ҘO9 Ҿh2Mk^2w|\tYk"Gҫ~.ng^6~Ԩ|> uwFɛ$e;$#/ }ߝ?#:3tYHfEcL&?:t: ʊjF֨b6,\b"[yߤ8dzp%;vwnj{H;{-q%SֻQ)&;x{cZĨ4kFgc>e cRy)WDw@*hHL^&>o\3H.m/GZk nj+-@("7믿3~)dЀ/դh'(osVQז5 P:லUFBaHCVWeT$E#L9 sls÷LcРA{6m|D5%.:X,E|jt.YXfM Lhːu[4g%*Wi,AkVNET0|m=TQT?cM\ ;AL 0&#.=‹&3S˅N1=w⚘`L T\Kюւwr`󊋁{`LP ThIƋ1Y+6+Vg]4 cd`L 0&PrJ',dvY$tɖ }*,xKNK`L 0&`"`q)(tHMMESX}1;gL 0&@X\ f |bv]<_1& Uz} I}lREN90&`v% _RppirvZ2dv cL 0&|` 3S!F@|aͻ3"&`LT¥ٳΫ)>Z y7qUqqL 0& 2 ^q4$#n `L  Rp-3++ J% LIX3e'`z=[Jr)(S QPv}4 ,T5lj Acn=`L 02&2o[oU4LjL:Ye\ 0&@'`q)g#=!:FZdع`L 0&8\ '88A z`L 0&`Ouxך 1&ł 2ԩZ%1&(ڴi5[IґL:Lgq/3R5Qu'}?Bfj_4fLO%:TorL 0&@4^GhU>ݰ1*囗0&` `RPsw|Cx6V5?>S1,L 0&-¼?.> 3^#ش(m8&`LX¥`9A rh& ]ƅZA0&`L>,. "[-8̐6]nc7}R`L ,.'% Qؾ[;5 &`%& iKAHi s=$6~ye*x5C=N}K `L 0& X\ 7ƥ:㛉Y;ӐJW}aL 0&`'QH'*,E}}7Y/`L ť .3єTh (<੽k%&`L^r4 J8T*(4^&`6I0YB/`L v)X PH&? Kr; rߕSCeSv)hϙKdL 0&P ehu$(D#8vno6bL 0&`'UY⫕z%4Ȏ+&`Ld aJJTJL6ϞX`L 0+Wb@ۋo?;0)^x 4aL 0&Pʕf`Sm o54T*-(Y7.I- 0& : R$G*ɧ,tLaYR@`L ؇. [!5"Lq$US`L p{@/@P>{+a'ꎠ[`L 0&P2J1s x{ x%bawhxڹd97`L 0T?"oQqxb"ۉ300tLT̵kנjb߂KXj%,Xf ڵkWr&`$13ۺuk{[إ`rL 0&F KA=3%xEfL 0&\ *bc=& WxrtuVs`L c*R0)6ZlT}-<Ϭ6{.3&p<i:hY>&0uv[`埀ťRLatkT{=`L 0&,.m$&`ťe-,`LD,.E)&de@IDAT'%VnH$E;)E75Yqf&`ťgV!,'>Lww}I0>7#1&\ *@p-HEXTu1&`&`Rhi]gdL 0& A90&`\ Fs]L>47-oi-&B1#1uq;jqqqzWցSPމ1PLrk/,uP"Z'`Bɓc3RСzōa$2˙!5?ѷ@cڌ#[-*LDݧrB 0ϓxKK9Q 'W K r7 շ&b~l$l8=7Ư=6vvTvw/xfKvQ+pbdk-"-OF 0{@ʥp%xBN8S!R*ٺ!.^hW[4R~fl0.Zh[lR>z1?m59a~0#glE)6L1;o;vz 8~cdac҂1l0 RHp!?| ӱvěsǞFṞ,;#2 =(kRm¾}۱eX#L>%0xS!'pQ[0xp8,XZ޽ GE)Ŗ&hgaqMd흿­zΠ/Bc_vݔ VL>@kZFh7xxS6+Wʷ{oiEZoڧT:1N;k`Rv"Gu~}v4|+!^@ ` .4m>s cƠݧ Q 'aW x7α ӏW5Hk~-Ag1ю^FBwC81-- |ScZyc7)ǭ3zOһI1Zo7E=ƠleԾ8pt/?l|>"׳/ J;xnH; Egv åSprnjk8s喀*poı!v]e;at]`" PU7 ){cn@XzK7p:N"+_-r)W=?^eǵꪟ,wY1O#c[Y5WNӭƄ'UXnz0st/,نU_vC8 T|x_e?_ŊW5&`KpˏpX!^4zFkW3n'Bq<ȠГ-X^knj'glqY|̸RZ~ƾL~cx3ZO$+BviՐa/c~A|Po,<}/埉gC55Qk`lƨhՌj[?4ީ[♛x.Җ$fo|b5ƴ놱^ r./`v_>.,\H4QN .ȘgL)%╛VRnJyAǂ ld(&ϑ,3, ?CZs6.W'RhVɾ4CO&yaIGX}.D#`2MZ-HYK#(gmh0WTVi#)q4)$hǀؤ+7X -I߇dU0r@ <<\Zv=k)|Hx:&!t JXrQJ% ;v믿^283(Wh=4>,g} M:˺]c]٠A|f[A s)*u2o7 @DD;{yfVJg1%֘Lgq/3/Á _0mUkyR*Tp<&E] ڋ$`K] :G cL 0J] VO`LTaQv-eu&עLW?ԩ_آM!Yr2&`".Ũ VۛT-9-tdꅂɉ`L JLCV/~xBI&%oSvT,} 0&( n2WG-i:M"c LMj0 9 `L 0P5^yi~&;`79fr["'pdΟu90GVDL 0&J@w)9%G:/wUW\FtPMD[̙kԕ~cc߆1/YL2 ___cL ؋@UcT9WWxh>@CtoWXQ4D0*iV &&~~~h&pDR^*-Ku0CiTV8m xgCSI N6CvxYm&H&`w!.WVI7y3V=碌 UΨ֪5NrmVMfL 0rG@)\ pUFb_pQ[d`U|zzv65#cZTl5hJY0r6R?.`L ؇KAQ**V.A$Oeʲ/,mԦsȘ eɘfL 0P Hd I8^[ PL?W!xł7_1& .7ELDmZ=i-1}RVؕpO ^`L 0&P ѥ2V /G.*ڎMz+]U`嗀JRTu06]wF/:$h$C]vrx|t0Z:k!6$ЭK9{N8q2N( kBJ>p,899A#{9hO`3V;qa/@ײ5N)"6AMr+ w.a86ov >nS?G`fV]ÞqQxaL ؋Jl6rM{cĀ6WmeQ-?ޕ&L;4A&o7oj)k)Q{vBx'88#c'ԦQVe|3ЃꝻfms$GG[Ɯ<=ᅢN'^K<_0&KRP 5$`VHPʎ>= 7++OŅQcz=n4ųf-t1'Cf,4=&7P( .Ӑqe;8`)ϷpLQ IۄcILCϑݎ ]7jw.zשqn!edee>pgo?a | !W@"d8ݷs: N*ގ/\~@\  ?M&'Wx* P>^ ,2b&#r.DMtLZʕ;t, i4=vG/]rig+k9{zR\wR. _Ѡ[A$'?06&@~\ fD_ zwR* %% Pηkw(Ww,poei^ժSAo+Iq:)5RWw[qP꒭ci~;H}M@۱`|L 0[FmqLx4"p}vD ]RrԮPgy|@LkH&\DZS \+GzXJ=dר)\*yTfzK2`L X`V8 SS}`"h-7!,5qwg8M#ED:7wPTk}VܳW[*A:v# ߧXؚr<Ѱ1_kfv!CGM#E7U*mlʢT:zA |O=5c iF*9a?DRPˁ%дAH׉*Ntvم#4- ANy> WE͘!+ D7 cNK'4UӇni|<\8q /60ٵqF™0vK?jvZ{)m/\oVkjuJevt}v%ҐΙE Jo1]ЈA)\+5Qa һ^iJ*}IGj:^Upjk%*Ծ>i8#te% n7 0jK+'z%+iWT>֒ƹ9+Ox"VΥ?[\ :WBU6ު[pWBA uQ9٭[+م֜"c[1{ 1@BR`R*F#.#*艤)L] zծ.&G#'^zlAmL뺅.2YϙجG` քwOvރX+.lcaΣ%Bk)PhNfM#:htIsHzz9kHbK4hNׂG:p]~mL,.>(EM=Hl-i{4'wicN0˽p~]"qH5ϝx_)i*@P5 pCVwH1a WAm(_B! ꤫WmzvT M90_ tb\ڰhhF$ïI3݌AJ mKh [Cp5fa`C(i:qy m* %E!dSB#Z*'@ZN/$hR};[Prԣ!z,[4;c.Ȋ-P%s.윀FaeFJ)hEV5ŲջCD_tH8\=г^%Tl+#gOơK~gcnFE!ښS̞$<ú6{5: rGhf5H 6'[tXb đTW^Mj1U=d,A>t@^/NPkbֽN]itLk95I\(UNoosyM@`<4_/N[ ;#Uމ[v܉矷` n"=\5wQIei]Wx5SϞ‘32o Id#:Ќ,N)gPҊ+X݃i}*u|s!}`;FZE*UIBVѪI c'm rɒRf+PSg[8 D0ԠAɗu ӽ6m|DHQ^SMbMgq/3Tsš5kJV@+=5nizj\/Hz=4;b;(Jx׭ gz>V mGi{9=cMHSAIkb8ĴPLz7p|V׆ݪT!+)eB{w`?2h]RA{S&!&?N\P}f[۲Od^C&.wKq9L\kQu_FKDbYJk,4ŏN#&MQ Wmt]KS~/ GZKB'!Ҵuɖt#1%4i}<+l!'?"f5 ?ۓ3od{ٞ6 WB!AKʤ U/]bڙ()+) K^5 >e"6p ˜ݠ1*,B{a#,C'| N&<w.A4߬/^cۑN 宋)۳˗:~]z1q/u$b}]$`HNLK> SI,1-Ƅaenx ]{n}sz-Y1-')-0Τ)WORQJ(g')8X\ &K/Jrţƣ]іz՘<ғp`|uv`xHm?^6K)4E^4+),i% %-ʘ򺽗|}QQ~:v62ح۶sb?,hڬi֖gs <;YPT G[ 5~XB9\ Q,PANϾ?6h"^JXSqL1;zz06-)ψ}Bs& ùlboE۷ށ3|/ۤp#ny 1W#֑]hW_WZY3ڴiGܕhօFp&_Xzƞ,.E:=e%d߃ b(ha[ϞM]l4 /ZKG1}52k;ǖ _4Ehhd+ULM;[9H@:NKkWAX21 5<ĺƕ_zuY'i‘/^p,l= ڜd)tҒ*W@q} HlC1pݧ#m}]_{bN—C)FC A#;<ek^ܰ WHRmE#פcGf ы@-)ëp'І^ġ^ZPyyʶ#Z!puX|꜂Yhɭ"&HERo6p?HǏz!V۵̅磞3f)G$sv7ڴ)/U[-o7-Ь0Pw 5jEߋT%-K:H65~R;m.h}F*́ 'FCw`C / ^#ؑBݑ"v5?ܴ._$xáVwxgqNwN%'K?~ltVl!86;iZd+ `c,?**AA+PYdV'y-VcwyUrN?9vex=qa9e Ȳ8ȥb4Gbn dz/eRBB,7|10L\*TUɇiRD[$qGOE%HIC_i 9:& N1Jc5 {t֎hԬwR@/t_EOi8;Z;Z=HRXGn>M- XJ -bZ/=!2N@l%o- ,C )m޵3עܽD~XX;e^#}ηbcq*qjȇkβE496oM42y+J-whؤRR,fij35˾\k0G-R @sߊ"Z y7O'!Ȁy:hhZe*A[`i$pF1yE&w#pҧ ZkFj0bKΓ"S8) s2}.~dRА]M/̓d*h'O-Â,\g9kt՚ީ#px^ކ1})hOit(~-\VϩT~PѴ ^JP&sLӰE 4*TY4d6x.R*(^mLlJk9-U湛KLD8rӕCApyJgZ*0/e.0C/Ve eD-q2iTODyt@]b}fxp\zBh6 \LFKYJC }Tl&hӮ s"~zL A'rxsxfL" x4S+>jHgo<^;mHG4# ߅7ocշ/ş_(MSe5֯Q7ծĘ/>Ƥ݂"V n[gWx)Fy'C!8bqjҀor@ں7A$TAA? *hMNIӑjdyJJc*PGZѴզR?ĨT4@A+M^ :iWQٿHlC@ZS3tH/Ӑs2 TQ9Շ/ copρCp 7( ,-@u@ܖ+Z̙3r<DǺ[O"BZښ3x{~C'~o>66V+C슷s(~SsӰ.hz>MYҒ(`|]9KA4h0^^#GEr9",+Оh9N|hfL;iZ!=hf>uTh,ڭ#uBЦM#A% AT {!O<$h2 Z)UM)Ŝ%cq N{r  0i+L4]-Ft$G'YF?yd\>GkR~ ũL@EaxOr')kݚUs MZ=y4EݺuaRB+sRܷȼCs(5OZ9P24!3r\;dڢ.&h@u:4hx^iTIM .n#y=8ӾH,bm3eR g&Fm^yT2I(I~wdHdňV PA$h4Ps=b:WVQ}'K9])`o:H/gs_8ovh^F*9QP̩B '_F8giv#kKyy|ԮD1J6G҉֖9؟0Z#/RbY9IOL xAZ!௥8Nyϓһx<; ([F DY^@E 8 ^E^X"`(Ct0Rd(RiSHڤ== $-)$y?7wߓɻû@i0_B31*`1mvcB1}/y>,= id ʥ6%D|yg_poҵ I^ѣděbHmYI[Ҕ=ByRoeWi$L;v)iJW1Ա7*bʻv83Λ`lR3fJJ> Vjwm^q.E _9{֮_%r2Ox!w(* FVb:Gcdهc}+BRr m 5GVEX#fV$1fvVbسjϱRͺudɡʿNm&UKҋŸqC~HJ$\ w͆oЎh#xqC9O[+ZΩ{Q3IGJb7iy\m̑7=@4mLCL#geDZ=v}IEÏ{|I!KEk/Wh5˦Q>{m64h Ҍ&OY;w `VkiY϶"wxQv2dms*fÄ;tL#*o*ExI]bT4/6;WΖcl ?Ŭcz71=k;liŝiv"t# * [Ȋ"Z>ܣ":mEGH([݅,4-):g0#0a=Uݩ5JCfRqaud#d-/͉Ǐ^I+~`6lh!7n"[USJ*2A`Yt$ڟԞlcR0d"7Ozcy8Lc-0yԭ? kLbG-sD4 ߥN! n^t02^u S3an+StTx B?tV֏,f+ 5,Zu=Xkfwn5. u脐:AqWp4A+w[řdq *?)61\4U+|ɨ}hF#|%:1w#`cR}xrHL#VQ4ǜq[F#еtGmPczokLGE;Ɗȇ֠ԤWZlLܙ7 #+NSWH֕SdJ!d%=6jD4:ik1u)ML.1)XPDNšdH oW;|IKЂ S!(LqBwz 0pM^)E5 9sF$Zfz5=_4 yY r#Y9p4I~s7+W9[1y7fӡxo 'F޽#y,?[Imxg;ժt iW~8&HYO,KsBфwb:fmdSf L,& c|$Q'dD;t,Fǟ]ss>FJQasw5#-v /?ٚcLC4^q2Ґ+$s$ұ'ҠS9[SziR "rXC&,ܩ k%4^^ޑ>~Zdd=DWOq ..?y?5Rf3m2Ŧ^c[ `MF'C]p-%WΈY ;KrBqHɓWy:dESע.vL,&ӳ?zOE$5S3{I1k[:~zn=`7 #Z_U NK7p5=:u@Èy8pZtx'yTg9 (e2q)yIDATVr+baI!ǴKaMdtW QXC\U[F)Q|ee&eK3 KNҳ~4]EdV\Jt"&xQs(Xfbd~w N0OmY(NGWmS`nA :@>cK/LMA0g(v%qv5h0ڵ+kV `(C w&=wEݏ#2 m.mkZA#d_Bj/-1&>T~~W_Jȓ1 I( ;B YԤIrJ"SƞHD#{ê{lXuۀ\cLVh֤_L;<: 3&tYВL/hW!j=k:Z"O5^Yݵr:tWfСo+lժU&֐986Za%Zc̍:UKY}5\pBv|rOw.Up&sokhh8Z'& O} ljl)Ƙcb袿e?&mށؒg*M5U8,%<U6PV 0&n 33/xb YF W'h9:,yZ\hZʧ9y1tK`-[VcO\p 8>9ϭ;&J1 /YB? H[UD& M\&!s~U+S]m߇0LڴmlnZv MG#RM"8v41]M E{֣dq5xM# Qz`1Rs&`շ!4nbA'$slL j|&RЪAkBebk#.>wضG@N0&rT*3{`[Q d25i!@呈7[Hk!Iu8;=S߃fMlVbf E1X"a;:'"(0µrxJ~J])lvIDl%V>Lm!~Z;C]spޤj^K5)[¬82]2"cth1]}DFDDA>b'S 7]MH^ O~77ԏנ8U˙aRc(X9}wIGlBȏd :Țȉ:^Կpy? 7 0&(2MEYru^ۏo:I'dFIp-zL8*ϣQUY" TpdVE3fCvP-qFjQ9Kz}+Ioo9:%lLځ$y5qB]aL 0GHuQ] zm#؋hߣ;y(~75ߚ#Du׵2 ~\M'csHT5[huNblRzy`U_i]vL 0&po ֈk>34:*lJa@}Yם]Ld_;IAHPPq]٤"4(+G/xzֈ# 0&p hH6E*Ұu%YL zRbF yU5EW&`L\,&32Gˡo<S'R:W&`w#!L <3uib}|)Q~w N;Ct:WBWJ&<@vBm#"&+l WD"6e܍ѥmmS.M} GS7^K`L 8$|2iGxxĄJ I^5Euoy,B?z:wr^h۶T˳UeL 0&p4K,!ͭҴ^;fz捵hng*z"Ѫ5v܈#Q%M7V3& 6 ZHTg,9ƿ|;gbv&bI71ShC2kխ[o)f΋S2&Ծ~6=B1M|fPhӶDv LBG%T"sْmo=R6)*6e |=@ΣVcS3KKž&.K$s<_%Hڪ5^rodE ED0oqmqp`I@Ք;<\UjՆΗf _n呈!HhD떿bmZ?~xL ӞA  13 |"|kT$l]CDZjtJ1kq`Aז nvI%©o8t" COv2"p؈SrW 0&isTpCztqوQ\Ƣwi5X lPZjZ_nU ~S&>#5($|kȩćM~Ik҇{QX9{`27HѳQ1/iWqnl5'V0&=KBuQiVZ:zhG`ocSBA^ R<^"L?쪊jHizP"U!rWe[m,Do׿Ŗq]&V1&Jد0a&9NF=}>XR ͙@+xA7GGYbѯVMZ11 f>N4RVB{{E˞M<}wԮB%]UNt_򪌚#FdU} p1*66ƍ+%G %۶mSO=0&F--a PE|iÖ6OZ^e$2dͅW@zbS(M6yn*ExeKP]E*(S"`L 04$xmĉT"Mʒ]#-ҐB&1&`C0)X1T&plRM^7 0&<twCh@|vv9F8RR20&P qf?E82Hە=E;^BϭRŤ`L 0'`cR0^]i ~Go7npib}DzÀcwusd{ },^F(r 0&@iӦvBI\;2)HG`Q%~9>U@gwG]6Ǡ+{mYfff"<<ʳB^uڵ}vՆ.wm膻]йsS hd٨(.t Sw=x֙TZS sVꋊd<[vwmBkݵݞpFbRPRȘB ,:VTUk욹e%܏:€D NV%p(wm[|ܵnfe79ʳC:#@-wt <\\}]-(vwm73wOd-&أ|C? ja,P{8 0&@I,&E"UQ>r#SP*=r3p%߳UMJvl`L )Nكi)o|)|d7L 0&@ _UhČ-Z:NX '&`L_h/ $`tqf-QV^\R9luVD[nLf~{;"Jޝc'bQ'|D} 3Ŧ^*<')7aUBCOG]flij7嬩$~%|nz}?Dhh T=X)}[menĉE}B]Ϡj1wJIH^E w\y:6K/ЃV`Nxg?o.Vh3)D0FZlK=oE˞٥Z蠈xXrAoCc辗p8[0hXGi{ňA..z->@_]uP32| <evѧ`Wk1PڨǤ(ZC/rO\}F Fvi}D_:bn ȚL)Ψ=G 9>.F,W3),~^uyw4ǒKtHSC9%ʓVՂti 7H%ԞȾ=)дeݻI[DJjHPf:i}ٟ#(:*&IFJM7}X?|.Iʓ-]0RҜV["m̤@F-]IQ]2hgHqIl6R]Z u:.u`mt!旍GHtAemqksҪ-9 3{t1=nqs8 ;wNZzg(gJ__!"a{oO1I \.OCWl~<Ԅ?¦}@$DxwTSΪ(؜f Ǘ+ؕ/Aҝ(8MG@>F=%JAqZkq~hB?#S-nۮ]Ysh&rNj7^zlSq! 9Ы 8p*\{4z^}5Ѷe]/UD8Z2]yΪ-8?mZd:\s!>簔udI@7].rta |j'_-&aE>,Mwp1)(L ^8?<ۤ3_]%Ҍz[+iY4`L&A̔QgНbbఙ8̳>.]yxm=- C.Pg=i&j#zvLf*r]M =g P/Ж="; 2I~K 0sOoՅjrሹ@Pm߬ woV!f",i'(wm'F;)S 67-+/Z2`.bZۆx66jVZ'&|ׯ/ ukvBh^ɟFMB8g,miw.P;Dc~E0RpF`L5QP,m?GY7' ZēsIQ)#vS46ß*?;?҈~hcE}UJY8/2 -~6v4Sx}iqՙ@Y0݀z\y!68Wm)>s*si&#}v̩D)|$V&%)s{Ҙ1cKvJN*k,뀼KZ+mbh'^ |ZkEDE'p9!7 -^ IgiX֟Wϙ|_T:i(sD}Uv*|/΢PR{F?K"$ǚ$|)h%\wi3k$9۬?PG̳^{Җﬗ%gnAi#LL(N}ͦsHw:i}R̭|[63z4NɆO%?Ht|{5~#]ll,ƍ8=cV/tx  Zq9_q9w~+r ^Qx{ac~[w{~U~Y:^q^_!ϠZE'̇c`Lpّo1gw |Z`L /)!(?~+ X&mѹ^)2&`&`9*VV{3Xh,||eL 0&[~M%A`L 0& *Å,d`L 0&PZe`L IlRN溘`Lp5CĪU]`Lnݺ.SaN`V/sVm$uDOhpD%]W)Oأ˭8 0W%`cRPUL H9v1'0\Lg)/<pDhPxgN}c>U*t7afSC|*j9}4\0&",&"\>kGmQCr+9AyW !`DJiU:l-aS6XYbn1`YZ~b,&IOium7~٤&ܑՂy;6kaA@ߤY,Zb5#ԮK> Cl|P-D7UiI@?RSamン32-\ t-izh#ftyTߗ4% 1V;]"e&|/PمM(>>r3"JL[w] 펑ֹwL %+FF$CZv6Z-Sp|*ˠ-IpvND=Jk:l`(]J-_GFM0=v<ޢH, nqƕ. 9܌ y:Y?)k7l6S]@4 (<&aaCIIICÆ qfD6md uТEK LKS(fZFp%dc%)cɓ'˘i,YB:[%笹-lDPMʕ+ 23-#<٘0f +3u*RjN@5G]}7LjkF#;&`L)lM ++".C!IevL 0&h"E#4%yT GRX2j\Af=6pZu\`L 0&`1)(PH{#&&1KcJL 0& r4>}Ӌ qQL 0&Ť@Q|5[vtjMX`L 0g1Ppf+ߓm);HLZiW-a|`L :|6>~#|PE`L 06·Y\xKt#3L 0&@Fhid`L TՂ 2}衇*\,`L 0 ЦMBb|_Pq|PxI5GޟD>|0y_C(v!/ұ 0&BO8+B +p.y!|uʴ /2Yg#yŤcK1&C@I!? ,xrU)B*J&PdғW(YvL 0&rTK!C^U-X* ^&YvL 0&PdѯzY!,UFuPኄ!EN`L 0+B o=UȊigk+؈%„iQY$ƱcL 0&n;%d _W$TB%`L !#\XRی|)\t%ŽHl=eK@1&p@@#`!Od*ڮ2Wc`L1YRAVWEd-P{qh`L 0&"eAKɔ!?JuIENDB`././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/line.py0000644000000000000000000000365100000000000013627 0ustar00from datetime import date from openpyxl import Workbook from openpyxl.chart import ( LineChart, Reference, ) from openpyxl.chart.axis import DateAxis wb = Workbook() ws = wb.active rows = [ ['Date', 'Batch 1', 'Batch 2', 'Batch 3'], [date(2015,9, 1), 40, 30, 25], [date(2015,9, 2), 40, 25, 30], [date(2015,9, 3), 50, 30, 45], [date(2015,9, 4), 30, 25, 40], [date(2015,9, 5), 25, 35, 30], [date(2015,9, 6), 20, 40, 35], ] for row in rows: ws.append(row) c1 = LineChart() c1.title = "Line Chart" c1.style = 13 c1.y_axis.title = 'Size' c1.x_axis.title = 'Test Number' data = Reference(ws, min_col=2, min_row=1, max_col=4, max_row=7) c1.add_data(data, titles_from_data=True) # Style the lines s1 = c1.series[0] s1.marker.symbol = "triangle" s1.marker.graphicalProperties.solidFill = "FF0000" # Marker filling s1.marker.graphicalProperties.line.solidFill = "FF0000" # Marker outline s1.graphicalProperties.line.noFill = True s2 = c1.series[1] s2.graphicalProperties.line.solidFill = "00AAAA" s2.graphicalProperties.line.dashStyle = "sysDot" s2.graphicalProperties.line.width = 100050 # width in EMUs s2 = c1.series[2] s2.smooth = True # Make the line smooth ws.add_chart(c1, "A10") from copy import deepcopy stacked = deepcopy(c1) stacked.grouping = "stacked" stacked.title = "Stacked Line Chart" ws.add_chart(stacked, "A27") percent_stacked = deepcopy(c1) percent_stacked.grouping = "percentStacked" percent_stacked.title = "Percent Stacked Line Chart" ws.add_chart(percent_stacked, "A44") # Chart with date axis c2 = LineChart() c2.title = "Date Axis" c2.style = 12 c2.y_axis.title = "Size" c2.y_axis.crossAx = 500 c2.x_axis = DateAxis(crossAx=100) c2.x_axis.number_format = 'd-mmm' c2.x_axis.majorTimeUnit = "days" c2.x_axis.title = "Date" c2.add_data(data, titles_from_data=True) dates = Reference(ws, min_col=1, min_row=2, max_row=7) c2.set_categories(dates) ws.add_chart(c2, "A61") wb.save("line.xlsx") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/line.rst0000644000000000000000000000125000000000000014000 0ustar00Line Charts =========== Line Charts ----------- Line charts allow data to be plotted against a fixed axis. They are similar to scatter charts, the main difference is that with line charts each data series is plotted against the same values. Different kinds of axes can be used for the secondary axes. Similar to bar charts there are three kinds of line charts: standard, stacked and percentStacked. .. literalinclude:: line.py .. image:: line.png :alt: "Sample line charts" 3D Line Charts -------------- In 3D line charts the third axis is the same as the legend for the series. .. literalinclude:: line3D.py .. image:: line3D.png :alt: "Sample 3D line chart" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/line3D.png0000644000000000000000000012410700000000000014152 0ustar00PNG  IHDR]sRGB@IDATx`ǿ\B$& "* * (XhOQ'}OEST(EX"(E] %)$KHd37w{7pٙfsm3?^"@ D)ƍWafXu2͛!I`4#Ch>9@sv0ʭ' X|`,ߐtIbA\V_GyĪmuB?vꗺ??Qf*\-Mc*6~Lm8ۮ_~=y)ƴ٪2I*E.R&bYKEE%|b'lNh8zGq=" ׬AŸ3uzl5GBgR@·ՆTV}mWEj"hQVl5a*VUXEZ}Ưێ}OD"ziWZ"_dSmF1 5kB&P'ľ OSmcm\ɋEuj<կ-/h>gQbjWvL{eݞ+*.hZgsǺt*3a1DZ}~gAO^YEXS3K>\7 M%`fqryt24Ԉ+Z, kY1HjGcѫS (OlxduGľ7cKqY5OB`Д]%2mזvw<\-_% N"vGK3ᝥ㪦KOɵm}9F^z95G°C(kE'~ؑ~Q W/:i,y.{+7mn/Ư7GyގGWp1+>q%'}xЕ3b~v)gZUR= ɔ+WɊ *!~}k"cj0u;bG֎Oؕ|PPx̃RMuz0)Xz ]M-Uh#WLQW\TVe"v%7~^W`Qw}-aF[_W,BNJ.g'Ѷ:)DJWE_WۢxCQ͹ ѽP'; 'fj4 Zʾk+Pǯ7Fkz%Z鏱fWLLiziw-x]ɳ(FT~ 3Tq&[lwO^Q'"- -+7J*];Fǃقnv'g|Wi੼'QaU7cFha<q잰hݸdyr`VJ|r娠կȨڋ۪*͸b?Xi) 4vij?ϪvM2}J2f^>m^y[@G[?cN|3xi0RRR#TBvsPR^>EE"-e!՟1U€tň&;l;5 +1UMI1kE D,rC*6˷xߡz9_{qL'5k)yb<ߋ,' td6`!BNiӖԡߪMLj3V~ȍ]0r07aU&9a¸e`It͚5ޠA2˞M>4mۛРQM?^*r%'zܼ%f)E =So,/<Ä~[;=lgW8lnAi S䥢<̓z[m1:HXMAЌWȈ2>br{hd\-T iLѭsCO赋}ŘE|[f+Q[B^-<(c 7 sn`ϢPkۗ;_'+tjB޶+eDOz]( ؀w_~[f.y~_T<%qVO;aY<%իk*<-TEx١BH!Mg#Qr_%Ic8vlz~j&ҢU|J&RˋX eu:c80xa"v_2/Y>?׭^ pU.􈘏r'%UG[pw> y jƲWqUR%'jQ 2"YCAn()WsU^Bb[X}=Ÿxzi}$)6xt=Wy. _KQZkc&$Fr#?*3Ve|y`!&|Wɵ卋ϵ3 8`D<|'gh2G򞔛ÛyMրـfd6?5BCcѬ^*yoi_b|/(L[W]Ks9'YIDt+ݟƸ۱uYqws.fGu[r2 LƖy֡NkTYUˈ4iQWm1VDVǎj4׆Mm)صyHƷ,}:X?ףK/ bLq)i L' -2{pZ׫ʌ?NژokuE#b.N:"e"ʋ|k]_p5o5`(CN=KGE?ձyOA)}Ee<?33nPř*?H mY"Cttjժ%i9ٓVZnlH#2ǦcmIe-ؖ⻊JDZ޽%=튘+Pa8k܎T/\RXoNE/Ưvkղ^o/vcMx{A |؉]A=1WC[^ߦqJU\RtV]\F.Q~E$Q}{~݊sh=}YwuDc1W%tպ9~ݺndqWKG$ºUQ=6Vm-j;7qXn 18띐1冔_zx04e~Y&,< 98y$ԩ(ZCNaۙjAAC#;(~:"cbⸯ/1pvfYR/j 9xgs}etʋ9%hyҧ-2T>Ͼ=V$": 37Ţ(ukmmZm򞖫sSioSl}+Bnߕ>QYHǕ\UUNjǣ-ۂ)Ok]sJ^[Ӓ[cǵ@*`IԯwU./SQ1vʍK*Oef-7y'sQ]'qhrϒO^*)AY%Q$Ƚxao{}攅A,`0N-DC͏,wwhSyQQ,8r4ze5۶m× `)U}:pJ/i*ib2+WL#`z!("-D"aM0"2!>'p&;oL\5ws'no^}$iOi84kʘִ+`xԈGc aPɩ4]<m m1 &ŬC'aix/ JE?*l 5{ÓOÃG֨EawiOCuq36yғwVyX_1튠-7+ G(R] $_Q dajz>[p׍ꀶX;Y^c$3)v5Oֿ)#`wƚyj?~ޛ=ŹV*}U_݃̄0 t{1-p{oN\BQL[ֻ+!l}V_z7F-')0{ $r[dKߵez>  m\a(xniSq~2áѰ-Ks g o^mjU/ٚPm!3 n E\ñ=6K+r7+2wecOgr6F Sck,IB:r=8 3bTLXns Tw"6 u|'l:?' dʾn@q%,}b^cU~Ç}l̼ov?7;lY8aS[RYH;ƙobWhǜvO0j^#ﵸI4CuW8rd-z*v%qI4ˋ"=|6@{$癮hd–gRLfT{<0 jp𗹸TgG@S,ĖZ ؝*]ƪ+3A#О-e2}X(ςZNuMi8&>B~l;\arZ ˒V=M0h6 0g1M8c%ղ;Pxr/A;w#~Xg,?X=+O;V@0&=Gf)b\N}U^ w1XY6/CޡΖƊ,T|d3/KH MR5Bۀ Uq. MdQ#݀~9ݰp5%`E,!2aMu5uaN5f`jo7CzBP>>1,(cbb8%1uPvuT=p-yxqL4_|l1=sʙN'6kx 7 9Y|zLggi1p)2Q`2!鏥xwS\;ۜ/M#C.~bo/$?q{`X 0 n>, W?傩$> 9-&"1Q&r4o?iҔGw` a<0gRΰu7Wm!f^L@='4@ئh?p/ڌ/܃UFɗ-܇LF/KmYY&,B ;Ѐ=io/&o({c1vn^~#0Ea4~==0rͫoǼa=ؾCirJYzv[{6Cyaʮ4e$tluc|&gWiXs z|6y>{V>Fj=e囀a޼y96a}MKkt㏜>,/iK TB &2K'%01OW>\r5!{^`7VKYƳBg՘;Fã∩ Tyfz]HZXԏ`IGLI{7aj:߁{#~ FD"u2.o,yvȝ|5ZccG^c̟Ҧ7!WFLDZ7!W%ӪuO1(ceWB}&G\P$OU=H!D20K'ŠY ,A7o8S5 ߤo85Sou{^WXz׽. L\f_/ K X M`jLK_3.Q Dmrp!߿%`|Uf{h|>pB~E.3: /9s{xnhp宣NjLIq@j j d??Ҷ~e-)S&k+L}gǴbkڪVר炋ybI 5s}5bfv,UqLů:9(( ^kVje/_ aƼ-HYu6+cxKϤ"c?΀'"f3|:$9xw-:F֝qS&ѭS_j6GVNt8߮sn%j5ҩh'/R/Wp51lc1cj\P(cK=_˸oxuNIF½1- j3$3v#MGvLj7F]us RfJ-st%%9Ƴӳ#XL#SgtJW Svy}&ϓ0 `٧5İ_@ z iH qqq8wyWYy8F{!Ip6+/ ׶jw Gc?+-tذ: VbDV:60ZC c6ǸLnyrJk2u cLhk<,ve'SiĝW#g0gz8.).-X~ T) }mBLpmVHY/۬6*ިnb ;*_ OvWXT I\cbk*<.a' D}-8cwM11eغ~.n9.m:ft=eCr@ gmѻ#(]:qwX%Tܫ]?ibn(ܫSkg=ڡq<~Okj_{6jKƾ8/wGQ*;rU1;k>K>b {?ӧA[{:q:8l]9j+L^26f>ܿסɟA&fg]+:)@gc'a;ck`nxԑ '߽ ɓ9:qNǬy!Cc>c=uOWY;Ú} m<7vBT'LbHNfTeKms",Py-m<]Peo.dO u{^Ȯ֣XڄՌQPm8Qte9Ug~3KKVH<"Pv&>? w<̪GB5GXv|ݫX\L[3%MOO0jհv`Dy oY~mVX'"S{w 3e=V9|1p$?jy}j^S]Ӓ@70ƳejCc< s?<#TGT^sI Է/z,t-@zc[;O\RW# ΎgL(M1ݭaڢZ劀Nb3p"mn@H[,2oS͚؞ |ܢu|+ BSDt"$J%CA},BQx"}c¿UOa״~@LQCzua MYo?wƩ.kޭ*MI@+VrkX)!Wܫ0ՈAxX:*r'`ȣV1K ,MCUBʖqF<Ӷ s eHxhLO Cd=4vF_l:=]IؓCr%dpUoRǡQUWRK~ˁ|S}ܽ1էEلtDlTnLI븦MJwQMۤg`CL&.rQKIyR+B5Ո1K<8(,XﱖrI D0|==zZ%#D"pM tUց|og"6mo>|8}8r;\7|ۓ~_Sb{yJn|H# DTbvX۸P\L&\28 >P[#q>sξ{T_|%aơϗ0qeo凥hoHqufɩ@tKvA/Š1?3r+ο{_)U*Vq'JIyleb8[(ސ\qyQkXls-ŢE pn}#CN#N )tHyWv hѱ5Z4AuˣxNI58+Sz _"ʅ7ǭ_ō?NV:⦻8QƩpW%%Z+\xXE7GBGEp'tuVze%Z|I"*r\il[׽!Ӿ#y^:k3:+)֞cBdĢ;2hnXq.gjTӱe#_'P]{=Um\Y,vn{ p?W6uxU>%n*!ww/G8tސ7D|i֬Wc{ C`7 %Հ_evב 6̹ IY?(6D1p9t< 8>08%Ng xCϗ˕.a] !QxK?=;q]UMtx?[=ʱ+ Wn}9O\[ř;י{zrŧ%Vq׳L̚>>]ܨx3Um99t6,HݷR<8ssbH4S;3FT5"SKaFϩ(9Wh%g\u0%W|^-Uw .ǩKޫ4Wp1Ʉ*"c*۸f`hm(.>;2ʚs76E;Ъc^Ż1έy |rqk%i+*Lmn }3lO\ n8],p6̜' 0 ec%lPʔ0DC0Mm[-L"W|c&onYNpV.QA:K-r?'KC.#9=V4G"@m\޿4:"@r#A7Cc 1%'{64"@@%&`wJ*.&'#Iɯm؞Tn3/림yg>u7$M.`G93p -kEΰfY-bg!NkmàY3p cbq gxG.μ@˪깍#1-׵7Y4vҡKRBB ?sRR˸J8+#n,˟cN:qGBS2 7nJ(,vc~VoU4IGLJ886zG9cn=I))Fpp1|U\DóEFl ;CrqVw8+uGnȽa)`NKšU?3xsh% |S 2$g+"rqV&W"gm7,bgX bλ74.KMq obF74i{}8&9_8ns 3q;sgi{!!$D6v6) kޥsÅۯEȚpVXH8Ӆ\~T[F.mq[%TPyB.δv኏P+₩Vm̡돏L:KR^y,[*Wڐ-I"|LK~h-+ȕ۸,iE,N͑ZOEJ3_MgX[61%q*Oum\~b<Fֆ5aZl9B.uK7KahX' (PVKyi%V_?N$:ړ CT4lތ2Vϳ_͓唿*Jʹ.!mb_ 2D.8'zN\p̽H|^ : 3|'_`&&ꛌ2*w,juxU>%n*!œd\t ;&a0r_Q7/sqKϩXnjpt @rqV1-%O^Swg^LUazO]}\_֫X{uU=,UOW)n0Q {L\DFFʟ.r#y$(4}C??0MN8s]0Y>7G$\^2'~mm1@>rqVʽ1-%O^S/g^tհlZnIHuܙhV sAx'B|feo,a.d"w{½)6ap5#j?`_lk@=f]gL=*Nz3(/r?zG,!=G_= 5u[nm\lgS8O}wO"X(KtͧnҷJ=sϞ57GV%,Qy &D ZEwt6 W|8כ>n>Iy}?kǰ_6Tu)9 CbuH d߂Cw`.,۸;oabs gvmﻏC^EoϓsܴcZ G_f@vrw{ 8qg7 ]* ^ENN̬N4Anm\hM0.3?=ڡvY~&y3Ose,چw5FPmɃ=Ep6ː{C;Riΰ\Ě{q(QϾx_+T3e= \vn W|Z"mgXC3e_=.5|V^>11f)Ƶ+6</_P=-;ƹ;OFx0o_0}Y<[}1ƶ" 1ްtXERELK?#W|AZc-"@(m\9A="@(m\>7|ҁ ~Sb{yJn|H# DTbvpIgq21yhآWxhD"@<#`gXl_9QT% |U홧qK$Wϰ4 DTV0氻gb᤾I6.fWV64n"@ PVC4fn/[11јOq*"@(7TgF5DXUn<B4"@հ"7'F̞FloN'D"Pi X kqk6йghƮ:v "@gXC"#)۷P ۰!"X y ,I"@@$`5w xoV,VFQӻ0^thD"@<$`54T 1#='Fc5D|!&8 DJjXٻ5N:FT $eRaQeB&D"P**ê7Q@T0 DrGs"@mEnIL}EҦX*EL}EҦLm7 DxM=֌q. Ѫ]cy&[!D"%@IDAT@* a-a#[nihl]Pa"@(% K6c션;VfŠ݉TMՈ DT>VÊ*4Cܩ8\hZY3/7liC D"@kVUC>H.5?oVZP$I"@`Xodkek>NH^! ٖr>kͦ D"CjXssZp`F7k;C-V1_2e"@ P[Nt˦| 4ࡾ m_ D]6Z]?EqU/RtR& D"%`5Eam0ϑce^âkE$eѓKZhM Da5pUa`\IK DX \G*B|ݻ׃.+*qɓrb -d{<"rO-PqF7aৼ|F~>E3Sx!44Է5ڌÇdyb t;%T"@ Ԯ]_cm="D"v驸4kc[ LgF"&ī2 D O8c,yE=0Դ]S|qf|`]C;q:TeQ"@' ժ+ع@j'X~-t_;l_ D;A-Qo`FU Ѐ79s!w hm uN|E~ D"@.+0kގ)5!E U3^VF$D"P 5Vb/ޣUb%q1 $"@ D]Q 4cFtr\\X  "@ D@E (== y< ӯJP(5DVŨy츔`3u_oIJr D"@>Wa{l7!A:GbW1{u{z@ D8 `\p]Qs8UԔj ̼ڡ8!N6 D{Ƹ8˖(I"$4s]Ee"@Pw*P j ,Q 30]r=_v.+Y%dGEKh 8m#Mʞ}lNݎv7Š0zWnLyx$_e>ajx{;d.$jG2/{351lx\[y~gNoz[ڷm'p2mLƕiI9!(4zv\rSOX00d|u~F7Rk_D'k gaϳ™,eVW!Su @'' 1:V?0}8=?كI«HlI Cgc{1Zl#Dr e+.gFάfƢ:+W-e̒ڭx8{?gd`vwہSCsaTD,UQ9v~HKgO҇#ʁHYdla10eJ_6Dxqֿt0& y mת S!J@ݪB|ْ&ג[ KF\\2O*NG|YZHײ6%3^M٨*Rn$N\@"hB#~ .'xn!NIb|߽WFm7#go?`-(2fwΝ;˟.^òJ-*)m2F*gvX社c"0]ugm jod~%$X*GV~ #lۗ'8a'q?0ՉrYGƸJb"Ǝ+=q''O%KرK?e+2z.Q ך@n>鳞eNԁ .f. *$EC eXݬ}h~Ÿ<)<ɖ3~~*NCa}lr6[J$ҷI*͵U'1Ckk\~{/KJ{_lk:®_`rr'{T:y{#Im(sgϞV\Yv<~}&ϓ0 `٧5İ$m\ =. TE$=gxQ(R0lkLtt0fE Y2fqH5?}D%@WR(nx;QMйq-Ԑ] .J!x|bL1lpdPOuI{{^7A#ˏ<*_E*>|ڰKfߌ:'KokDZ﫺kޯloܯظ,޴OK_A ٍZKy}8[lzu3K:"PQ躍 b g!_@@ӻ1oOr_ܹ=Xr79DIl]tG▦7y b@+4R?c.}y~ehξ !!a!9 -:`4Z}=5UG_Y#%x^tߊ}ٽX֯jgڇJsq*${S8ĜCU5z J HH8&E9D}ɞL^v .7ŋG32'(HY؛oafHǗڏa;l ]k7c xmrpېQr9)FTlϟ3*_V2/tq"l]Iǥ? 6{tl"hqܴd;.ِ /qf=pG؊F5rk6?MMτQ,|6yN^v"A=oC3~j|;{ZfL΋:/G>Ojy<oKщnb}oz#[p/2'U,|zc 㗕xwW%JI"3t -&1)K,=[p=Y-2_:aⷋ0Z"O\|wލ>:ֶ;JTtT7QHU4PiEY|#:Wk&=cg,f'wk▓"WX|aTa͓aִ(C-|!B88ڍi'[߿&߿Q7cL<6~usa޽xݯdW^e%r9Hgi~φo|ՌC (, DU#Pl7Gi Mbq-Sqb[FDDx7&mvmܵcO-"@5 @ntj"@*.rWq-"@* vK4Yk]\D#J4b7C˫  "@Og̘%+* /Ġp6g R=ğZ[hO"@D b}-SPbŤ@"D"#fg{BCp1!5T`RJ4tZzEj D(n$_͕}X&܍::\<@O&D"[q$n/oDZTO<㨟hov"@TW^߁˶!X,}+._@ "@@i ӐOD5Vf|Arq屛ͻ֦.V/mO D @8"6 °E0ayFl nMU"@]qgs9=,lr.!.Qh_@[D"@'`chy*>GT˅ D"@"DD"@< @nYBbJR&.[MKFԷ\I(FY]^]Y%@OD CZ " q213YM"@5rWwǿ|}" 1_s/j &oǑ,ޟjH>ܥNG  rWg0.%~zڿDB!Rb,owkF8q 7a#aL" 6,1n^.xA<<wpΌ2#)P D,8tn,/%CQ+&Jon>'vފc M ܜ4B߂'71b]))03ʼ0̢\Y;dIG.6#0 &J(kJ8u6cx5xmnG{fTyN`umA,1ՆXvGzC뉴(wf]u6H2x9hP;1lE ~ G@8ts%̨ nlWrP p6 kwv0;c5 _$jG9je-m#]s6 & ܑpnxOϊg0jcz7 -~Wn;x-ҥ#nr  QnLscʟf2)S7df4 O$nupc "VyP]-2[^A c >*9oGs1G{Bmi!O1t£P;, U<Vtpd,*يą6]*WU6zaLYizKʗyo^~QaHcv_TT$Anpb1'Wml?1ǭZ7 "][7Ӽ/g8,WPu!nR[n"߉w?:eٯ̕S L|cj\r;꘯ cR甹!"/JV{bCn!3̨X)QԿ@[*ɘɥ8+c!4i#TyإRvfly(\ݷ2XN#&Jyzv/a T5bޕEUgT@},\3/RSsi3--v._˧UZhbiff /(**ʠl?^\fa~wιg?ϝϼgy_z%]$ԏ_ɥ9.L,br+ +B>Fn֬YT(!b 0@eܑH})z^*qN^F#;-?h*9Jpmc[ ?nS "\"ں*V`$k(ZFR66OקGtccc!{o:~ÓTA6JR\S.T, qe~i:z,RDƣY%IDO=R];JUjWs%YG}I9?_K^qLY4bs0G鲓 xf>󩫤jIDJ*r]CO)]{݂#'jDiەr "Yr4eLTo7Xv;伮N_S~o[/lRqo{f}?´sxndwsq~c1zxEj^槔rDn4qIdx"ɦ0Yd>C,9dڰF/\Wt-~\zތ r$-1 c-1KtCu{42$nD8Ӊ:%Rgl9&Yu^g]RtҀȘզ:<8mo7dɒҳjE9:aOtk& }s[kȴ ?bS/?D'Ϝ@xIRJZUD 8@mN1欹u(P)H>k)U W&X&y?yg(+Ҭ&o2I¥*b-HfE=&ckO% e(nOGZ!O~0r>w!{RU]/s@ڛN?`OIGɔI>IzG@(ɒhܥdEdzsgDJWkMZzF7 ZS6ꉔYaΟsLKك ,2U,Ȕ6' 8[棔NΪöG76!ϤnvvC8i&2B1],eV"hGkǼҲ(=g,Dhmd}0V*"Ev)Ͻ#U+](OyXY&t $Yr$:[ێ83[*ZpbOSxe #%ܑ=8l^nHTQ7e:ϵjJaT ; ` u4/ϒvulCL9$Ktom1o>SkA[isKmC+uF9XWe.0S6EN :,]hz ҉`^а9&YOd)'KYryuYz>')WП/GgkZ`Ǘ5I|n9駌 .k2i2bǿ}<=7zz><~nh::6q]\lT:r+S}Ӂ1#1ю)a'^%{xUZȁIş)[\bL/a0e/k i}6QM:Ui듊Sv LNJ1f8p@Ӿ)P}Cws2I2ʚݔʱD&c%7eg 0yej,[{zHX%VZի\Y*ʌ#"Q;X+:2$S(-Ldӓ>L\[^.8EcY1vڴ"#S NaÜw?"v=3S#2v-Ó .K)a}߈T34QOa&6ga}VQY3޳kq7{̈́T`0o; T|[KF|<&Cg7Lm|yjH7'R!a҆JtLEB䭵0Fr0KO>kxK֐o0 G&$$d)`"֓0 eLo$b"P@ sDt|>gmY:WK_M?c'?R<'Pa+ajÞc¥4==1;"bJ[]1=^%_?e̤qρle ~f)(]X?15w&;BfB qe6j^qCu00_;@MRw`lpGkڈ[bgĆ:jQ[Ili@z9~;ŇWeы!#$UvΚ򟶣:NO?Mw:!K̻α[Y%RIO&O綬2HֹȕT@ɱa*a#?{kiK>lO&\&bUR1Ljd{C%=RNҧKA3ϩ&;rSVV*??gMmfsFujw_J5ë&۔ M#|:tǭcih[ 4T`{4 nޔQЧ?M䓿q b_堗*]"]/ujy0 .;$Xr ETMPL]ە}a%JarftO7`L_)+&"mB"s6Jq7rL;Ltd̾>%c}?]#C *,}x?0% ?OÇ4㳦"e}W&RC+Ξp<zf} sCP' ' .1ܛn_,FN~ݫgbd"_N_hm2Sd>.RSބ/Keq{PO<Xj\NlIs&:#ێu"ԨT"$g|y|>ae;6YgtrQq ZZZKHD [ hHm;t7k˄$[B~+pO?sWM:~Z#m̺/&|6[=?r>ҽӸ>cLx%\ph6.C.%/{s鋱4 .0Shv|rHJ_߻ܖHNA&XC/նMKc"]'Nkřsq췪kq5$:'Ts;LD4ꧻk6r{3,uS~oH4 l\`Ώ86)R͸MrIrLOhVöor>zn Sp)xݦ( kQ,HY˝ddY/&G/'žYz{<^erx), ND6*ߠIkVEB6|铿{Ss_LDYOyK|oǔql&cYXs}szd2|/oV7:4zxkҦ.tyiK$PWka޺*K pKDµk֦)}+oɕ!8`tigҍ-6Bu4&^x~LT#x\[+3s1'Og'(;"\rRx)MFhm]R҆| @@-4XUoӏk};ޘq?$Ea3o\\;:Qu\NLDzP5TVaͫ68ahwm-L#[7;&mO{RY)˾qI۷J3]h㒞X.묌\M6rlF&•?=ٲ/!M+~5롶"3MA[k*זvR=F?~%Y֛>c, ~UI$"T7Wzc6SNMʕqAwW^'[I]ct=٧iJר`w3Jky՞|nkti\mENOԖ8A@fTi58GAt$ QM:KCe*Z] i]R&x/TLxGaptl{_Dі,ոbAǏsaڅ:݁Ccbm~VymNHӨLTD!ɛ/0#X"W"իW3.wit$%Z*$dtI0=: Zoȓޤ*Uo?.٦un¤w#謲]tcA2>ODe g״=nk@2'_Ei?} t/ۉ$q*ӵD;K{єkӿ^e6-}W7e1${pa*e lOFN6ït ϫ8ڙmJZn-Hst;f*ѫA5$Mk*ccM`LDg>fۻŖCY 5]G7Ћ^JqߓBDhm0Z*t&na&]jwZZQ>m6lFM_)+v7/4dEFzzm)V5EAV6smW'܊ 쵪P^ SZsuGłt Dt_vqHj>@[64絷L"S}Lv;?F,OT---UƿE,rR-oUv䇥WΫ$Lt0!3O‚@q!Pu~.]W?*Li}3j| 5s/-}S>fD|vL kHaš̶v>i$dCRI>i kKDLTKAz`l)MW&G= s^"^GHQ)?sNuwy_Yx`z5=˓a@eJJř50úɻܡ9AA; QndY?uOO6:=ٺcX?v,$ ̓L$Ls9Om^28p&ͻWm>\Ռ{Y6?FF= /0 w$ _F?Lѹ{ =l lt=Aܮ/ ,KH؈=Ejվٸ HHνhAԩ)#T僝86h%޴gPmߏhZ.cġ%FܟPS~ZFjk Ѯ7`w\FԦ~n7G(&F?=?$4LK$,R#KoCqk>Ƽ}f\.۞"KMv/UW^A/b 䳯+oRÄJ/ ِTtV1;'[EikB&RY_&PnR-o2F6C˾>Mf8h}</9KHX?|>4lf㪠N LIc!HӕnJ***oH?Xِpze ɖ$4gd*^tGd}|ī-S^qEמ8BzUhjEu9Ä>E-)${5ƉA?2. 3Jʹ=rZ&[j9بrzQVd3L-5]= 5G}j7"@JpGF,~@H^,(LV Y/j ly:zr CS뮃lz:Vi^-g4T]FBu-$zIWO,Rm~뵮l4GժfczJ;t2&4{r)RM*پJ JD*K{dko d[G~XCiQ2.R&̞h{MHcռZI >ۣ\l oىk6." 6X_ӐXmAFB,HЁԏ*"~YDY^-#?ܖ7~ v"h'80eMMÏ#[`US wbĬ*~%agkj˞B_#sR_YHyj&`dlf*+O7|PߒR+{`zDd={sZnUO%1`mS4ib6^@ZSt=w.+_"x t͓lQGᅪ1xG9j7#K؂ [<*Gz% |l\zPKL<ͱ3 Q_P3H '[pBQEu]k_N##:fk?L%Y.B#s4~k&cӯksuVD_S]_.N"$]xݲ;P:*5nޟ]Ucq$=(wQՔ7 1S{;UOSA@(0R|-R>wy\rz"|~^>oE:zk'IDATjAOSP{x:}jOƀѤIP{~5r ZblzkRQ?ش *ܵ Xm dn46 _PM/;MxrlG/`*6Cw&Ҏc2W\IS;@I Pl)$>K\A$[{m.1p/Q|^e I賰3EXXdUH nЮuDpB-&gy*iQQۢcwGĹNӕ=(㜪z%ݓ=b7X}}3Ʈ9D׊j̸!?R&)aFJ|Ap %\WE{G~cܿ௭qXp4# 7H8"1 ,_ZŶJ5o"g!Llji[m;Jcj,ٝeE3ދ8]|7Nk꾩BM/o}aj*r0*Z2!Ǫ*d~U fC!AHZ]etJUQK"e%)\G@/r)=꧐9ݓ~rrpm*R͏(Q\@W2l«+훍^OcϾhEhkмS^5$/LPm܀`vح&0ft-1"\GK d\B@OI fhɑ*CR~jH97oveV_Gp09@aȖGq$j#^_feRڼD#.>GMt7\X%6&3‘߾1cmr_vpƈ/MA9NTvS2 3BjKQ/V5kٲ*jiUK;)g/Ő( ]C? ߁NJUtXU'4 ]w }f*eG"xi5^"^r)1 e;^P+,m"m:Mu*i5g:cpTLl_zsF @7b(? +Ga;p֛[7Fq-Ra5WBRr4ZU7 < l%1L**N($^*&U!^FFt4N -AM^flNS;(SθobfC>_^PknifUGoxmH{{.UYV획֬1<o^_>}h-p+PI)qN++qIp7_BBFd侴"l-J-WTl=?-#7:W ='blh1EU<ۨKaRqFRo(}¾v'H{ew`6ΌFw࿟ @ʅJa/Cp%$Ā\i|]'ba'JK g&\ "azyT-x^|#eQDp3/#xwQ 7=cVqi6@[j:g s_9*DS˓yNg:pCcWŊ [f ƏF!U;x]LhHt/[6mi0`@!`Kj8#PeA9Fޝu7V6w4%]}6HF޻pAGp9)l.v<)~F*VN/읬*~fp׏6XRN09:6 nզ02m6w\`Zdz܆@8@J*NMzы7VQd;7i).q!Ю];22+$rR"zP4ԫRY$]{.F?\Ru_xlq=T4j!)YTWj=}~:g]x:#Vo+ TCӅLؼ%`/1;We'Oϡ8opC!v븇ѥW -VK\3Lw֪[RHY'VO</tx=d zvǨx-lvƑJß=CPL8?؊#@-4jv}(dA̻C1OԷī!99Y$^O=ó,&ًfd a=x*6DWq:~vAKb EA@Z< L'Qr&ߋ2YH)y~W$ޒгb-g`uf,QO1kVaC{&a=S~PIvQ @!x-(0,׋tZgqڨ嘲%ٰ #,yī,f!^=:4CLe'`8aM)Iw2v\.K5l U=azCv@j4|=זMKFMݢmBM}ڹ 缏պR piB'@Lmd:8;E\uy%|:UPM+ܾ#i[;u=K\ Ft \~ԗaW1a(ϺDxu_iϏ j70.zΌo#-5R1'5qLl\5~&{FT9.x@ .:.x FAr*zy3olHzU8ө`uÂP1* !|C_B3&A+cpG0条H N?wޅ?Vi5 oRy㗣B/unD-]~hDT˱k6nx 2|3M\8/Ljdb )[^2U].A2oexiG]z"vT~owq)&+"l:n9~׶~qD?͚rd5yc-bU /hodFbh %쿬h" Y6-2RSPTI=cg{%܏@Ի2[RNU쯚aMsm _I)/> TBf{˖(/[z;XwgZ2"r4Ыk~pYMfd,ky*UeRjѺѥ6T2_%O߃څU/?y<Ή8IdD b8Mh lpKƿg!>#0kt;˾/o*iu> L# PzS糆)VXxZ?gMG6>\Qliۊ{)4:jy!z!7WJ\w&{D3)$qb B\Z~-?A&sK.n%֢AG.7J";vh? 5]YYBPcnTfYz+8A@@pBD{WT*?3W*a͗e丐HWꢩ[wo~;}7WTx\v@ϼ}9| :) f\VN:2rLM2' T A Hf 3C8ED4LAI >\s7vBf>ʪr>&F34pXMٚ8 !@!8~7O]g+}v7>C8n!ZH8!3g!42= Mנ"U,K6)8wz]d'=> PzlUwmgVWteY5]zdUoƂaڍؓ k}*X\]V& zzj8A@\A 4>dEZR.gX1WSWJyg1:S෰S;X]^?F^u7bcVgZ-¬U18s&-@y@U*՛7X~g8uUqϣң l\85le}g.^Dz ?A"`o-˃{^p5(`Ȱ fLLUz ALAf ]t?O?:ؚYs}9A +2eQ|d P~eWCf'IF_ 2RWƕ')A 0ULب_1%i%lK0I&A@Jfx9j6 Biزm uFu1 JGDb0lRUP=f㨃 ioAoC @IS84gߌҼh+G$m  &*Tm{{otWBM}piUA@8YXf#!B-gR,NA@A8e'5 生f3oO5, ]q  _67]2gjA@r!Mkf&;vFKSɔs鸜M>HP` /r##s & ;vYll\}1ZڮH(wÐ Neul13?;D "B]=' >W_>6ЖO,yΖx1{O£64W5nFM\ Yss/L b ò|1l8>Iݿ_>5&IbؚY+̨oÇ)gSUH P =z u?9X:CZѣ_~Ҝ_g϶֧ i%N3Z?j,P u 80;Ӭљ2ǿe0k69e^oZwEfs]j N**j՗[VN+;w^|[q;sQ܇<­7f}xܢyꃡ ӲvwrקibT*Op/G.]Е ꚠ_]}uSWmuUEfut?ěg{)&s^X5Aob{b/_륃W cT ;>T~8 a9:;_EV"FÚān3qjwc?Jh=̠2oo]R<3>IDTT@MF- Cێqji;rlJڃo]4\ UG}ym1\<߹.fkC>F8|0.l\`8S:f ԨgbI_܄~RkKCU_X,7ïͶjJXSV1H9D =s<;E2wi+7_]Ҕ"kUtW-yRmKZN+͚mki}տńيӧu+xSC4. #5o_'}`Nڎ +Ү ]bv|EtݭIJ4~ `C (Xe iWM[SSkjmH B^2F:4FI~OkJ=zi.6+v=4}-ҦtwMJu_)OTkAN3:A:Iނ$3NWz| ef7Sh,x=S*;W-to ǜclU3v߅z-Tټ_/~J!l[1zNx>S`P$8`<)1 T]>TCC~I >%E+w) UZ<}6 An26[V݈=Id\/S^X`1~u-6ĺ[0! B_-H1f`AKVtxgĽ=4G닠-c]`E@,Kv]V}g ,-0 9~{H$bZ#% HE50s eXlܺuz1[`67؜eYnņcBe+QGtQ#6r|ԍ~2SCm2_./6W EI+T) xtSgꉷ)845 y=9o6y,LoYNݯ[v ŀ(y8~O]L(U6=iG>cĕR6rNݪmtf]Z;mCdU~um`u󴘿[eNdIcs\+q}5/xOc5wuXf Ə*.A\NL!5݌t5Ռ 6V \51v(,HH4puk~\j"N]HQXF ]_( bccm6{ej^i SAjhp/KmD|4׶@j5P!cҔ(λ]Ԁj[70T`Vƥ PqIA@+xRTA@0" f㌈Ƚ  8s>aТqm<˗4E ^<  P~ϨqE]˫uӏvG'|ϱXYV4U'й8C<A@AH80mQfy'ӻT$عl,EjT  e_2GSRIfm69$ :ަqm  #sFq)Jי|Y MŠ`+NՆH  P!q9h3h'd1/¿j xtXG,#A@tX@f-qX2~LuZb۴.?+ZBA@(hSٸIbE펝R>;Wj7@}mP+q  Xlf;(b" RŌ^ qYA@Hޥ>c;;ϜHX[2!NA@ u&oj⡣0+Y>&֋8!$1 @nQ|g =A@q.C%A@b6,Qr_bbbкu" EFD~/Cc ߿SCq\'/Ou><د\Yl9F)+V`ZpܜLS4p9+%:Cpi&uҥCq԰o,HU9kB!eOA@A|#Cf2e6@ ,}HM2.'NA@!12qXw%3&F#EV*TtV  ]q>q &)2o>mMPi,f  _67];2W!TՓw**)bΜZu$  fox^` MWť/>x~9qF#_AOA@"lY>t6;wJAE~A@Yre:x2"Ʌ zgJ;  ]D]X$RA@(ٳg-Ju7x{+A@F}T1\VW.BO;d-Ym}-5@ԽJ0u/T`*X)2"%tP>TFL|iojꪪ uUR\|2u@' P P{.HbMT%uJRY>-$Fm\A&GiB! P $n`"WHg)yTS7\2RTu1RA *  ;X$~$SS8.J%V.`T)XA@%̓$J$2- PFL)#U@LqA@r$]zɕȖJIXSGQF)}޺ҥpe),rÑ*l[2]C 0&@@ [R~FJR"929rN~K:Jyi#O-lQڵ+9D}Q,_a{wrƊtഓ s`|9|9΁믿piitڗXĥB!jp`L 0&hz4ֈtE>|X`L 0&@X%^U!^̤þh"l]Qsf{ |9|$tqn v}@YOZO22M1>׿:L/ i=Ԑ׸ccymKio\=G+'x6!( #Z/0nܸ?#| Sg֟r)b ~kf1~-SmM96C+g^:ҠeS4 $]X@#9O^WGN"A7~x $G:TFwCA)IqN<-U ZmbZԡ07UY[_M~Uƒ:Ki-~w]Cc:{KtlOkoU^'kcS}˘6ZrűUؽs7Ԉ'bkhhs)kc~Fe2&4VY\:ӤFVf72N[HI2Zj)m/<7o+mp>~eL I+\~m(ɡT%9^''9ׅx; ѲeKEBŗ>ZX U;cI=_Wbc9N[߸G3rH/_ (،lT?ND.O9kmזjQԫtIƾȗuH;~㳗LRC[krefCCm2Rz9K$27.e"NO^ |ٔ:H:MނbOAʒq=~a ;˙a';G+Wr/ee}?0^}S)H;dR&l'RU?XIBO$c=jW7eMG%MvYOFWS˲yzm_#Ȭq~uV.uгֿZOiVTGֶQ} y_8ʙGRIa}PT&Ԑ.gې 6Nnǟ9UU䴊R`KeZ=MnKЩKK;z~mFO^rB1G+Ǎi)98g=#ݝ~ZjYJڽzCS/cg%ɶX%eU4o}eH*h$׷G-c}/h|(qK)-VyikOFrL5U *eQ1W7i>vXIy(RCl3wnB\C_~$$!(4N%\H}nk]PʗyZt ӛq]D`iKF{5zči?zS,uik˥\E" ;F&Q:ŧp4貴3ũt"y> qv5'KOOW._˓Z>dhJ-QFjYGE ]X|N7G`H>]R~Ab(MBPn tSZ*PX9_Wim%Cc#A'!9>B^Mu+-9ewj_-iFgmw}1F@נ@,;mK2/mUQ#e6Rcٖbd;ai8w~^_'UzK$P%;ՕO!p?oIOxI?S I^؄]:ڂG=^M_2$Z^S5+uNrlTբNr3kW*ɱWZ_)C6=kQ]z5~ُ+/ʴNytM4 Loz$Y޳5dD]kEE%Ḥޠ+QX)}E.D+qݹEc {`i_]Ͳ_'$ӲԺS}i,ytLA]_bgN}r;b<Я f}<6wOyi.'}՟/R>7~S:TO0*rdLKm 2ԥpIK_Oi26Ϩ\ʑ~ KZ%鴫C1 i7q3*o$>/U;tv胫]UⓠC>'_0~K^ZkcFeQZ9]_8?(;&}v\ >OTNX֗iuOiI:HdVY.זv2󴸨<%v{~,E7]eBk1&OX[_ӱr\URbuHKKE۶m2u6-'<)! wdpubf'E=ѹ[e K*P)L=e~eLiqՁ X|YutпM|X2cAVu]uS@nG8Xx`{W=}5ĜviߠLsC]KZ:H1KMQ%'ЊϾZ֠ǰf9vgE4.U2?)s+])&s\^гk~R#UPzk,d裲ߨ}SzqLH"k[TYV7W1Jq1Wyzp1y / Ҳ QuB7e}MnO@)-qkՋk05J6;aʹ@(ݿ޹>-F2R<Ǚ qGqӠNpH}v׵Y.Jb$ȞY"$[)P̣cG:I?uYW22j{o,}(N܉<ٖb^W)GMS7e bu֓A,uZɶS_I~3]UJڎɈ/¡ '9R<ٷODzYSY&:-ȶXՓu(Ce}rjC8T9*qp>gi.[< eI蘂XX%SOTWHmR/22cO\EAm!as!RLA&STzFFMi/)2X]GI/(S̓m6T9WkKpHl(^>'92i<7kez1e2-e1Y=ɶSRP:Sy:Gi)4ZBBy6dSVDn*>i7~ԏ/m PMv!3}E˦ g}f F"5i)h˕L?m}UԶo_'Ñ/)#~չ/:|l_~e:7TN} 222X]&2z2n.s 7OFS5OimODzZ:d*iXg+u2O3~)S֗Ա2O/iq /JYSz?V]WiPOKR'_Uב}%ʡlه6j;Ndu=TWic=ma E"*/ېb:J'|Trx'&3 }q⚵7* Ь9L 0&`=ڵkqeΧ[C1i/,t}l1pq[R`L 0&'] ܱؑN:Mt7|s511qxpuM)؈m_]eǨ^l4858q)V~ÐB"c㘲X9) Y$b5N9=jnTw錪+>ˆ=R̭W\w^\-\G 0&`L#Cti= )3$8ޚ7(G+D#;: a5N× m|5L ǐ{Twhk!l~:!Q !v/GAy9Q}t:e;`L 0&@&CǎFtlZx罬)HO ڴU;wc$?x ם_|_b_žڛz?Sx8&IrXV&kQ$`L 0&)74i;t4.Xq4\|4W|9i6M/W3p5f1dl<CFS[5Hh=iX&T'_=@,vUt;ߎa*f8E-L 0&`loEkhTu~: 8Uh3\ JUNr۶mʣ DS,U#1:6ȪGiT1;#L7vIƂ*0*SStkS?6;Z:B5S54GFڈL 0C26N L䲸|.myV]O|5(fw?>[\iWN0&t=@WVΣxܸqx뭷Sxݺu M~3f +Y䊗/_ &(m۶͙3G<@}2o+Џ9\s5^{MC_z%Luf(ŋ1zhJ_J]3susP8c`Gnu D]^/9V yWP#^{aH=u =$V6L YG}hI]VUVsU_l.YU>СCQQQ{wuȑꪫUoÆ xp7W^YS֧OW}u?M?2fc,7R>]YTzZ{uV%}勝?Z/.SpLs9 YFG27~™d09A\eļM6w}W7@^^L _=_W̜9Sq4j L ܹkcoFp:J+Ys}9"FH#&p\%c#a13# Kÿܪu$%%9.&,B>t5W={(yP:\k555zRtMR G@K.p5cN΢6tAY@ u]pҚҕ+Wj1(dᕅPq$} Vl<&@#piaʶ=zӚBr!ͦ ;C6QmTḮҖC4O?)7oz*ĥma˚xڇ/vVƊKJ0G:O 4+K7+_]w{1 @h+$֡rTΝm@X @2W*#i5~*l/r 9`L i( ji "hzq@H瑎I^¦2mΎ~4vYg)w%Zג!C?+[naoO/ގ.p%creҋti #Oii7(!c_fܦ; 4H[>vL2ڄzZs"X~K6-b8J0@< 5' cf=i>r i֎FKRХho$iM!MA8Ҟz M˛u9n䠓Lr-e_އBSyOGOwfBўK,QON8Aq|A̞=[qilz)e !3g=yL Xt/a;zìY΅Ϋ~v"HN%k$Y$`)!'T>i7͒۴vSfI86'gSLirڗR_ lMTcCpE&4I2ДQ>Dt gbN4Rh #Oyʣwr.iӛn^^hFiZHN4IJ?hSyZ+K}r`HF{@S B.lL!@_!.Psz`)Jn8|rٙr  999H~(͜y\Oms$Z/Hwӥv+#Oyʣ~h[?ΧKu8h-0]C!=vRN3*@c:JHQȁ 0&m={RE= #O;ڐgvx<ݑWFGr~zEv, IN34c\c~q߳;'"뇧1pqݐu &`L 88pMx'Yu>,ٍr@?3EIPlQxګ_Ħ%lL 0&@@V<+jjQU й ytbtx4l:ǠgL 0&@ xq ڝO<6:jt>*䞸;#Mo79d[rM&`L כhpx<.D`ãbQIQ[뒏ǍunL™`L 0&#5H9a8n:h!2%>jM'PW[ cѩ`L 0&N@6;E]؅e4AxG`ǡ0Jiݩqih؝0?`L 0&vd]%~;Usϻ W⚰+ ݄aKǽ*'LJRT9dL 0&@:bۯ5_k58p |F{ωÁN 0&h-C=V<ES &, <,n&[~=o6ta̙x饗㜲ߴi\[2U&`O@ׁT,s= kQf"n:3[,\=y7˖-êUСC|>`L 0&yK2=5ԼDzzSO='|2k.5{n۷48bӳ*F ۽u9fL 0s 0A!b} `ܹ߿Phn$b:]tBByܪ#99GANN FƊ-FA_y1`L 0]V޷ӥ9L >}:NbΝbjj*VXuV\CuɄ.e`L Xjo֢p2xqo(+ZT4Sf1w Xhx EFvQ)3++ z<Ď;ЫW/1'`L Df" \=5p͙W#kZde~whh&q۶m8enT35>75r8X֪;IRRԌLo<<YړS1<~n\s#%A6<,)(pM7)iF1N܆X(`L Xa@:׋3[(:Yqdvb;a`7P]]+rm=6>3cxarXI[27"ܹsX&E.mٓgң1K9T&+G xq kw`?E;R&sL;Ca!Oƥ]37idM:UqFRo#iTn!S"R#QZkUJ}cND!T_aoʋY2cKt7&9QNL' &v Kǽ*A)NZ([qTX'&(vͽ8qƋoaDqmOlT(}!PHKĂB)w`L 0@ ^b$#/YKx+fL D1_ylJy]N@'xd&98d5ռh 'kxsI?_ñ B/CQ҈}…Aflr3;].CaV6*yAy m%)^> 3*B2&`~u +!YaǢhט_է%~Ypgڹ܏ - `!k34 t|-4 `' @z[hQ3f*++rh1MCׁL}Rkdڵ tbĄ`ec҆E؆{Npӿo3W\q֭[H3ggϞݻ*..nT3`Lxѭ[7߿?׽8d0/|A^nvnw` ؈;[9b|XlY1N Z,ؘ o߻5\lVZ:k6m䖥=v+#0@W_񹡋ǂjiFuV4aF ll%'o߾Jrɒ%Ld4]3x1gs+3'g_H쁱oȣeq>nD+-Zj;w6j{n۷O|lˆ#wsSC5w|n7WNBH^Z@tno To @u Jj޼y_e˖>=bjp`<0V GŕaȶڧQ!dU#>3:%-&:(ŜrL2O?yHNNƑ#G!C(n@(* W7͚pGs-YsŲy9w}tHI֑u;qgaOqڵյe]j۲]:FѪv^^tMKLMMŊ+\y[nUK:ԕ &>jQm=&/N=TI":ՁT,sԀ|cH/\ym+E;v@^0c͝ތ@'roHm۶͸촰3؁r035gff&uK_1m4WEG>}n0zh\B8Xs_=@'T>"X{>a„;w.20DZc)G@#oQ;v,d[r.qnN3&rƽXվt`M'ЩS'tڰZ5.t܂ 0&"FdLya>._Z P׉UGqǜyLy Lv[0*֖ˌ  XhJwĮsǭD 6lنkμs"kD[{\0;57@Dʚy785!?U&@= Ϊ{@&M/x7#oʾVЦ]b;B<`L 47xdŁFi]K$&*:[$-l\s.3Y׺, ZI7T'jCr_bGL*$dcqԏi"l|'.$.`L D)m֋ғ% fyu ~?[×=@qm:oQٲ_c8.Y>`L 0&|&Ձ,*F7|+Pc߀ˎ+,M_ 5uF0!U0hyDa&b mw7۶mƍÇ_l(c֬k#ؕɫ?bwC.F|ZgtJ>D׉{`L P.P;>P> xHQN)+t>}:fΜ3 $m4⬬,$UdU|hҗmpW>Z]9^nv߬ڞ{Pd'_W bcc^GV޷ӵyL O.St\J3'x"zQ>pf D SC>[A P eiBǍ7ވɓ'+Դii&2G/wa` $W_y Kp2S\rVVYh"|bYI-[5˚@o2{k2#C>3*&;eFZ,HrBz񳰃5ZOVHKq~G<15?:cj`74?̾[>(F] s=t`LL4Y@q椋2~VaW``\`yL 0&40ޝ_k$7&-}mʎ4Y_&"Iʽ E~ۆ@3jlgTn$˙@s @el:]x>N>b|f2+׻;@mdL l&W oW=geVHџ@5,'tW?E#kOؚ6m2P*&ʻtA$`Lx Gut#3􂥘=ӹzm=Q](s$$2&`L @4LkWZ)} -jp!q0H%k$t&`e@m(?} ;ܻ:f);cH_/ZY1&9d\wOñl@3 X||"YV3%Łt֠fzzL 0&.2\__.\Kl޼9ܸ1fژ9HOO9cL 0fH`2`O<{YGV޷O0,<ʙ;w.ﱌ3#@'3Vtf-ܙepQSw:*Co]v駟n\؄}sss>WeL aT| `/Xs'E?YSlSPgT*]y dH;v`ƌ7n\: dݍĥ>kiǟ(pل@[.<6 1qxj?r8X@m-/PL 5Cj΋o ir nX?g}!3R^*Kx/5?/?/}?j_󻟍=Y1oq'wkkc3ggϞݻ*.ͮϟE)޽æM0b}֨\>_c:@wyJvxOmr+M?×u`i ALOWRv~S;߫MQ9AIynѱcG{J!lbL3Y;w(%la_~bbY,_ųWVF8rO9a5xy8j<:%@jj*VXO)V\CdB úux;& XD!vey̰([oUmիM'`̨=H@ն@3j߸gTZm7&`M3fڴiV>k.D`L rDpS&4dmbLUFNLk#YdޠY`HԽܩS'S)C\ 0&@3 @j2cSQBqQ8/4`#y0-.9vY1pwO< (rV#@*:je9~taFHZn^xG P>(2 }…kPyf5fX:33oz !fL x dFH}'LTsL&L'QIf2aj̍`L վ;:&f-ܶܙepQSw X5(AWv 1غ *mpǡ#tjqd=@T0r> H?_ñNrE?YSlSPgT*]y dHs?P(Y=//ݭȩ?)7\>\Ƿ]pԫqB,N1&`5p +v~E&\U;qQUZkׂBdŠ,X+CioE+ 0&`ʁ_GX={D޽Ijrs cEϴ4Np{mtzޅp<:ʁva{"+@ 8hДK͛c׮]kȐ!Q́+G~Q!jhTU-/FKnbo/+q:j5&dL LhY>+(6PF}Th M?OW^'g 4k. *ȬB+Dvtr`V)EeX,D;y6<$j~Lּh/iikH@˃mOF3*7̓@+ M휶ӌIPTTdc߾} d9xs3M-ڐztpSȇǂw_QԿ⍳"7m۶aɠ"z 6mr+6,^ VV> vxӏl|\2ֿ>+VW~2:T;h ATA{.3JQ&+:Y& re#Ȁ(>A7`La˖-Eyu^hEӕQʌ?K@[m)2E\||ND/gL׭[gguVb;50<SN9Z M$W<Ұ4HU< L lZl[Ϩ}7oQ`gTlhQ\Ǫ ]7Lyd cdZ3fC5C`Pp)2Co,PX?\h]@G+/TǫWy(ϭBxp }@k1&\GSngq~'ݞ>)S(۷/y Xv EAI-BV9{Ֆ 0GEY((/ P n`L 0h"#`ԩX`RRRaÆh2Y؅76$ǜ7_3J2Vkq~|wYy0`1L ZD殿>O<ɏtzy[~f'iqɒ%0h +fn0Z_>a;Z̚5Ž,(t#&N RIp]p3~gT*u __ùf[?,5J*7ވ~(,,Ŀ/ 8< o/B@Vf]z®bBgL 0&$k ͤi#Gf=У{9ly-xyk #V 0&`!@N#<(J9rZ&hb_p bؼy \d̴tdff"==] ^y|駨]՟9s&^z%ЌM6!))ɭN0hM>?: 6~׸j_hm[sןDWN_zobƌM }1֋QYxhkӖѱr+I?ʭ`7k >̾bڵVM b:u1@~Ϣ-ZXվt`֭[ /PХ}h6޽SfGY`cP[I@f;g~[ꮱW-[L. 1VjgH-qP{wP[]Z؄4t>; ` ˵neeehR3??ɠ5.9992d2IڠIX[7V%َ@ߖ|Hf7Œq*Yi "|ɠuCK}$++ zK;vW/z/+|;{n1?`o$?R5Yc櫪*O Q{rs@v닞@e]:]HbPkEUΒv]ښKa&0x`eqҤI8prG6C)4\r%ӧn|цwu[\V 0} -2Gnd]Q>Qڱ-8PY漄/.#S1_Hyp[m>`D~c* VcB=m4e/p`L * ]vZ{t^wp y!rS]/_N%{K;wgz:GPQ3Af2!@k]2*FGdzPc7Pۣ/iǁ|H7O(ӀE둛YvyԆjEh8 X76*QFGd_8InF|-+u d}8r }B׊Fdm޼A,EPˤ,0&@%@z$/㪫BϞ=e_վ&L_͝;s_iVN"f+_j}k: .s/S] k}H?$ NEEEx뭷eMIom܂ 0K0r|)"_ܨ(3Ϩ<:zH?roCQf/xDH_ ǃ_u$->Ô)S,yXYl~e!+؊?KKQn={} ;S[1&`ZRKZ,:}嗠KVz^^[IƟ۪, 3"9w܎Z9?`L 0&@۷裏nȈ۳[%9Pժ5Z;doYs9EN F 6 O`ɒ%1b6_I-k M~FR#-ٜ@3joK1Ϩ%0h(ӝ4m2[_{wE?' I ^E98 v=sNޝuU *W""i6\Yu p*Gi"0L&$>  {oU;5=yNND7:TuGHfԴ4׌/E^NMO~˖-î]Ν[oҍÕ*VHKW;/vϹRŶ_zȋerhCւѫ[R{GwذfZnkrL#W ً=7p222MGbɃ0l2.==8CqTm0g7ޑ#PڼyPC~o֐3{h:cZZ! dj?zsR|sXxM,az9r@ ++ OX_SLWYqDiJD)& \oD8r?Οۉ8>L Ãqmk NSAffrLBBu-48d||DBnU$bCkbpz"#5 A4~u]8_<3Lr [caHz23 5GV[nqD)HZ{*"Pr-z&8?ݝ;Vdvk DqѢExڊGyDuwu?Ǝ{ogqZ|A]·ϕ|5$\cԴ׾Y5 Óhm@J֞M(뮻pwh-.(!A P0OMSW 8]s8ԗd+|T\r (@ P  % 񇍸(@ _o߾G)+@S<ky$ P***29Dʴ݌kt)rM:ROOլgסlu (@}r(`ek"11=%xT+pۢ3m K@KK :⋐/;cƌѪ/}kʗ?F ҿ曭zzzիW㣏>d Ri92$2jP=X7o>m8UEvzI0@˟KT<|x IUB!<qZK1T///8q-[ŋn|||<|UU&MdVtŊx!חKccv>gߝ;wjI㩫~K/Y?Jp7Zt\ )3o&*w2z.~uLJ>v.P0_믿tD|ǎ8p.]͛7_O6c>{SLѣG7/Жw[n2I[$$aiooGZZ嫄 ` -ricA5+7jzYXgC d_[ ZڼԒDέk V,)ǩԱ5X<όiu˪v/k@Zj%;;O<5UF[8dbDX$ʝjPSNi|ΏQOXCyʃG#eY5Q_ֈ,& CIOw}V:˗/IKSO=eq'l9/'O\R3gjH$ /`=̙/Y+b8?~0 u$+HI#WßuQ $ta D@hSC9?~ \QQAS;MMU)M0NijGv͏G(@ P@{ yQ f#tGЋcTY5^&Ǩ#'58 (@ P`@h~C۱nW0 g#NWغqNU{k(@ Pl+`H sѸq \Hx'9g 4:hl(@ P Hg$LD7:X4?wN?K\];>BZ"?'y(@ P-a9Zպ2,?-~?=s(@ PPw4_xm9X^RbBpp5/<7Z%R/=^x*qLY1.uSloC˘H! C(@ PHRWH5$[(M_-Fo7jX_T-(@ P0$\!@S j8[*իIDfzN_a(@ P%CSW DhCv'īI/n (@ P@ ȋGߏ_B P(G9˜f(@ P*VuQS$xξʲqȕ2L:5rG睦&є D^45_#FurG#R(@ V =A<ͨUykxc/Hn[F P,'Z;mǺU|0 g#lrزo|kw;ًMI(@ P a31\4n\2W*RBZz`u5.$%u]LJQԸ,(@ P!`hRtML&hT?S:ɉ?~aW (@ P *HdTPС$?B'i4BMj1AM!T,(@ Pd1&yKMjn|dAR( 3@P1T,(@ PI(@J),뭒z=d/oMrã<e B`(@ P6%ZիKn(lFRCQL  (@ PJˣBҠ'zK@ ddGQvH)j(@ PFڠ'T d$@J(:8eQֳP(@ O 4'ԓHiH pH(;ɣ$<2T,(@ Ps1($ꓡRZ!eyΡ-L  (@ P@DJN:ɶE=9W^GlG> (@ P h=y}Y&Njq єy P(@ I,0WXʕtIENDB`././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/pattern.py0000644000000000000000000000167500000000000014361 0ustar00from openpyxl import Workbook from openpyxl.chart import BarChart, Reference from openpyxl.chart.marker import DataPoint from openpyxl.drawing.fill import PatternFillProperties, ColorChoice wb = Workbook() ws = wb.active rows = [ ("Sample",), (1,), (2,), (3,), (2,), (3,), (3,), (1,), (2,), ] for r in rows: ws.append(r) c = BarChart() data = Reference(ws, min_col=1, min_row=1, max_row=8) c.add_data(data, titles_from_data=True) c.title = "Chart with patterns" # set a pattern for the whole series series = c.series[0] fill = PatternFillProperties(prst="pct5") fill.foreground = ColorChoice(prstClr="red") fill.background = ColorChoice(prstClr="blue") series.graphicalProperties.pattFill = fill # set a pattern for a 6th data point (0-indexed) pt = DataPoint(idx=5) pt.graphicalProperties.pattFill = PatternFillProperties(prst="ltHorz") series.dPt.append(pt) ws.add_chart(c, "C1") wb.save("pattern.xlsx") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/pattern.rst0000644000000000000000000000044700000000000014535 0ustar00Adding Patterns --------------- Whole data series and individual data points can be extensively styled through the `graphicalProperties`. Getting things just right may take some time. .. literalinclude:: pattern.py .. image:: pattern.png :alt: "Sample bar chart with patterned columns" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/pie-gradient.png0000644000000000000000000010327500000000000015407 0ustar00PNG  IHDRX$ pHYs+ IDATxgXYB `Ŷv]{ッk/* Oײ @vB B)?&w͐LnaZP(lv~0dڠ0,[Bwp[#GBAAAAEFVR/PTPTPT8k j j j jw1 /pQiIm8^PP   ahImh * *-DBoZRZj jml .7oD֭kҤ ЛQ2ñٳgϞ=銇@򠠠ࢢ"vww駟5kV(ZYGFC1L}&֝9 77' RSHcǎ޽;-rGQKZj5o<⡷6r[ B ήݺuck#((ӧv8q"''_%$?SjkAmPQ6|ÈIOO722 :t([2LPT2N0w޴Com( __ߌ!Co^OO/++ٳgoߞ5kVǣT*we -!$Q?IqŽ`COGoK̜9ZhooOW|[h d}}aB]߽{SNeff}4ֆijj*]T*'eYI2܅|TZA;jxHNN&KܹCKH/AmPAmP] .50,,,ۻo߾daJJٳg>$m!$gO=zܾ};11ykMMM>RYۃV_|Ome?hoϠU}^4ֆi[-666j ՜"Zk}upp _2f̘ðDBHKKw]ͭ譍~ݻw9r1ӧO%Ɍ3>z]BEiZ~£@A1Aƺ4H aC-;?w۷700(**z%Ba.ڠڠڠ|g<4 &!&٥K7rH6 گ?\c277駟 p8+W <<1@:pqq6l-<RdbXڶo5eOScfX}<2bfjɏ?Hl5ohkCWWwժU׮]|SBKKaÆyyy\TPTZRJˆbj֭[HGC6ZRJR(r Gl4oIO-T ׆?0 @y}0P(J\.C A%q[Q >a4`XtG%/DtM{Dw!L6ܞ*L&ʊ(jɱ߿0`ݱ|HOO50L%/;2a?!J.]***jժU^mIW&-6HPT~K/; @z!EChȴ%}?i=P(*CC]_t7zQrrrvv…5ӸC>b daiٮyZl ןh!H/_ZZZ200ҹdXwPWYY6o56nFFFjjX,H$5u2T"߇:zq'ݺy|15uza-<ظ~Rt ð ]PyN:u !'k|L&WϞIJ1c=z4jH.P433nje!C;*l1 {eZ:SOOOqRiHhhaa!*:hao"9wYX"Y|ypHs낂0>{jmp֊Dg'vrJII122:zT6N<9++FPZ|tʱJn_Ȩ;AAvvBvY;4DYkr̙lAv޽;vpwdߗ-u㆝]¢)S-[@Jeܶ;aB?V3d7]a̙6l߯/uB8cT"E-?///ujmU6%{8[/\ Vavƍ56^0^lllǏ#`v)&4idԩuD w,СØ_~߯db/^md3f1^>矛OVvT*uvv&7vqvFuu% Lֺuk @ur8͛6j؀` &MՓZnckSgtޣ?AQ{ d2 :lf5۹ЊIlmmMMM322KpX,ZZX~zWoޠ2o---\wzEynv򘘘XL,k= &s.^:X"q<#3؉upq)))R4-nbrHS&_x'EFEw^vv*4qg"^qիgΞDw&[nmڴi4mob0 pw=jT.9:G$7mXOН1mZzzƼ BJWϞv^ f̈0i2111?w>uxڷ7227SgT*yCww}}? z422U*))8›Z[7x}X@Q\TD3J, <rki/TPTTk6!DP9M0lݻoo 4kfKSP]#[3rskwQbdʕ>~B<,,*zϣÆV8^ʒJ&wЎ |afffiilnn^ɰzH,DjbbEe (--  rM|~l6=_vY^#?v?xs3zsQ 곭-p˨QK@ߗG{[u!_ 6u[ܺ}X655兆zܹ{w6r 5iys Ne7*wǏ;%B]8fPϞ=DwȐ!5Ægef\Rv@ٯt+6>:t[%V=j$'7mf2#LaX2m:Pa{vv@022r*)3+PtwO1P][̬6~fHuΪտQ?/^H?p 8$ZP(<(JV,[>tPFĹ{?i>]bbҤSsrrʮR*قlavvvy}Z>|8eʙSyURJ_RRR;E5_k.]B>qfjR¾K.mڴr>|rD"?~|2<<"6640ڒŋj䘠rXwYŅ\NLLZxɈ-/XxM{}w; >ljirD2w2wk>_̞{ ? .>><<]t)نiӦ5\֩WWkׯ/Z4[FfRᅇ nn-[,Iڲcbb<=>}d2vgMMMׯ]b/\nƕ+qa;!DݻԵj]z5##Xi4U1Bhİa]x:BH,yؖMOwCLT~W0pap@@,3Ǐu!T*g͝K橇;my]/4cߡDM42i\.sǎ@ 3gϝ@d~׮/Yd \_;ys,Zy\k*s#F ?˯߼˳07ߴqBh/_&V7mTٷի]U8|@޽Byy˩yG d"++8Ts@wU!B`=nXV4GHLL"о= ܘL&ٙ)))YsKm-MPP;`NNX,&RI&ڥW|O? @.C]/_kw4lSTTa^0ڷ۫迌k{?ԼZP>|XWWwx } v_߾ӡCQ!iӈS޸ykɀgLJ{[0^^^ޫׯk$~@h׶홿z ㅆض-$4tŪ_U8KRj'i bnnƍ{ܹ=wq85+D!ƎUYxJJʹFTO!`,ˈr:ZMMMLɑzE |-<~*E 3b"^z=y4.BwTT*%KT: o/'B?է.aG^jAO}Sٶf-{Kry$ 223'_D-O|Gvقl?} HeRRTO߂{nUe咝yy9hQޖظ~݄ĤtBAU*w4pV\cc2\a. 2{UhȈ褅Pb_-# L Ƅ!aՀjn7jĈʜklL9WS~\۴G?+UU/3SSڳ 2XH/5RT_.aGMHHXb毳ZddKH>vмd0B&M6SMe ![[ GBNNBלɴM~;rt7w,C?_h11YfV@ 2Gpvv4/"{ċ!\(wdbŋ_*"BGPmx5kFia{\@@ MӦ+s6m\ȗGV,[Z^(ryd]ZO,?_W `Dlc'O%?|AM;tttwZr?uׯ\  E"*;m*J}_ysUb9%%G8ڵk៓f/A E,geg㰡C ;r9==}bʔ?^Qgj|Q/_ [ F%%˖ffeu3gP/zYկOݿ˗F*))nݺ:擧OBḱcyյk~CI[}6mX`0lS*#(5%0Y3gqذazH? IDATYYw9|84Aҹs˖ G ]o…|>o~}E|阘XX"=v7}89bXYo޾%'!#^>sܼSN- KJJ?#607jDI+CCk >ÇS,:p9;w+!=1V5SFFF8~󈀄TgTk*}rY,}w֭U+W yyr8ݺCUEm8y-iڔ)8ⳍba>zԨo^:::G\Fie7mzI úyym/X :r34ETʼjP}eKh4G`ه:}9Bj\\9B`,?z<;wl5g.-5- !JurƍX_W,;:cݩyzv%5Wb9tpY Tfw#̛;yC*40^PPPvoiaoR;gd28eljgǶmȦ5U绾5~-߸~>=`0|l^dq^nn-T9:@71})SRRRq7jܑÇ͚jldܴ5-Al6 zɿ.]L$0L֭{Ek.11>DRںΟ7_vv9Հ|`ti9=+Lw?7m"Ι5k1wǎg|ו+v 'PjҤKO9{ҥ/FW07oJ,wЁ6o!?n%KzFuuuϝ9P@SP :ǎݽ{/3+kl9/gv>]j?Ġ^5.22˫X(_T^gkWh6,^Lw|>^\\p,--Z(o< 3DyJѱJzerunݚf?~rڵv&&R%暙vh^Mn úvNt366~LKM+.)624j+R166nZ\*uk\cА5V/:U ?{C788aXy YP= o% !g$Ǐa:k/_>t(5Վ:cfNNp!;wlU7<~ݻu;jaTnw46jн_zD ŚBBP*ZYYx=>>a}z644LJJ|#GU̓dffd6mEEEmٶtOk.^2bE -^q^ hlmllm|ƔA^#=䲕P( dVѱ'޽{iǷڥ 95Bð@IQ11z^d|>_T6o<ŋ DԒ: "aQQ͚٪T~r {{>?w^DB<8}kX, mظrrx@ݫT5HdddT--Xh^קJɰC?x50~;hW?@8qOX"Yۚ)g1p8RT*Ӆ#@r8ŋ ۷3[[[GEGk؆Tm2#!d0B&MI]kckCY6lC._r8bذ7G}=Y3gܻDj[[ی rBakkK_h*_!TqСy{ǎr@`eeaG[[[SSӌ 7v_}cnj57#U_KΡ؉rtLchԷ߽yfLLL~~~AA7oΝ;gaaTft={V^.K$QQ6ocw#2Y3g\x bc'N3bTR{7v}g7/-ZT4v999[ '˓{Jc:nff;wJ%B`5ͮ` Ν9omkK{zv]dIN2ǰ~[|X,  0Phhh=  Q|JNEAwzzxgsE~\MOnAA-[JKKlҤIjC>b daiٮyZg_j@(_6 ne$&&=ÇȤNGR'7mf2cd?FjBcPl7n["PUEE'q0kw쎸 P|7"""55u'O1^={..Σnj}Ѩ#SRRlvf͈Ub$!>ٹ51W*͛7 s:uDLeogN"#3SPÅBa{77 t{{;.ru?Ϙ@.<"B ZTfɤ2Ϟ555]v 277_p WXnkcCGj%yED&.e S*0B9zno&VY:{0 ވZ|… ӦMJt!an.Bh˶mM,-߾X0b۟P*rs2 '}M42yү+W뗙) LFrrʊ˦OZ6ؙxyymي:rhl|܅g?Qb|6voǏh`ûyy>񈈈!BRAz~6_$H((-))hޅd(&%fOF[ ڶmZ:?!Z9[7o=j$a].;=9S&M"'x%̚:v'RgR`c.]~ ֍7!k^?Q#FU)7o "Z[[X,>?ƐIRbcEtS НÓѩk' 4ݷoFEEmٲ'֮߀ }ٿ_~!&ς-\Hv6oO ]ssӦSL9ש7o.Z<͠7Yѣ;" ؉tV3ǥR)K4FP!) c>fdN(.AapNN JM+Ϟ=;zhڙ߆b1:1+7Leb xXXuKr`蘚J}mppM5$!;;;MB c0G*T*Ӆ[O*|+h$ScY=ՃɍzhݻwBH" ۶m; X9M˖3+U7`4rr\kV[WW==#Gή9*G3Q|6TmFF0''GPIYcr%@"Exl7YS EMkcc3aajjӧOwP{qXXX?|KJJibq|B€:'M:uxt9440=1Yn. H>}N0>[ '˓{J@Q3{9s'a4$T[Xq4Tb>a&fٝɹtdr´0 4p;zddW8hF~勎=ۢE vtxUN&7mj]vmc ,V?.cx໑Z|c/kUi{f#b Yll!egd 8_|*G)d2LDl6ڑJ[@ )"Ю--,,-,jhZ2Sqp`R:^< z T JމŁazh؅88aXy Y.<.BhԈᴜ23*@mP#r ^HMw XZ&Vхea mP^dx<61xm-j{ ~ڠ"2EȽQ;z"ԎF@U *)]K/sp*J#=;ِЀГ8. Rٙ,ǓJ}z^|YPPп_7_ 0PhhhH )y%.}Nw Sz6셼G'6G6@wy<޹s%FիW'H>пsZn}5 P/|7(Vl|\D"7rBpȰEEw=~dYL&s}|h#]KJetҐ`O_{xA @C>U*2ld]ML ɦLh>{&%%]r{vkܓOSSS!`Ӗ\ `bbKF h4>7n뻛8h0%۰Q(*ww16z ãfOvwޟ;sݝ(ڥ '0,<"B fa؋/^zzzԵ11l6m\Z.Դc-ZtЁ\##3S$|jbeeElYv&ݻQQ,Xf ٳ׮aX.Xamml  $XpzL!QwR<̫F~~W 5iҤpۛLvI͛\&M13g)))k6qxbH$1{v||Bk'##GG$bxيO>ulْ'$M>v:vľZh֮ݱG#"r_Eˤɲ˃CB[{M mmw ENҳGO#"" \aľ<m\uiib)/XBXv-1eI$edd5R6֭?n,Bhn߽~F nܺqήyaQєӖXyZ }/^|ႛ[;PaQL&Ӽ 3z4Ѻ4''gq'O7g󳲲SSSϜxodT4Vun5?{vںmw=?xACkk+C ߄=6 QbEk;KSJV{{+V۷o޽SN:vX5TT\iΎHvBC\RROOGavƍY&xy?dk7nL4HvvQ9i˖- <_z6!BH h؆+5A"R3!fhh(J۶mr( uun1&f QfffM6U^FfX"9~iiiTSTTq55W7]3p8RZ(Jt7%/~=%^}y CHCE"Qu]ssskkhM7*L!b^\N-X,B4좲]۸<~!mϟ?W@M4ѫ'ƶquz@ ?G#fΞ{u![[ی rBakkKW; gEt#W>J@ @=S|7%%!Tzȑ7oߺwH-jYZX~zDɫ7oB666fffapjQͻP7+--MLLZb%"^S'rJ4##l;8rtܴq0::+C&KΡ1Ly.]:-(E90q֑7qm8l'}1???//wرcunfϞeD IDAT׮ ssIdTԦ[]ȬSLp'O0 ڿ@^LS/_rUDT*_zaa ,-,n߹-$cbȵ-_~^XTd2g͜q.%3238_͚_ !?<# =~~r<))o~}!hD7$ZDbДzE䠠 Bl6W^Æ Ν9omkKB ӳ%K*wƴi,D)^={UӧI;vlܼ`=|X.T[luj.]qݫqcxĪÇG5gNaQٳ,^4mob0 pw=QOHd29w6..vi'NbkP_<o _}Lmɡ;@e1ʻ7)E"Ͷ$~ ^^^e ϗJe6dC(,*ȴ0TY%JSSS9lmlvevpM4LJ2%%GxSkʏDFC%RRS6.Նf~K/; @3QNԿLo\pl6b 6}yRp L6XEɧOB&1d[d `6J RDQ~-f;88|Ŏ\ccXWWuUڅ/9%[eX,Gǖ߾qp8egUR$6ZqiR!P`88a-Tfx|>Zj jT,(@uaK۷S8~I&988$&&qdЀ勯| beN݁Slڴ֖(iUha!E5&)Cjf̆yN;99ffffeea0s"Ԝg? $O͖@=w|OZZFFF'Oرc OǬgwy2ks@ů^rttp8Gן0a\.u ?KnUT`O|̌ //&5N.,(@JHqQ:;;LZZZa`Р`JN*DŽp>۷/a.\gΜܹs afQ.^͛_={ !dff6g ¼aLB, \~mQ|ڵ۹s@ @Y[[306|W^ɥ u'](|=çuLfӦM6m .|Ĩ̏ԩ24 INʮq-Yz .,,qq [ry'xu|hp$AS##Uti;8v-6kSvoU;KVYYYEEE9B<jDddW~xP$ aatjKrlvzL%%LְἹs._d"-KJJ?~kAsyY8'$&VJG6o~@@w6>QZtΝ-Ξ}>{3gqtt|]so̚9cޜ9U͛@"defGn58@mIOMn>P L8t6?.B(FFFo޾?q}G-joktbq~x^>F}{$I͛תU ɕxAjh"<6l/c盚klddrѵMP"-ի˖#[űqqڷӧװwX\\L>|aFF}]E>(̈́2w@KKk׉l6fPФ䖖yIL&s߁dI{77BYOPﺸr^^^:: |n$*+1ń6 Ry3cǎ韾vF|_w~}i.'`;j 42}UiiiϞ= hѯ`]pɛ߿ԬOžwnVӻoȨvm"]5rDfn߹זWNj֬g;ر͇hKwwr*w1Tއd FEX | 6}J&Mxyz^F?$D"ܜجrd~lΝko[ zպ}~ MnnnnLL̘1c&hTFH& H| y!6Be7[?bاۺ\\canN@ gϒǎ)**ʲ433ֈUXn0T/Hϧ; EJkQ;Ţ&,˦iS-Walllll\ a㡡uw.RXAwN|9mFEEM<΢tGKa)仍˪+Tju w tGXT(")7-))y捷7fBJ{b9!x۞`߾}lv 8!(6**UdУt`jP%~TFw@]h.,,qq [ry'xu|hx>fRR9^dx<6˭DFFzyyAڠzFwf$d^bHZ z~d@Xj( mx</y3~}6o!4w#F׏'p/,,U3̔<Y**T,x0=^S)K$/y͠5;pO̒T|7o>|P" ƏP<23&4=i!\z -,"%^ZWdʕK, ]hlwaF|/:粑ǎ\~DD9矟9c:ʕ-֐ !z_jGFF>^d2|ݻgΞ؏|E-ΝKLL5j!$44tk0 "eK/W; Lq EE2[kp/_m"$$d=/4MYKF3EڽݵS$BN<-ᄐWv~h6xa7r}M(j&#X0Y0$ YXѤICBB!C k׮?q?(**:|!S&M)S&oܼb0ڋ B-;VѼ{4ic~!@0YlB~#MXфҲXaa܆P !ee4Mjـh34{8mԱwB4^Lr+J322v]UU###{HUC`b|7H$'''$$묬L׏lo-YP(n|dfŖ/{?w̍7߿W^]lY߾}-[Vt!8;kH!eMɧfBhϾݹC㳳-^!V wL?׮Nhg]MѣGJ%!qY,'O66QS61wܾ?t}-G~GaTBa(ʞbQyKqoo䲬*0|xD2;~,.jy>羬pf3˲X 5w3tv7֕hØ;ns8D߲y@ 8sgØ>G}}V5~rkOzi9MKK;|6l0L߾}}@@ GnPsT*J:d}۶ۧ[3r;eʔ5kBX={vLLoc uF_vh/.w |W$=c>`UUH$ @6@+ zCl<Bk9W| SWWDz,˲6 W[Z4!̝ˮ^E3d1 )?j5*999;`Q w.bm]119S~dsr@i D._Z,jxF6uHD>`qwl6ۗ_~YPP`2:t,M+*!Sؽ{޽JOO|G}~,gD|<{'ц.S1Z~۷/;;{ذa;v:@ h+ډ$ECo}'ۗl)W?`k]ϵk?߸c|p'~z_AAs߹kZ:NjZEEEiii> 0]hEQBBRJe(^7SDFEճʾ7K$w;lq6۳?_7󖽓ZL7/55::{ -f&44ڱۮ]\C nxD`>ff7O Y ԯ+Wa+*ҷ?0! Nz'rKCCX,xeEԈbt|QRR\.'\.)ݻ9_.Jzs[l}B]jj4) tB@hotVV?0lذ]vBL&,0 Ђw"&!KQTu%>qX.]bIRgWyQ)/ !w3~ 2R^~}ĨQ?Ȥ҇g=ڿQ4TZtŠw`?544DDD{g"2'w~Ӊ ?<O4\MMO?=9%g?)NByx֣A*Ӧ3:FO44޷OCv仧Owin@FS&OJC644p\֘\.&ر#,,LR**@".% /%'Z[cRbk'ir^+њ B!Y+ f 6~묇H$qImɸ @  LmyTUuួ{cKqBbljje{ʕ+KmmmYY͛:4m4(w}F9?zɉ6Z.ı[Mv9g ]gdd{lPn.c2C߿_)ɮH$r$պ~ W9o*c=37#=Gf9+7r V^`^{ȑ#f4h#ҰA" T5{t}{T7g\9s/}1wXDtjb.AգG˃3|׮]#|7W^=z)Ï`,׵\ZZڊ+! #mFHx  Uh"I@s7s/zC[C\۾Mb$d_<%$B]O=9!:ãڴwuC5FqћQ~PMQkw5kG؃USS㽳xEV7ΖX1g]YV(n"R)o5%4!Yyʃ[z:}%' Cxp,|Z:iBӄ4f{!,Ebϸ b E(P(B~k@Slfp^,L+W L*mjjrejÄ{twu"*2R x/No0uuu,˲,kZpeUur g &N T?(4?`\W]C1zֱ+rD!FuZ n%</VР%?j5#VAo3h:Co8;P$^ڣL/;j<,Ԭ_bdRYE}ѝHHP,>0lи8G\~dw@0w%Im(71u]u%:OfkjP*.//wAȍX1ދ @ED|/dR%ƗRumڨ+.EaLQgğj U*՜*ׯtEeff>#btRQ1wɡa= 5QN\֕pW;PؗF+>a12$''dGpZ5ky_|ŋ~C£BC|= &R w /gsCdj,\+v֡ %FFtlP>"`pnVV… g̘Ta߾}ӧOJ)))&L8v {E{&%}wEؘmMz] w<6\  |ΥO>cYVx30z+O=ʚ0cu%{NvimvmVOJ$%L@R!+Jqp+++@S3C=r{ mnmt8C7y*?pN*aVGfYl6;(J LrS@Pć D|Q'h*WHHUӶ=u%:CIm-ٴcP #jZ}Tؘ7jȄBȓO?=eѣFysͿαcnjiMMMH$D^!<ߥ(a⼳Y M%t_lh̼NLHLz~5o-Y|ۈezOsVoͣ3&M{a@EEEU?$ IDATUU9ZlʒTwb&>UK8(>рcZ/_)[n8eZ"##oءZiidDdBBTϾ;?+3.݁{DG_k !=ӽG??Ԗ͛/ZDYKFܳs6+ϿKU̵t<^n;77WTB?_~׮],GGERoIy "A'!B{+KCgsdy6y}P .Cj44Bda~4ibHH!dȐz"&&|QrmfO-/-'OZb9#* />>?54)`]vĉ>[TTD鞒b0~=>mNϞ*6 4(33b8""0x_nm1B{V"f .LƋKRǨfRt8w":RVZ,t 6!D^Q~PB***xY2)"-`Q2&TO3w%= SQ̵ۮm 94ry] .(z*1YW]>^W!@5xZ/T{uh~b?~E}\Q[y>=Cb!]N .E*d=}0"b] 1u"Z,g.n,) QJD**L_+љyCTYP T:/{k65F6L< mP] wqu(,zx"b:8 IJ{\RygmvaVW"uW߫ؑݶ:mHn":8fI/{P([kжPҝyB q\ju\>#'iP@EommjݔP1ftvxBZxXKn] wEͳ %Ŵ,}L]]˲,l6\njڗCo8Co@ӷ?KfEov]wm6Add=V u+B_wGC'?j5#ɼwœ?jzG;exq#5;QW]>^'vg*?d$exԀB>l g=Fv9Y{5(A" $"| 7ޮ& 6#lB:,; j~*2^IHV$ZmAAAqqqyyJ3gs={|weeeP8r &0 x\\D񧊷T\] [pՕpW"m\ȕ2+ch|$99`0h9}#~͛7ƙ3}]1 8d$OΕjs +.Eڛ(24[p* 28YYY .1cFTTԍϟ?~^z)?999?o4)_u%J;0ա=?d3aҶDT,\D-BwB{-I~f] w]x]<>\Io)-% .@s5ߵl~ }Y»%F> {Ӗ]Y"QIKfh4>l\\cRi*d=hJu(TIXg H]٬h4^7 ܶd]n.^pS|riJ]:MU9r۹JRXXȲM\jV%(FrG_v\RP+v֡aw E~~~k-[x.!?̗LWW߫ua9ANψH[=fu%گu( 0uuu,˲,kZpe j_N "fI y,*)**Y PGZfd2.PXXZp@o8 EQT3ʊH(a4V\~ds[b%;mKcc `<ϳ "\-ǍFQa2 OH[TT;@%-A wZmAAAqqqyyJ3gsCmݺBtFFƌ3/@#OH[ֹS0k UL] <߁Ғd`45 0aBRRH$*))ٰaÇ~ViW9uZCyx]fիW}Q ߛ|Nv}{铏m&L(*i}SR E 6,*g˽+ (څd;{aaaNNXj5z#G9/Ήα+?;qf6;d}S "zBHSUUݹug6^)Յro}e}S% ʞjڂrJ5gΜ[־oFttoFEE5zحKC}}QԨeFXm B\Tq"Rҽ(ZAܜ=----))INN6 F֟}H$ jA r˙9VkSej4Zj4XFh3X'D"Hi'D"F&+cE11@W`w!˗/7rÏ?XRR2~k.@+Ĉ$%,v <  @r5SSSh:KSΜ93m4oGбn w}R@swkjjvܹsNBzÊ+RSSgΜnllwa!OEs]77777ndwKKKKJJ W1ؙj5L?cObbb=",_l6؎Lnn߽~z}}}ttWt@_333yD⵨:KnRR҂ V?aÆ>hܹ\wCt_}UMMMxxԛgt ˲Vjr@$߽|2!$"",kXx)/+lh4F nd2qn߾ܹs555o1l6liz˖-|>l6#)]Nm*JBHqq۹? >|ĉbY%| Ì7I 4MQBoќ9s NcF.Ӵ' XlubѣM&G WbثM9f/,fH4tPٌ5TII 7 WB2`3f㹝4M/XW^gϞxE!h srrwV g g gνMmhh|0K/-ģ leɒ%[ 4^kXt:lR4o4m68߯j U*՜9s36m:rl(*55u޼y>ZԔo&$$pwҒd`45bY/--}衇zŋ}*oh\^|7+++++|+=zTo×Q+^~ŋGEEYV,@\{QJWVVj@gS[[D"5.՛zjrroyeCCC~to~gjkkiF @\5 'N޽UVXѧO?[-Z0h xR+b}b<`6'onYx1MMMM"a|7***""a$D"f`6Ba0bP( ;"sin^8-Hihhhll^ ~(Fm;⋏?P( B,F`wf3^Z"!#G,((ϧNjZ?SX|-1n[\ j( !a.3{{\RI|ꩧ֭[wB"""x≰0 u4CBBflf|ܸq&,"hƞ*6oҥׯ_')QMT,l6b4_~N<qi.in: !Gg|<(xº,rht, B>!^gTII ˲8Aklxs!O%$;qVj_n2ilEHK/)Bx.Brrr< ,jz#-?+ힶ`Mvwzzzng/ Np:Vg`f-+ޭ3eu%ӟmse_TK#3jwpbrD߅ {4:;i4!dIfYԘmՔν5N>O(<ݣW5oSh: _u w+gF.24Xʝ^cﲬ& ȼ@r#=UW굷h:}=24!DogʏBzD2"GW'Y?IDAT {ks'K4j_~( %[>vTV;|7Fa6څdwD]?.&c04\_)BW9 -x u,KKX%,ae[I.Cy*y_@`)Tf]!n=tbf%:Co8pCNNNw7777q~;ʍ|eٺ:H$ tY^dбV-(((...//WTsn˲۶mۻwh$$''Ϝ9399žniiiIIIrrL&Zgܱcĉ}_\l6!++k…3f̈Ѿ} گ_c8pѷwiqqq=Vțt ÄVWW;p^ #>CVV?P\\L޵k!d2y52siɓ'tEdѣGٳG$y;8vr)ߕH$sέݳgO||h'7Еrcǎ0J嵨:=5/^$zժh!)))rʕC:th4Z]Nm*J>$,f͚5h D {P([kbŊ*%Fv P:sc*))aYeYچ+~!-`d2^XXZp@o8Co8Co8Co8Co8Co8Co8Co8z3q .5LMN`Yh4$0`_mϞ=}]YY!D(9r„ ~t:233yX쟐\f3IENDB`././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/pie-gradient.py0000644000000000000000000000265400000000000015252 0ustar00from openpyxl import Workbook from openpyxl.chart import ( PieChart, Reference ) from openpyxl.chart.series import DataPoint from openpyxl.chart.shapes import GraphicalProperties from openpyxl.drawing.fill import ( GradientFillProperties, GradientStop, LinearShadeProperties ) from openpyxl.drawing.colors import SchemeColor data = [ ['Pie', 'Sold'], ['Apple', 50], ['Cherry', 30], ['Pumpkin', 10], ['Chocolate', 40], ] wb = Workbook() ws = wb.active for row in data: ws.append(row) pie = PieChart() labels = Reference(ws, min_col=1, min_row=2, max_row=5) data = Reference(ws, min_col=2, min_row=1, max_row=5) pie.add_data(data, titles_from_data=True) pie.set_categories(labels) pie.title = "Pies sold by category" # Cut the first slice out of the pie and apply a gradient to it slice = DataPoint( idx=0, explosion=20, spPr=GraphicalProperties( gradFill=GradientFillProperties( gsLst=( GradientStop( pos=0, prstClr='blue' ), GradientStop( pos=100000, schemeClr=SchemeColor( val='accent1', lumMod=30000, lumOff=70000 ) ) ) ) ) ) pie.series[0].data_points = [slice] ws.add_chart(pie, "D1") wb.save("pie.xlsx") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/pie.png0000644000000000000000000011245500000000000013614 0ustar00PNG  IHDRsRGB@IDATx]|E_r@!z E0(BAi")vE  "R"(E!ZJ( =\%ͳ{s\Kr )3mfv}nnvF`` 4[N@e~ב֯_G?Jꝗ4M9%^./},{6l؀ÇKT>{>++gSbegފg.=7S^g4\6唪_}4׈3WcQsgSٳO>[v.rJo:I[>%L-u 6.3ZAR-,,`e(ZPȂnȲr"9$˓ rey,0Si,yN4ʲdȈC^zA`LOXyIQuJ3:SFuU;$Z/?WWp^̹lSY_5o>ŮS3m5tnM$)>2>dj|2˯֩u9oKjP҉Za}Je<>MA&FCziv?m!O9_i\-ٓ:גpӻ.EO\-_FedJ-%u'SoI+J)6ʍݘSL8w8 ÑD )еF-qw"--&Bn"~Rx`g`^ǐ]1{ZIb^V1~8 \7sgkuWHR\'wbGO9lq! ?GR&+hz~*> ]RqV\/+\(I)W&FZcks}pb!q;xnM>g%:NCu:l\e>6 X3;iHViw]~J6S”Myys4+-`RLygė?)~n >hC=8ܚ|%=rrۙNnz ~\=!M^Kueߞvn59D4Jv@SRQh]]] ]=ǍAC9%Y&I)-ب<'RecLJGG:Rl7H9[H%esW9-Z/cͱ ]/-/s_yS%WT*Mg|B7;1NAR>2e=q<'JeYxn"Wڢ99 =5)J͋(l{Ws_y꼘&\?+Pp3:)E99+j~s{guߠ´A^.&aAy=8[_ɧUOc] ȋ |?Uڬ,_dg-J[,9/ωFYV6ۣ3kƅY`꼌JJ/#O .lZ>h)x,v 2@6 ;//H~QN9s0ϕTg`ҍ)P7~0fݖx:1zq 5'ǬKiթl_y^vG8\[2?H_qErr*n87J_*ed٧8?3]fes,ed?$OS]h}nb?$9Wʕe#$(dNms[D˔[:Wt@ $kT֏O Ǿ Etԟҫ' 8#>WK#Of ##:]r[B%S}?+]Q)He2L3k]fTStzc\|?g'Fl=_x*?%纕yYW|-sp|dز}Щ +E6ݟ侢|Bǟ5l/_{DgLuXNS1`ӷ1ӕ.аi lH0bI1ѓM[A$MaMF>yn6=[6K=8/䎒sݬOO4u n;?G[}Ly!PZRQ3ry'w,ck4Eݶ)I :q!r?Y/d_&?s˔S*M Bz3$Ck*~"=eV3gO: T.C!..{Me >U]= (p/dr>ZVVRsSr)%1o?˃{s_u_F=κz4)p^ '?Jss~H6OvСij2}=vcfDXc>sJTu\g{ QRJ9%g}%a?4n_Y\矽b}&;A m#0Y~Ġuy%!^BTcLn^v"NVsNJKe^΋g)I\x?Ȇt-\R>7 ^L/YkTb'לb? XI$e O}(lޯTej(X;rO G) >ư?|zFOOO4h zj*YRZ,5-b|FLy qku'Z߾zz7_`Kɿes`_:}f,Y_)[-\Myn/$ǒ,Kuj[9k'} n` T׼غ;.&ЛݷO5~\ge:.]ɯ,s:y=f6l.MM^biMV^J8>z+ۨls5?繺΋%4A/|rV.>[t<']ʖQ?-ɲTGbrE#iFRrJTfAomsw/>s#Р:Ro^;Ⱥς0,7W3%:x&)oH/ۙyeQ995d-הYZ?ZN\ Y"{hLW AR]i_Vm;ZN\ɐ5|s^)Sd3֯ t\<\D o__g$ 6-y!9\5yJyd6^2蜒]}ἔSSn)Dox[FYTVHE\.'n;9Y}P%ze祜͚Je;?RR~Zˉ2![•5$Ų8&^.RNɞDi,k'\/)6kIudq^n'(`SZ-B,(&65=uک릲Z?oˠ6JrK9%n8%z{c0ӞLgl+ UeY}xn/Wj0DW&sY:!w8.t*mQ6S2z+xY<'eY=n\>1!^^6SQOڋnAn22ʭٛI1W⪅qڒ.%Ez sK)8vkJeYI,6ޮέ3D|\./hyl ZS %:K:-#.u[JlR#>e?f+%]\XM<'~k\0u9W\5k0aK$g!Ν;;K:2 Fu\B@@ ʈ@tt4;#F8,;XkY`PA(@@ XFIХ!**N|nvsN̚2SN¤IS1u8V%_!Z P# ola\4e0M(6яtj>4B|R#@@ Ff`uW̞= Y!45۶PI1u,d ģ}:"k^ZЪҐs =#vZB N|텙'bkh#j xO@@ Cj퉱!nX v`ʄYPA)lVwc+M@@ kY0aAuYj)%Lfms#;#ӱ`k ]ąG[2 oy;d :=b* Q@@ (6Ge!NVq56]"sDi2^G0eQ,,gaX`G\FLKFaG|(>~G3_>h{Ok`U8M]S iU iI @$. Giig˗%FOz/3^:Эc*x!]?v{DɲwC1 =zul5Nj[S /H@@ %@JxkKGJJ2r<q)H/qu-lSaMD}<=R,fi¼ 8h7l,\k4:0fr}i:>5>=Nn9ghj|9V@@ "`s 8U&vlǰch4UnAK|f -.$d.-=HI5}ߎKLswp슦On+bGlk[e+g#Oʶ!"@@ pMddiRѨ%zx[~|43|ǎҼ0'ldjRoGzbn7PD$;59Z/_%ͯZָ~}qLOD_[\B-rlsC85WEZԩ:VL/'~cpƊxQ-@@ =Z@$@@ 8jwEr.SI4..lj&g-rG_z!k*OKXYwSɝUlݜS -AƱr@>v,"{+*sp~:\> 6,:mVX#t J@y<#G,%_f :w\"Al1*i٦/((` ̢#o}-Sw ¼KG1rI>8N(?X]Md9hn|8ڽ::U Q#TT~#&''W~υ@@ PbwJ3/`/aw{Y4ymFPW3ʕ[n>TEO<|${w-8@lα֥ I?~qtK9^SiB)&j@ơ:u&-DiL?v_F W:6Ok<3dcҋa,3[4 :#$َ pN}C%G͈m%ҎO m`vX{&ɖd֦GGUx,epxc4wvBG=98Z{UmXB`˄ZQ8-gtw / 'Zb8eޒ /eĆyrԍ%;ׅᷬUe*_._>B/U~ѠAaťDCj2{ab;E(ɱc G-!"pksaK I\s C,k |\xLeX\~Fsbذa2==7:N7*0 8iBuCFlȴ[r 3_M}םgkdd. ms%]1,#=x;L6tX%Q}ED)=ië&yPyB,plr;#O3~]&:wrS!}f0b;4AFY#fɃe[JPQ\|ٰvƮ1c1Cv4`kqddIi!p`D)Ȟ@ܚYMPI=bv,!B!;_Î6hȕZ 5fdn1V|OXlŰfjQA`n7.K_m)Fo<+C^u`5 IL1$$Xm8v9М._>)@l ~8-tl8Md|V;` хb:Η6ht^Y󮤓5iL2y`}yh.~A/21H'-7DKCz9XuhvD.p$Ca>'Q#)8d @G3b|:=^g'ao% 唹eejy?We;`Hc$Eu @c(a u?"Y>x(wφ1S{2bJ_(TWf"** Cs}ܿs2)0=vڔoDQ+~woO#MBտ=|}8CU^8eY_عmc5cL98v|m~@!& (|FQ~}7G'aRvT|8*~ܴ1RW ^'|( 6~ 3G}WᗱNw]!8FF"Y܊sg_v'Ѧn}|JQAz`mMdm1. naÔx(l~)jaİ1r>$Ĝa'{Sܽ9w.,7]BQ^|1W\Y?гj(V+L7g۸]#x_%?x_fj&Нr@D︱;V>: #Nmyju`se&/'zGD#5 w# }p|Gҵ>w5{N˘{UQRy˪6Zm]E;bհ%ݭȗO y}+HŕIy֟b+..VyF(g{!& o7bcG#4f ~Doe /G}1cA ?J^d@%G֩abɎ > WKEqag,x=ː 6k^,}S`dhgبl}CB&靴mcT!QbuEOaL,!Xܪ){]y6-@@ P [M-Sʖ3ŞfE"%xY/go+ݲ5Xypj#ۈ?b +;7[4OΕf+tcU6%G> zjВ;xz{a vꉜJ bUCv\ƺl-l-MRBi4{Q18?Zis]gz~cOz&кZ_k p]Q}Y+ Nlm{>EɓoǢk M?%uL ڏoM%ء,[>y OқRlͬKekK\ɦ;):6? ;G!Ғ{6]$6Ǐ̧qv/gx7~|w.|7̦>itqls蔕%Y5gyv!?UAXEqJKeDVj Ğ]0fr[|)^CWɚX"!qMk/$kx?/rP:{jJ* M7>V{k7Hk^)gcAw[Nc}}tXC~RI{)p*/N%DFlҍRPMj_=?Ƕ]oj^s /Wuln;.Y٨ȭtsD>G\ `}%xRc+ >5eҴ㙏#SC(VKPO#ؗ-J'`t[eT&OfF^&1<''DTuv[Kǩirotyi4i2z?2 =o}\lZ=T? XJs 즬88EA P Gr{|=g>]UA2 ۺNew؛)7hӥ2 fl"^˥elr{񆭯7Ѹ`asq5b>y]aٽkt(L`8(VqUY_׍b.W1>! ]{3*F`$üŋ _#]a +t/{bâ1@IV ӓ2œOr? b(Vՠ{ٽze K8aOm=e:I'3?< ʕ ofvɦPLL6gRwcM`$e\bxiIBy%YٗeV,9NEYuCQdYKk(_ǚ^?d5LK ?Wtp&Óꌕ%F8ƗLA$-7r._:ZEÞ/ ô^vk.C^,P(MŒE!|YQ(X~_/pB_ _6be0|v`ʔ"]炩eKJMCq*/ΪXkhĚ,-ر&LpL~52U?Nη$!s/>K{o-epRZ!0bb7OaĹ`"iH1tN+9?^$䅇=^MJ ̭F2"P˯ f »~=XlA>O<0va|QT^Xds1>F /&$&|bh.I  >c >f?p=-eRź^.سעNɢ\Q)vF윖{^Sp0!E  00PXWVIv@dWU2 }qػQؚ:cզ*Sq|Ds#֭[vX]w؈ȑ#Z5kֈi `R6 LK i*fQ-1ؒA'^*T>x;ZE6Շm` <  ǴZmrrMQ J9N[t$@xy1 '{c;GRN#1th|>=2uBh#뜐VCПO#mk/G?g^^I]3/cťD Npc"K6z J)@!`#Cat-w6W&*~ʺ ,cS1x-K: Oᑷ ˊžaHoښ1Ĝ–CDB cω+hyН(H@6ݽQM提;hJ)uЩ]= * ~L`Kqo \H;X4jzN-X >q0̘oW@@ T>lLɇ.!QQp>gZQ32y}cJxTK ۾՝1A>1w;|yT"ч-KNx} :y֒f 5EMWRRFuj^ant iO.Ӳr`ܹ.Z: RPp4Nl]{MSGk$Bf7_.DqZqR$@@ NBƈ5P׆Ui,?^Zg;kCǻ|7^&"hE\x%ec .li޴4OqeNLGVٷpϗφ=aX͆j"3^a7-&q"66tItǯkH@@ k0c4eaӧcgF`q=ksȂjJ^HydPhX+gΓ5z䤡ZRoQPMI. :6:u`&< Zi[_0X l!la˔.Ql@@ 8f.!ch4 &(]=[q4OOۡcT`Ɨ2aNC~~>Vvb;52b"pl}w'_W1' "Um<8] nnӁ´xvy݃؀jC%@X )HAdn ?CN'Hj=EVnS!Ǥ91ˆK}{ y;`bW`19O CE޷ d2Nl~wt-UjNBmuٶu1y2e7U4cSQiiPUuY-T^s'ՕvWJ 6wx6_x{X}W^'eE~58e+ƴO7@Rޢ0yy[3SO_ɖ b|0#+f/dmE魞yS߮,J$,-10 |9\wڴ%nQXd;O^ J@fSЇMnF?o4fyh%MtH * HDeRg|kdggChZ'Zr #a!o + 'Y1 3 !s.x&fPžGf*gfإy{'Unb "X$̇#4Q\ڞ| AA~J@@ p+@{"AmnM|Ѭ~-MD*7裨L\|nZW&C_PgZ5Sφ#N ?D{;a&y+kk9;EsG^_$Ӽo-@@ +ɫұ@џ0C x@ꈰK ( LIHKaܥ&r[îᗅpp(M3A{7LxK?4ΞVm^qI8Z0]*3EYZ_*L> VїR"l_V?MA%@UA /W@,NEW+T6o|žhl G6vEvU#Xk.핂jB?r,J }bz@W? 1L\A%7A!+hz3Q{OW j^hGCTFhi7d;SALjl+ ǨE^$:пcC58)oxa#Xdh, w'QlHx)93K>VbijЀ+Q 8w:.t ;9+Kw]®3xgSim R@'vˊ56j\ݐ.l)]e!'O;fvf 5w rC#ksh=fCС/|_Q,Eh+?pQƍScX@0d[g@%\Gl0.[[D#9\WyVƋ-]+R%X }EݤU&`Q`|6od d/zʠF;|›( ̘ųM7Q&4dr*vG:Fm!8i'S/&A\ ݯYY1ߜ<$@@ paP 6P][@<ѣX^m `5΋ mpSÀ,JkoџIOw`t;_ӧ~!H U7Z/JH#TҰي!ϱ aGL(o8p3z1N>D,RRPs:W~(, Fskrӱ8* BeCqdyT^:c4{q֨[[LhXG@ ]-ͭZ +t8ر&Lp>/3:7[sm^O4u_^Lltk=?a5KezF@ b )SEXXyn$G0WOb$cHfʜ~0_^Ö7JVi}xm|+M3Ʊc0bj4)wrR9S})$nTnO~)\SI7uXP-@(Z5o[$*hDq%zz3tzt/m[ 9T=@1 U gqY/8`oWJG8Ő=5 Qa~E驆KUqܲ(SON`D$ :uA,b]JŷluSYDQ b8bNҖJc?GcGNA!u@mDɮ|>zz]l~(jPx_,yF]k#xe)׵nOIJB| D83z^3\>¶@wӺH+H@Qlֵ}!-?zlMJN.}'[J2ou#o<};Ð}{5Em9] ޷ V]j9^ʆwxv&Sc6RDx=(h r&2^ V$aˡH[ʴ fqtkރʁ&Kh2ޝ[@ HY}6`Ι10щ@@ PĽ#e#x%OlV& *.@ .te QXڠɺo% d %W}[^"刱iwˣIpi vFuɴSW޾}[#ȂggB@> qEnhMJ±c? =/v䗟ǰ9;)E <}m8E#y^ofq$%'G7Gw&b5T?z*@{m?"W<'M3FTKlX`׋m ۺ%Qx殲gisw3ɝA?> X ]ąG[2;COC0<nz؀ 5 +vz~̻I-X( <>;lx-`ޝY],gXmنE/&OLbfH?CH*md-Elf[ݿ4ItǯkH@YUp|BYE *W-\@!`soXlz Gl/5zuLsh T7xASrA{Z‘ LEO )`wC(ׇRPMɳc{l&˕}ho1^Hy~c!mH)3wc/c;O֔an|}l.(a/x`d`Ƹo99g1T~$r˅s)DEg[6rMׅH9H+6C~-7 FWQkm{̼ZhD}lU!a_Ϯh:d"vTKVn{çO;,5"|j갟.x<)7\wԐS,Vfzx~`t' ?=u Yŧ-fm}:B1k'nÌaT4~9;F4*U KBKqz5Nwc:V*1?\uUzaky pJx!S PeDFFZ_LsTt]k{ر&LP|76 ^ɘ{YB>4짒T\PGSRmtn^13y(dX~4 AA~LAR0i[ne#+_T> 9x [NeKXIiyvU+8vFᰯl)8g#)ƜΩ>FH & )H3A%LZ5+µ`k5kйsgaB: CS`r@0Zp?Y V hqDKSBv~ #j*Kik*o@@ @9vhE &E'0̻5+//ʦ!B 4ZCP^ @Y`Q*@l>moCZ"h(|"`3֝ݎz -?Umaqm* 0[ ,!{I,A#@ 7؋/}'D Z]$~̆ɌQhwɿD$(6ߨ0 /@B X4D}/$(xV*ȍX~u>m}3;v_L@ [$@@ dg`³ E`Q^.RXg\*veWD '@@ T=m@~^A3\X\)8y%2{wQFꈵfIsXlpiPF]1tl5Lt+p4VnpɈf-}K :[2ӣŒ@-~ M533p%!+X M;Itp%'[eF(@Ps/@@ PHM̪. n!Nܸڅj@ `5-h=V X<|"z!pb ز" 3V_^tgzmP[ ĕI@@ :t Y95wt P`vIM*F"X Cf.fi iHe#" @B ?OS›Jx{#ZR-8+۠G^^DP(N T)"]f^Y[5q":j/8vǎ$<\lR !00yrC@_(F ]!e{$@y<#G,W'֬YΝ;&.s{]`\< `0 "Uz"OLjՕ#S/XZMGWS699D jGgv1};֯4#(VosOku) _pg:xb1,U4,9w9Z'K?Fb:Uea@@ qS#滊Dv: '˗//r0Ϋ@@ P8sJ ^~+8,6Dʈ@*~<#F>l{z{5TŠЪ_(\5kE*_axe'd#ÃSMwG‡|ܭI'v%*ZbBDl+ =ZT 8a7_  rhتpqYMB?'= 2.g1Ӹ|*a9L%ty&X:مd$BDg;0Fv^I@ 牽 *y#pj:is?y!8 *:II/>1)4K̍yMn87pe51̾(I=g#X|-Pd #iitDmUXf\ډ,,cI 0cִzMhZ谘Kz_]&@fv@Oļ~ZxD0 ;Ӱh󀏪oj&ɤi@ " +ˮ]Q cYQ"AB $dI&B̄){{7I9L΁Crl<Ўa> WwQ-D :˱BM7hTwaO YR25>?v *M1?EGO _5ČW52o|X?xӨBŇh\d=AMS0yxno,AOX~q?4]|v*LBUsmRXK$@$34BQ1U-HSE宄&sߋ9X~ԧP+B腊EWa1rX x::jQ͵g8ˁ0]WtZ۸c4Lh;S#4Vu2u/OH^**Nrd8^FC$ [J]WCf$@$ RY25b# A7/Jڃ_*]ԬHw  4Y),쉘6Z߿$֒ x-6X x#v7:7Wʎ u%`DGC8. Y<.e`9İVc5::Tyo+p;Pd x9ZV{# h4W=s9f<O+"N'[TkqvY=E4V^z}@<Xs$@$@"ĐfN#B:"p(K|<$5/ Jgiڂ+BIɯ~v+ztW\~t.CC s>nkEp k[vZH:lL|!=v32ķ%;Ph# $`l_4xmhjƜ^peH5:/Xc`af`ǫwu#ִa7kOb?J܉5x,$>nCDEj\55x}:z&<1O'  0qP= @`u`=o_J7ӑzf$$vldZg J(@ g"KMuff@uq!6+.aH*aopJl 6A=+%9lAkpc뀆9, <,_1CkYX|a3$@$Z#LbڑzX!限~zLLZѕ[gހ',Xtj.!"[!2C._{ihlr#/; ?It֊:,@ޅԋ?ju(ƒ-0aZd  NΌedLNg[ нadsj|K1N}]Iir[ &ח ct5H>W//R9aXwK^ AYNo^B? k[-UJ R mD s.$@Cd噎KMgdb经&3Z%?Y@<>a7ƱNXrҝwÎuXo^Vs0ºMǞMÛk%EԃUܼ蜦jAgg'4HJ$@>GH>ccp#9O x,^F@FAp)ua487e)9XK.((EEE# S?q2uS $ XeG*҉O[TJXNȏN&tGy:77ףGNNG4LԽXA$@$AȞ_T\0-b.:Z)6t(ŭӊ'$aN}~ܹF~SO @?hX吪 aܥE{q\]$lR@_׊ZzXF&ȏ{iX NĮݭj僂ɸny}Xs<r$@$j̝t HHAhj5ZC7]aƘѰn(Eh\/J!˕*;l!Hz(0*^ODVotՊYwfBɉRi djŊuYG!B#0~ZD 3[3`t{ƟFŊz]9 ¸泐a"D>L`@ʮpG8Ҫ"S鳵0Mطz6>ة> @˼F sFfδ0\v+N= .^>|ݫfGE2/z&w-ٴ8%0_s~#ˏi7CA Ѕ_m0tfUyBDÄ,{U#>A hom?~*.Wk?'4UV܅9hR"q-nxh,& F >% *& A[`B$PM4WUfS jKdCb1VVNjDa毾ƺT%;Flv*f/ 8jBB7Blp8 g~shmpE Em=܉gDǁÉgaJFԐkQ C8϶XM%ˎu*9 8.|\ByeS/{('ŀ+ [+67N۞ރsuQE  e赈;㶡]oPW)mZvhǸ?>uXA86,M9tpmKɩi BTTν^^kXx+mć݉EnGi[n/]z\oJ2^V˞n7q~ZEú(BZ}j<6}GO6!] O/CSsbаixs~5~6/Za7؀ ]++PNCHH"'Vvݕ^3*k,eV(-{ۃ8'܄M/=?뉗c,$@$@>D sba2FS9st~+a;p0m:#p/]=x|d xAb?q/I ej efŜǟǜ&ͤcL\z>PS#،肂Z(y)JI}gX󧥠 ʳ=oKH((@U@ՈP|Mh/}YM$@$]MN1cP%;]ZomV:6 ΛnXMǻȈZ3fƶfWDH1zcV= 6g؄Q@hFhT-9+VW")eg':iTu$@$34)x+gѫFL@P!s]_QGOsc#J~6?¨TJ,8w FDŽ֓9IުZ@U ;֗b`] &) k6ɍ^yڀ7N+ـO,sXuSxHAEEE/xd2!d*҅A$HHHpI;{@^QYճyHzVE;=$b*+繧yPj4. Uw;# H#C1T|ZiI:Tz)'-?aPA9;x^]q|nչnW|⹋7dz/—nwnuQ{@Vҩ>iXg3`/f]HfеHQZ)޷]cov<2tˇXK02}&_7(6[߾Wx;Xp;_&CӖ}O7ZKVu?(}9ukEIOcv[(uK&v ܶϝ-s:oBl(xdCi]FuWgN~pXK{"6cuE8=X8V5m6;|X}_g/|̓谯 z5߯ Icbsۍaa.U]Z)[e.N"'~|0P\lam= cXHH|J8g& kޓU] /?wqn.!N+҅r`dLH )]h#ZٱOC S$.7ձ1<3' s=},JO׋g`;`mO^T+'\/Gu8Ӻ6Cc;cu8n 4>Yg\^|n'\ ;Oo↋.y}+/^Xe2-5%iXxw""?*6b+_wg^ Ǽ; !  iyǰX娴&A2J#"qT:qL h5o,Up|!&\.HɌt[p_`µ`;bܺU=V x7:c~J51}{TV}ʉ {^\ ɉ8waAE\vʨAj|"Ʃx'/t%nK2bzن_m9h-ŷ E4r}̈EW൝;d(2c[0ᩢn21 pYA*QGٳq?P{݂?䷯%f,^;'x4ي*}Ўa+߯^¿{6=Ao o|:+}%aH[r`ܟy($% e3FߕԻ,k8~5> #oGp;&3ƱNX̤;åհopfT㊏h%8 !ꐺ|^V~m!K7.ܓe4ab,2*[57 ~6'+ۛQ,νGyjB$@$:F*7(`+?:d\ۺX$17+XLH#]Aj\:#ݭueTNR'ZG42sCx=OhTK .}'  $0. HB̝. V:.A6, j@V)$5*xX)whqƵHhǰ:6X [ ֆc|Y^ifU lKFVm~Y6~!b.:*dd )1>fq< rԄ:4:67P߄n;uM6"`Á4zi' K%HHd'FgKo>cܯn(E  dXVfg86Eq !# 3֮IJe/3X˞]Flf1F|RmM D@bR$qZ ZbGņs@3#xT2/E^Ӭ ef(yy ;HH|a-e#}H} -—tWEa¨tzn6'eEcBL@fXwTx J7,$@$@K@$qRGD.g+7Jk%PiW ܑ@&|rprv,D6wYS@bD;=yWX2W M„sz=}F "]܇,_|h+=.53% g+hJ,%uِ@?>V (.6wXzkK=܆~Ag09H$@>C@m5fՎ[ۺ F$q}!!c"^u&Ulxtja݉t|ۂ-҇x}l81 x(!cv{«gm xhغꕯ`U׻* q:57zo:̃sAZf!VfM܎ #E2OYЋUi0{jqPT\b]wRc'M$@F &<'KӎUBvds_C1c"qݬ~{ƅ¨{$@̰57 >Vh3A0ڄ DMdH$@$ !;a6B7@a`X {WM̉qRR}EyA$ ' 3n{z7W P5w,-Zlq $GrqG{&^_IDATmOl(yn LbS;'`ք8P<0YH%Џa=@_aXޏf.< $@$ %eqc4A*ꄭyHhl(Y:kŇ7gq H)" kSXn MCa-Ǫ׺}xs/(=) e hYJE:XKz"`nnFS:/R)T* $p2úiJ,[2>3*k,eV(lJ8D, Pv=}=a}M$@~I@ԉ F@VY< p՞"^]=)b!Ix9?y8%su&֗ǻŕ4Gq, ZM(fs+nM22`[MVNj#`,ݍy!@̰(Eq?0c_1 ~аHNӏ lu=;EF[7Las+r5ޠu 9I ::f!#!I)AsLr_Y'&6uAA;cQQP AA32=Xij0pVOԪ ̜p3_C?Mbܱqg͡K& %.l0n߆ иu;:9'0>b j. ; M<!4_Z*QW!,:v)yؐx$@'.((~!,*8l6d:HG؄L lBuHw^ӞUd#D>ssLȩD \B%'sss=1??999#ЄKo2uS'SZ[{޽(m(!cGeW´wlF֟кoPD6IIP* }fbE:t\6,$@Mk+L5(.lcO0֦ELb4gG$@$#ԡzDM!b^Q{aPj:łfsϬ 62jtpb3W*J$@$@"i#׼%blEl475*6Xī]lҷY-=+ 8VA@ 7Z%^5DFA%jtSp2:4{&n:#Zm*ŊWQ-%B Z;Ir$@$@>A@rDD9~JL䞢J,Z/b+Q-nY>~Ȝߝ;Z40M_    U2܀fm2~)ImW@E1_}ԛHHHHdu>V5|[ LV|+xbmO Q "!yI+B?C@~վЩ3 kSM&4TM07!Rg_狄bߢ-S%n\DFD    )2úiJ,+jP@B\V[qv虘,ST*jMO5OHHHHH ` E^<Ū ef * G'L^ & 3;*JQ<:*ˆn؄HHHH@?QAb^ (uAA,**6 $$$O % x:77j#''G^+Ho2u adKVUDnuI ; x–RչYM#tqqqOcǎ@Gl6(s'T2u'.YdJ'^f-My S} ʅ16&T֘`@4qGJ$Spc)]m۶Gd~k. vCxˆxMܪw'"\ke!^zcL܆ߥxA$@VPp#2u#nQdJ'~|B$xQYj TJM8`atxF$@$@$@$d`XfEɜHHHHH%Kx|yڴi K     SL_h!isa8MCU;Թs%??999 %;Gd~)%};LuuuזIHHHH cm &Q4$%    zh6)qja݉VmbH)F Ke    02:4{&n:#g[c {S$G96(fՠ`8]    K@fX' h -ӮִTVNOmKYC$@$@$@$@H@fXۚЀNXrf2]#b H{a“VHHHH>bU 1,<'nC }*$@$@$@$@$1YDҖ_>Aۍ5$@$@$@$@$0䆵 uhlC}:AKqv$l֙QޮQ!!a%    |֮IJ")3:bBފ3"1QDZ'N0&Oÿہ a Qɦn.CYb{76APvoB$@$@$@$@$ 3;*JQ<h5b= uu" ̰><;̝隅HHHHH@F@d6mlP^ 2er8␼Cڜ,6qtHQ :qHi!(qDC "8v("HHHH8$Z2%Z2%úIamGDZUSs7tB$@$@$@$0$X;!ג,]K6tiGC2NRCiTKs @ldctd3KGq\vvϨ$7 @@pJj-H В-ΕΕi$@2:g8e!    ' {i\KƶӰ;]Az֒,mj$K\j\YHHHHH PQg8a-AjӨ kɨa-  ~DieZ:kNvkQ(UJE,K{TӰ@XHHHHӰr-ʽ^ h^N_5W%b,$@$@$@$@Fa8IK^N[:w^KuƲ\z}\:g!    @#4FUy [ IENDB`././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/pie.py0000644000000000000000000000266500000000000013461 0ustar00from openpyxl import Workbook from openpyxl.chart import ( PieChart, ProjectedPieChart, Reference ) from openpyxl.chart.series import DataPoint data = [ ['Pie', 'Sold'], ['Apple', 50], ['Cherry', 30], ['Pumpkin', 10], ['Chocolate', 40], ] wb = Workbook() ws = wb.active for row in data: ws.append(row) pie = PieChart() labels = Reference(ws, min_col=1, min_row=2, max_row=5) data = Reference(ws, min_col=2, min_row=1, max_row=5) pie.add_data(data, titles_from_data=True) pie.set_categories(labels) pie.title = "Pies sold by category" # Cut the first slice out of the pie slice = DataPoint(idx=0, explosion=20) pie.series[0].data_points = [slice] ws.add_chart(pie, "D1") ws = wb.create_sheet(title="Projection") data = [ ['Page', 'Views'], ['Search', 95], ['Products', 4], ['Offers', 0.5], ['Sales', 0.5], ] for row in data: ws.append(row) projected_pie = ProjectedPieChart() projected_pie.type = "pie" projected_pie.splitType = "val" # split by value labels = Reference(ws, min_col=1, min_row=2, max_row=5) data = Reference(ws, min_col=2, min_row=1, max_row=5) projected_pie.add_data(data, titles_from_data=True) projected_pie.set_categories(labels) ws.add_chart(projected_pie, "A10") from copy import deepcopy projected_bar = deepcopy(projected_pie) projected_bar.type = "bar" projected_bar.splitType = 'pos' # split by position ws.add_chart(projected_bar, "A27") wb.save("pie.xlsx") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/pie.rst0000644000000000000000000000236000000000000013631 0ustar00Pie Charts ========== Pie Charts ---------- Pie charts plot data as slices of a circle with each slice representing the percentage of the whole. Slices are plotted in a clockwise direction with 0° being at the top of the circle. Pie charts can only take a single series of data. The title of the chart will default to being the title of the series. .. literalinclude:: pie.py .. image:: pie.png :alt: "Sample pie chart" Projected Pie Charts -------------------- Projected pie charts extract some slices from a pie chart and project them into a second pie or bar chart. This is useful when there are several smaller items in the data series. The chart can be split according to percent, val(ue) or pos(ition). If nothing is set then the application decides which to use. In addition custom splits can be defined. .. image:: projected-pie.png :alt: "Sample pie chart with projections" 3D Pie Charts ------------- Pie charts can also be created with a 3D effect. .. literalinclude:: pie3D.py .. image:: pie3D.png :alt: "Sample 3D pie chart" Gradient Pie Charts ------------------- Pie charts can also be created with gradient series. ..literalinclude:: pie-gradient.py .. image:: pie-gradient.png :alt: "Sampe gradient pie chart" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/pie3D.png0000644000000000000000000011721600000000000014003 0ustar00PNG  IHDR$+ sRGB@IDATx]|^ri@$H ( @`T+vEPQAAibAA @&C %!HvM6{KrL>wof^{77;kU*,)))X~5RNLjժXn=4/ZCѣ!j Z')?FMC&o߾0NB@!P(" ^?QEk<ˬYDqF\UWs@P:9uss`РAG'^H_^lݪQE!P( B@!(5&'޹n|iĉAi) B@!P(2nH/f111ZaQ?1?(P:9us@E=D:.^S-^Y)^TP}K;7ւ !1q;.1~0Iʗ"$Dp|D>}4WJcy-mr!SfGI7l" |S'^xx5/c%0 BdտY!;_7VX20ޱ$e6Suq<~N@͊Q5");Hb*͔r)xyOh_(;IbhEjiTT) hLE>T1 zl;]1Ui2=t.SԎ߼V6+|2Fy%'|k&$?ͅceJr嘚ŏl;Â׻ HO4t|)Oǟc!ʱ2d9O?l8?L,!1b\Mǩv}᱙\7j2'҈_诧62xBPC\sDތߏg8f/~~'y.s\d]x5~cX2^7VrE͎s!恊s˾f]$/׍cI@Ⳁt}o7`ziMD=ajAnsL=rL=ɻ_֓mSz1Z\dq~=}\_/fueJ2rݨ<9~̧*l)UyK}!kiy8rlppuoJi&qzi߂ZrslvR0:u_pR B͚bFH0!1gg8DE`0e`ʺg'%o NLWIl=!avo]3]c>PXOQG*r;b%pf*9afD)⏤˦y4WI;dE1c>7Oz*~w}xr/O6R6fjl ^ȴ!,H\ yh$?5SxqDCVAuc),e]<1%y5{QLQ'w` )YV4;he ڗol]{Q)1~@ơ;𔏹\/g4ddAcbIcΔ S+39I_ϊ؂B៖tdskXP>1)ՋGǼ:CP`zzR`Ju]9DKQ)XIğǪGp>c+< 3gD'm0(?Qx@oqDgTJy!%: $^OuF\8s8Jk艊|'JGs]ѬͺDl]y ~{7aX7%۝cI\Ӷ&vg;L#%r7m/" Kg."'q[ϞI|N'[fmғ'O|յ?ůM]Pu?u5y縞w*>TxNAGl>Ox$>GB}apJ!׍GԚ+VَK&b?ނ;k7b٢Gm>\g#%f}7+3F801/OqF6AӖv<2m5V;[6q<Z=,O}TSݛ:fHϬD61ѳIGRnҗm1QE23m>֚/6|@tP}W$y\^nɰ(j#sOmc'ra| nS<35=ϸ׺D`dglN~,g?eʱjqgZ//Le=zLȧv⸞_!b=#Mf;-oSˬnGOofˬt̊?_O7/^uBT ,.wy;}gJu_L_<#.\RU[aɫHGPfbugc7SAL穬+ݴ]Px< HT.VƓuvM\/`\2ם=\Öxp5Jqnd1&v/vov8- (ce܎YVQ(˔t>7iCk\0y㸙jTo6akc;dYnS>,;o}zukZ,$^~M(LsCySΔtz^,39*Y81~@tdCcLj|I+SdzT׋N)Coo* OlUq 4 wΏ{1.q3;r 9rL5s@|R˞EqgJr-/h ޛ_Ӛ<1_Ycs6㜧qK̊q3]\Q}8-A%\y6 S/QO3Y)Q]jѶ!yMgΜŞ={PzuDDDҗrS!g[D~-<7ӱ{uuzc F7s_ٰnk˭5WR'(}p"CրWw%KF߉j#7\991$Ϲ%F|\|^3Z ʓ}1zZݻ:jQ173OFQhfdNԬվQh-n0',3g-RCԮN$<ӄ7OFUfLn7'r$o˺TK.ɮH#4ofNTaQRvG٪}SQqk7'O# 8Ĝe;>Cj\qQ<+~Z=\AQaj >\OY@yD=IG;?qd6fl89 qAXU19#f9.};qO-gQbنnQ|PX/fjs_ %9Ζ{fcsG9fِeuϺD){}Y+*!0-R3/dmc8>Qaƶ,úDD ɱ'>?٣ع#'>~LYlq r>%Jcs,#YIq|%qmhm3\#1Sm.Q*'91'<.թ0eN6Xr1qO+ڹ{yr3ʓ3SMusG$6G]a]Tw9~x#91']q==d[G5+WFPF"&gxn}ħ±u+jdwǟ>?=u)bl3)Leeי\AdLHxJ}w]L6w? ?+˥2morLeeי\7O<FlKcLY)˱ z$oy #m3Mhq=e;Y<ۖ)q`ʶertYHٞLYd9~:L\g(ztL4_mF)91ee?ϱ2?)B:fPʹPy{{l)ۓ)թ\>Ul_"Δ京WX2e0S( B@!P(1b54&^Ԧ,KRRR$sŘ -[UV2= bccmְP( "M6_~%Rx[ER5B@!P( B"@{Yr|{{d.oѣGb3c6XlS.\M@FOxfGXgW.\!s3zY:cb,&b23#0P( BdxY7>1 ~gE܆m{cyI?SB0,.΋7B@!P( RF+MF i '*TUAby tދ|Grj}NNdbXbAkn 2CQ#{+tƯC:@6HGLc==&|(j>8/lIWW'gn萖xtZ8JȉG\ٖ)eљ PVeS!PTsڿY,sUVUJ 05Ǧ "g m&ʪ#Y۶~ &؈ srrpo9-o+7v xT !?eKY?2CB@!tc+@-9}*<3r/< 3Q8oYm*fAZ5*/fP( xٱ7oƖ(dxHC<%[lzQ/dѣxxdlqNٰ`U[╥.d(Tl @xP!1yAYH3kG^H v(t%Z6c)KZ5a3>5:u:w'&Šz{>?~eq0˂gCiQQaJyr%phXn᭕L{09gۇ/}w VaorL1#ߧdEkg{3ESwEv~?(qcӦM7؎2PA:E?CS&!8~LMkݒKOFD^tyh1ƾ-a4m}%7[{ZzG?{e^|?ݺ z|bD ~Gjrc[yoǫ>4Ns[Dql! =bzy7!cN\q!f8K;)Et|.=0^Xi;?]89U ͛Ĺx!5@x$".Kŋ~2 1Q.޻~0>Is.~ƾf-j[юimb] }ل}oq~{ͱ'~,-7/oO xQ%Ⴈdaɻ 2/{7p%ܔ|t]dd{BBqMq%cj'FX֟kNGvMk"g>LLʐ\3+7z'pώd[$澨ITafN{f5} 4}hDs$Y8n?a})M6H{,gW=sFs&801mH.~u7%zI_RD|D"}?1~}[IЇH$"u(}W:Yc?w۷lO/&NzF,p/# /{GyN~dIzc` q=96cЩ^kJDZtiAFXs[3DoW㟯":|d1y= &-?n1GR"%Kcq$lO|%܃fa9ղ%'&8/xT%kFG{^zX&æc/iC_UlkGߞ"R1ؗ(ԾaoJtRc|f>uy"c 1.z//7coĀ{`\z6y5~+1>/07;|Hوf")U{ ⳻Z8Vf&m,X6o6\)6w~  .+[܈I$#]`&U1,sMEu$6z?UC(ǀ/E{qy(\u5*&NQ<'Әmң{Wwrrt퍟﬋:6LĿkO-W&¾kXŝ񁵅¾ic֢ m߯^IC#k4M(#@DVN}7_QAþ?p%Zud^P`NC`5g/2 -َmcq}ϙj?UvF@@# A:7֧dx!Mj >xX\Іzh:d- Fhx-Q4ϫ=G`<n(>V=/}>Zh>cWtp3 ~U "~=&k2;uMzk ͺ{+D/Gb ݎcJv*]#Zaz ,hUS8;ӗCf-r8DH#se bɈl[\2/wh<(fĝEt<`4 ?d5T![AӵEjꅊ@Ǹ)qhBX i="?O̊Pwz¢i˟yTlQ eT͓Uɵ>LCfs+m 1~B7T̆\j?z=*iFETv/D,L]1kߛl-INJoD5{v;B{{{ Mk H;4iUژ)2 4+_cD|R<@I0\% >[U!|;7W)׶ ]vtE?k!=a>{7=vq;\x"FVA 8tl ~vkQ pm;?Uhe+Uʅ@ei8i*!+ė,t\5K=)^f.U rcj{Yht1Sa?ȩ} kaaW/OcHiBǕ7_*tfkhV5%KcwͿK~;Fp,`5oGS95?:l[,xMb]3v($9W%wX%vVCh\[bjZDϯ6%|q۰ '֟3oK߉S/NUC!c@r||SO?`IZfXwRXX:` |0'k.būxwq_N/b=U찊_a5QfL~| ]P3FuɚT+ƒsatg|CQ }x ;ŗ2*[75*Nh<0v },1Nțq/jM!8&$*;\!aZo 7߄֏.&jR=zcjC~hx]/ ?a6^kjW^ă4-([e%/IO&pg<.!hms\]د%(-֗L򔶶ݳ$Z} eb?+5";KJmg z?ENnK;exL1IDLiqOMǩ&J~Q_w$Eɩ* #1[?`ڵظOn+7A>D,'J&ޮ'֌3[^UnXDuemY0Q?}M]{9kV?'w5Ϸ׋Zk܀3g-̬'Q$O96ELWS+<~3޸j ޜ1 -?K-#DnB &N.fcV 1MmSҫkB*g[0!b_Moܾv.?u5Vz;ݗpSNa{Bg hm>hvtNҌ;i;ūdl6Tm&nhA|Sy<~;V/u[vVG4kŵWwTvLww{=|2i\٭^rsY[466 aw󨉮٣7=+$몺B ,>~Hމ&oC(5F>lO`f}nmޙ)(M''1Ô$%k2"Sm%쇒'$cO>gO\U _6@Wo_춑oOwJo\]g{ ZdzEk/iwz7$rp 웦<_%z+ ^ f?پrܣ:5:0a[WOw\[-垑b-3D[* ̱2Ꮩع"oGǖ;ݝaًέu>|7]M{ 䑊S~}պ(m-p:7l2 >܌U/ XZqa<_lJ6 8zlقVZ]R S qF۶m}kXY81bia7;p.!k0jFeOpytrD*yykQ饧4CqYuo}r|:Ί="z_> m")ƴŔ)b Wi[OJ U# 6g_[I31@h_-n9^p-.p iuWWXG,8V cn1'6(B~|x6%^cCbԟ%'fy)M]4BmPGtB@!P\4T.^OZQFu,^p(E=zū%zW8}|c /JMyIV(tY|, ݟb]{vʿXcRM 5u8U #`'T_h]nQ4%%PTXQfM5^ar\# 9];89嵒_C4]*s -EjdStԹ=~~[ kPSg!K \˷U3U/ıao: DU\[W%pGw@Az9JH[ww gjO0uLܴ"4 w,)^1[֧؊;%7C_Hf`7W(RբWk{`EDDbe!t*l+vGRB~Ozb=* B@!P( =W賬#3>ۼ KiwBP( B@!k-kKl{Ҁ0b>>l9)wVzbZ3@aj K:O85kKW)) B4(}kK#6̝;Z*.AQh+L}gnn'o*k B@!eKY|P( B@!P`rf.NG|{ooѣGb3c6sKC7C{Dt"$|Ŷ?5=(jT(lHݼ뛃Ԇ߼xjK@L9P( @ӫY_c֬ HOڎ-]pW83/xk$zVTU1,=[#"܉Z}:d&|} )OalFxdͩtWP( E *L]At.R<*$ k`xxotu]{+3ұgp.y},6`aП1w_xxNT:wa7' KѾ_' rGc,;9QAC>pmX$K%1SM+j뇑<|>GVAcVn+ B@!P*8C@1<d"oOP8,BЙh 2 n?v.v*5y녢_=|&4WCbߟs<ƕHgףW&h6 UA1ym^(NkOe '@IDATގqծǢ`ZhO1Ynǫ7Vdp%Z(u( B@!(5<&i+\ . 8/gĊD BO,O;Kvs(4lG[= HAXB/3y/ZvnEXrNj\x$rx6ãoM+#DGhKdQm(j7AHf`͚uC΢'fUQ( B@!P/0zPd5DfLG~$dwLfM-&_IZ,ʦD""4وM{ɩ[Q`C 8=\5tx2w7c;Ģ%U B@!P쓇lX` Hy9 mǢwcm@Ltq-4SN"P7bYjA7KKk=6kvBK֬Z?0R]cbf&oyRgc[T= B@!P(#={RFk5@5{8|xaƝd"<WLu,tb:G BT=68Іxd!**iHJ=m۶% B@!ki&g-(a6ǦiE%;(? jVy+ž?e |NfEHUQGzpU B@!P ELɢ9l3YP#JV!P( B@!pҐ*~}rtF*QJӲW'NfMXRU B@!PN(}kKsUV220 Smoր֪v!#pd_BwokhZIb*~@(*Up<Եe] f1=}FJCr_b.mVqW^'T]!p@YR֤$)B@!P(D<3'̇E,笔0.ab[>oN>y8ՙeݫK-c&s([q$efϺDTo yG5yq,#Wz?*תPjZdWS7pIf㡓0'p큉gũOZmAa[)Soo曘QLa؆߼mD%?;۱5PS2ko.͊Bd|?'Fg==#njx3znɻ˳%93H[8ȉ:Pu#Z(W x0-%df’{SpӞms}/poM9{Qc AK`k3XF6EM{y!f v;i@6įE-pW8uU;Zu>[.l8y>K@A͜ڸ#缆KF5u{PCpSE`^ 82|y~= q?G;}zJ4^Xkk: ɛФ{l{ ߋةh;=n_oqN<˸5+? GTJ9DL䙶fa9ty(p-'j4cɨh|,clS?),$ESQ;5< ˶IINӺwz+֨ZBB˶-`l_-'|7&_̅qJ̩p%գXxGty3 @vV|G+,,t$7EY=.%6K5JAK_lsסhz]c-8%Wi?7RM%2 VL7A<#MzĕB4<6z8_l9P=XfHӓ@;Q-ZG3|OƽV p0F㳧뢇X 'YqUe1&lvO%f}lnjG}rIGlex$gO}"?0~M7c$u2AatĜԬ9JEC /6-pqnʕdӱ0t}(f8Y}+iAPp #/"S\V+KG_?* Deθ&l_5qYz,/M?xl^MZ%Q9s'G2rIu*lGo޹\5eMǶcLmzfc}g9屉lj9YONUR(~Y#E昋=Q28}KW>[Qycc!J9j}p7j 3{ޣql[.(Ubе@?Nz+7H@wĬ^ ݛ̪QgB%A;o$h_"Ml֬X;k;xH慯ෳ+D^-' "iwh(| mm.3b[]ehDBH&~ᒼ T{j ^!7cZπ)sTsH˥AN9N ('L9$'ƓǕF=evXQ帟\X:6HٖLYҍ:{h 0QG<Kc9&>vċU02ŭ=℡1[f J~z;ś7A ZWNDh+CZ!~mAн:x'k jAcՍd;y-v؀֡M1f4O3YKc1ZDu 4lT|,5/'Y1{1sԷ<;*ݱ-ʗʛ J+踜챰1a6'$}#','l&jO} -uYVS.ыēmFl)6QO:$D{3wדs]@+J˞={ h\OkG $8ʿ/Q^ln!X< v":@Φ jmHXa D ܠْSp9x!ug`)P,]\<2U p `^'66V{}۶m UPpe$ z(zchlfR%IjagfO!y- e;#Qq7_v(7 u5K M6_~> bh-3%iE?ZiԦ,/R^;tڏ&'!C. {YU{0W,05eRE!m+hR񜛦h2K@n,8v('kmIѰıqQ'd1)5SYάmre;fu[:S:'LUBn+ VZRZ~Wŷ(L}'YS'NfM[Q)/dΝVZX t(L}{377W[[nyYd;wsHun1X6˙Qep?|n= ]#7,m:$Ŭyš<6ujÃdN2E.eMJJ) @1%j^jD0dYŘ,|9lϨ+ۥі;y-˛}6SLIL}lOC:?/[ǔgJ{և*gD/׀}HXQ5,Q"oSr BPIwa!L'jL K8dY푬,'S%֗,ggY.ǥĉQ?p"|n3)b> #l$FpR۰ B4Xt;4Rc\P 16S;~Sⱼ'}cl_MSyLIm1eQ,S:$]*}3%\2rrI2< jF&0sL|Dg]ZzS(e-7w*.qoL8LNMu~q划 c7vIVn6 x("1i\֗}`6ȶqQYG7c̣#0*˻$cģ:%~O~U.<΀Wmr9:a޽ࠋ%B@!PnN,7Q[ sA8F9!>.2(e9dd]'N6dmgV ;tnҒfmeՋ2:adq*FMOH]X| nKpƎ_Pe8(kWS;\XF!PP7YVU L# Mhd?dbcSbr(%`v}\gp᱋Ozö>Ouu#e=G]a<o$ϲ[ea=ѷmA l'.ϖ7b̧z: yʸ$=uBP(*kՍ퐕_9r$ddӠlS\Q[cq"~M<^6WYr9cS&i'ۖu~׉vME3R溅xkgjSxT1Y()l3٘>=$Ѻ·'`+{*Rr \0 %߫.'P9&Jqƙp(z |TL  (6QJ[*Vo+.Ujjj-hU\F+A5ȖdO$sgNrg3$f~sysɝߜ9iyI{<[-4ĚE99׶yNׂGKyI7iڗǵ%hV~<:_y:n+U^4su]}9Z҃/#"qy Z$>;o%x| D%@?W.T13#ZZ6Jޛ:ME6||SMV>?6VNZ}@6/}Ea £"jݪ!ZIP"iԠ37P2!2LLKƃnYOjQr\kO,XJ7x43ۙ}u|;mutm/Gm6e>u4mfI7齥I@A|ʮ`,QQ _z,>AO()) b7 Zp{2 Χ. n$ C;A4hNuay/F/YqE As3˘mu\._?rnRw(iڇrڇ9]:]긕om#:JU9mouܜ'6n'݇-%>s&燵Dp -eM6l# $xs{(#`0~FɷZiQE4errNuNhN%:7׭m(ӓWIjqSsٜ.q}^rOϵ)Gd*?<ۺ|_޶WfÙ'_V]1J ː;j7۝:F"$I$U5rQiPL'`6Jnn߯G752R9ݪN&vf{0k;os\ׯ˚f;s?|(.~t[6ڿn{o6V~?]lxܭ*OY|?>:Ϙ4miLA(k}oe %"-Ք( ZỴ4.j%wW񌒋 UiۨŤ9;m#q<"tQ rn]>y _rV~osN'P.zďq9qs[,bw̍O>>j>]z9v9ת$N|X5gzgöBfyؼWGcoq2gӪFT㺃2!8sྸZ !p'Z"3SЌeLtA`H !Ü6/qޖ$ӱX/!Fݎ]jQn~,ZG)c|&qfUVqa.Q˜oϳooe{ӧ"Cplߙ1uߎ.|/g;DợSmNg! w:pIt,^ݵEyvtoRΎ>6@ AVw AQn>*.ͯJ~_;@1d  H^uQLwG2X6B rsʻ7 .hZ(Ū5ؘȹ9qU\+y:1OYFmih%isr}͵{eaePOꏟo[p7Dh0o{Hl5>RaeoO~+?fkEk:P6:;W@ӷ]I+gH\ S;c㫱e;;%H"O`|hO؇|+X&mM"qZ:Jn渙Eb|9neo\K;\2-SlJǸ!IV=G:J}SSb,$%M룶I"ܓO+ks~uVqo>7oNom؍_|$Eb>61'}NPoލjia@cjzLtg ĪF o?A%ߐxzçק-h}ه߷ُs[<UݑHHaIW!:JofoUct92:]?Gmg6rqs|mrR.Jj ! }HCv{^<5{(Yo97 Xs\*hg.,O/9}YIޚSQseeeJ4WLǴ=By|q!6K@|&rYn'K%7%WhI\rit9-2j_6ب1zbo/-_g&2.//GIIId'WyÐix/>RVIjeJ{n'ʕb;C (N fkakq]l/im>7H\#qVb#AI[(_r;{+E$@ $vό$!Gɭ6 D f-%6iޗeYd:(A2Dv:gM8AG 9_ዝfŸٚtaHj J\6m 't_nŰiVNG:ݿFpW<&/x[ WF&R,|ҟbaExus>gp 7O(ݎ5NZ rldq}GIAj9|}4{R}HM@_);_W[0st ;0z:E+B@ r1s?.g"06т[BFϚWDu>>2GF>ilC}Æg{Y !? W񇇳pkzǎƂYp~,E$<n|@vv xQrY^Qq}4K\yD+G_aT3b|o{_ac"rrHl$\|r87ϧF$@qO@uۢzD}Ԃ|.nnI$~K+$2` ߸6%3po|.lNeO.>W#{ N—of}y|oXiS:YW"c4|%N4y([2 O׎ XiØ3O]w̓MHH`!v;]j`/AJ`Wk+֮Y=߉eg wmQ mo?qޒ,5s0iZБc8dd!~ Ĝ較Ў(>EFy+عTl)6x@>N$?DlK8hj2'}~h0s>$Se5]tbkh:pIIzjl>d9϶ll0 ]? 0;uAc yC'`#o㽛u:W]x Wwq)՗K=# P}z,"%'zG)ȿ$@&۟ТIeO/S?#ZbtڇPN (FP;271 ~ 6C {lCҼS9sZf'OUZku¥(;uۇ!gH'jk{J$@!Q.S rQ !s! n=]XmggݸnZn)QϿ 8~7k~bt*q윞E~@wR|!+)^$F,TuȞxp/Q&SUcJ-[E)jrJ$@"`L[QMYҬKF˽T𸌘'Gπp0 tݺψnifRΦfh @Nm%7DFv:~ĽЬnC3ѼGqhcWat#NSS^dJΏ뎲q!P##uvvV=iNEs (x%½(U:jDaҦ2M'׋1Y_czZǗa-`akf\>s\׬1u?ҮEjnHy(yc/>=iųa+oDCa_:I`蹃ip:k^Yo5V`JU-@=L& !=QcVV r1wһz(>F6)j"{MtoGwITmNj1ln~_vV@?*Ǯm/*ڜǐg|;  $'w$'4Չt-եm1m>9Ѓ5y@<ъ~h܆U1#9 vH ;Hw>n|w`+фbvݗ%#b<.Fu4GAOZ{iOa#Q[Ɠy*& w=lXhwfL& WRI "grRM^mތ7=ڼ-oG6&_ݯo /z4 go|`;i>p[W+W9kE^cݵ ٠RTosuZu@>ѮS#!tH_ʄ2?kJ۹8/لo,WNGV[7gF*OSAD J 1(mp͍O}܎hh7vŖklqV^tֻo8b.זpì:TjSK'ܯcʦ?_ŘAWnQmct . Ē|'ұdu3㸥oZ$k> =z?kZY |5hszT 4P-EmXH#g4H8Gua;fݧp$k o美'6`VF޹JSxOF;w J<~ieee'g2 '1Aaaa*O愺QYF)ʖH ajOFhlC?*g(t]?ͯ]^{urv\WL^7˜z8f<˺_n-L#eU^^;yÐi߹+A=rx`iO)6Ɔ8@@6j]G_,~ђ]3.;HW!JKguw)X0vdS#x3G uܞN亦f k׮ŏ+].B>Cg*]A6]^ݔT\yDת9 $@$Hfa;,l b}w=+b꧇ !Er4v^߳a8\6c_fvϊ(z˽L1KlKȸcPcgf_֛-i_᫹^ Ī-J ਫAUU~]4k>CMHDl3 @ ɟ'Gj蹉F@͉YDpEi,De, xo_}PbߡPSP=;b÷w->{Vn2] 󾹻[Sqb$HH J:@uY*(%- Z&HtGwݣY}Vx  3F|~Gsz4;BU$۞SM9\s%NvcXvlĻRsywg֚J3J$@!0@HV  }ڷbW%a6>.[|Zkdu$`)Sbr~>|yyPB$Rkc äMU؈i8g6NEud$d*ʬJT(8 ,8Bͬš@2HuG45)=[7H2$+$ ΄'IWS=~5*-gD&UZ<{6',%6H  fsQCP(lQdQ*Ӑ24ا)wh=D dc9郟V)j7L )we|RF @ 9) Qx31D-$Ю8(z~džN\x;ʆ8wm&'Ј6t'n @l[UC,vXXKUQ,:R'h?k8jAzJO}fThՊ/BZzZL& .M"Ķ߬bM t_m.x}вajuw;'o 1܈tىaóóһ?hG:({GE  sñRJۨ~6cN ")8{1y>5|#=;^U-^*Uf@-?-msi6n]~I8C_n*h=?<x=޹s)VT.>QkYeeeJ4WLǴs8@Oe{'2ݤogcf3&;W܀i-k0[JD9mc K+us^ZZX9,//GIIUm ]0IDATI@0dOxi0Lv\p매#8-%D#_b"85e,Ipo-x/ڔVۢp򹰩iOk{ NgS/۰ֲ7G"sV0,iR3^o*е\_4>]; {|]x {p_{}./|,@$@N,ĥ/|I3oAD*lĻ2W^5xN 'xķ'5s<Èn'?=V~:ڞe *1,uqh#m׌߼]:~f0tr|W)ⴴ^q∖'=`̣cͬ \c͸Og}߉8\u[V e8i@ԃ~n+}>x~[ͻZ갽C'ODz߰< $=-E7MV[G@T HqL ~(D9C0qhFcs=Cr1{[v]Z| s Ϛ5OSўS[/v/ ,~oyIܳrjW,z4߰m{%2 B\W=Fğ ؞1jdvd8E˻0Z%+BT[wk중eO/S?#Zb2uڇPN 8QwDs_חMԣ▷qZD O? [>|jq#-**e-JgpZeeZB|q䨕W+Q}=n-N m}Q|z뛸{p,xjTLFZԗ [ '`'3O{x_6H ~ 2$E} ˎ{UesԤz,v `Ed':8p܆f=뀏X͸ u\5 7+1E87hnFl &_n"ྫྷK/ᒈ >i٪.OZ"]MǃtZ5aoD&J$@#0%OQ`l^CihIF *B2ϙ_$IE՞nJnM^g[<(}b Z޺HܤZ pO,w4 ! b`?@hظ!MbYk~/Z5(vpƵ8p|O|P\v" ࡵsCE+ AG gtKĸ-O?;G/z<@lS;mDm W%/>'-[Ewhh^ш: j RQS׈\ 6W tա2m)߽ rU~~/Gz# ȕ [~8n~j? Fx C-)pX4l,xǰR-n,,-[㼉е]яexLIi @(:LeJ݆LitNQ[" @\0 b0u>nuwCr/CٟY_'ړf{D A1}`$YHs/G#ɩܵ+6dds=OHH@C /u4\+%{AgHb&4RVhq]IL]'>æK杈wܞ987 WMϚ}}HH⃀8/kVuس3E[oXUk[4[Q"hlL(b͞ gH  X Ԣ6Qn[⏷knRXU=*٣G]gIHB%?]S<+&SXD={^9$]veYr .%=z:|Cd3 DjG=:)C>}#%C] 4XHH  t}Խ?st==ǘ'$@@_{mG\4{V(IHH  Ma<]h&QIH udVIj#jx75.+e+x3IȢ7 @ò2-[c oUB6 p͂G    BR\x;ʆsڂZʠG P}HHHH'`)wlFjۉUhD$@$@$@$@!&!a {&wx<RYY$Y!@ ӗܚmIHH bo/-e0!(//GIarn Cd^.X9^HHG Z^[[ @PazJۃJO, mhk;vbOk+\(< C|WL Z#3IHHHH h]탠'qMF+}\=y=wk|u"Gd,/ q       r$.JFǰ, o)?Ҳ2Oe҂Zf ?Ԣ6wljyFWl۱k Ec9 KTztS;o*hk {N渱ebHHHHHVpMoY75VF$@$@$@$@$G t:ѕ ۘiT    %`9F9hhSƩkD^V.r]trP$  @,xǰA!ز[z9Λ<뙞6|x8k{$@$@$@$@$,xl:][ɍnnE[g'atz{5N'    X QpМfG\$*& ~,~V> nt:9탄'$@$@$@$@$"{EEE7<9pO &#eMM 琞HHH bo/-- s7ݕ:" o24 ~e\.5Uͼnܰ D@,6bc     _A6qQWt>k]5upt0B$@$@$@$@$C->{Vn2ʹ`գ+rq7M6% aS%\~،G{-e'IHHHHzX Ԣ ߾o-+GNǍWtcHHHHH KTFt8uŽfń%6Y$@$@$@$@$@,'w?ou-p?#Q#5Xz>ٍ    LOmCcdpdtG!Ѯ8kA 9$@$@$@$@$CZ;QpM6yYrijc ͆'5/ߜm1      qcXV٠mj->{Vn2\ ڹlʑdމYzYjiQFމ}HKqN    H(Sbr~>2^J|7 :۝miBjj*> %    hjG=:i9*`}̚v 2l5"    %`9鋥{q(++CݿǏe+({Wv&    "4yP s?0 `d  kXHH uuhh6vl U5p6Kϯ2 3HHM@۩x$͍MHH ,7z *TKlj{Vn2q/G#;SyE:vcKA ǖ<.{֬3fhcK`x̃\|r}.Z'"DG[sK7y_n>#J''T*$2aZe ԯ\8;˗W5>y}[ 6`E[9"e5? H@-iu䭬3oUIظqEuMxmDviO봰΍?{Ǡ>`_?%|ԅ2rX_SKE;((ȃv<6դ2%L:.:-eRZE\ww%QF bAAexCO pORˇq:Q%Ie/qז`[<;RՋW#:)pIAp JQ|p)}v$b{:\["G6(޲Cѷ#[_fϯ_lvry>-ħ;1[/F:<_eqqAcKAqY[x`̓##+8PObO)B9c>x^+?XG}LjVsCVyC`PqpkAsx qc'Dlc ѣBp95B _NRscXLVļiZTV}KxSY..2`Ygft^ σ_?[C.__ӼzaS}76χ8O"`|Hfs<6u棒5~0ʤu}"gIGx*h]uQCB5?rY0py_b <-((yXET䣴_|i<<FM'ĺ̳8>O,r=t-%"<@(˹ QW/sjӼ:f"'e7kk(yBI㉼d| †z"OޟeJ{2 ܤ?xi:"OKBL>lV()ya?zC׫!5ʏ SU^D;7!;z>,E<6ɐ?k'>z웠^Y,?ZZcIW r? +fZ3kh(E!0]}Kd_tkTO?~lfxx^O"cxȓ2dZkB̟uQAfph+ дYN(l ~+o/L̴ִ<^?'|;,Ûjfc4K*}^4ƆTiZ&دiiZyXcxǦL4/B8F_NciO ]՟˱$Ro)]yHR tUG`>v5`Ƃg2/o/˃U"O1cmD,D,/E,/ s`P"[mҚ|1NX*E:S&A)Ͽi:|%Y6rcg 'n;sC0jfE;S2xG<6 UTf/Oξu*ؿe|OمeϧO !q+rx-O ┉N^ ѯy{ӴqS8t;)uSTṖO'bIQ9 ˠ\ ҍ7kԦ,y\o]q쾵3ƓtG.11ឆ]AB!SBWiyu-.b^4]q]#}mf54H+ۨh/GXdLe=bb[;2"M,}cg\Ѣ dGG*BoK݁:7:QOĆ/J\iiRfvvٗ6剬lN:`ͥq_8ϷjWo#<l\XEƌWFDzN.04Ghk_߿^ל eK\θ| =/q&jUcy:뗴T>gZRyy,yj%7as1??2Pmɓ:5?E47$dy}SI&U񪏾Lsj!vgKTV}yIS))G^ΏSח˷Ue[myZgu/4GSX)_^^_.V迴ߧ|UU.7?iboVLǾ@"t637obrlww3S~<ؖb^C(O6F' A C_7pm-}l QRϳlSō E=Ǣ\cR&{b,d DĦJx].G"-<7Oeby{^Oe<"-?<mỹJ^OԱTV9oǣsk)kY 7YQK:YB~̃i](hcnK*0u,շW!N޿e"-dHǖXhm і<ݬ:*mD<-iDشIZ|qˍ7b=-fjV?PDzȑ<_o)%PX-w '/.GAs$t,vYk>^|[LͿۋlz /^Wph/b/boy=Ӵt^ e}P~ML?q}u}X޿X^fi)"'?BW!EEEilZ&"L mĕse ?iqcy;Yc/_o)7crɍ0ƙ.AxWͿDڷoD"@&ɓ'4㷗l#C̏y~b͚5fx<c^bRp$):{,tR981u$M,bZY]WېH ;k>ogMF ]o \).Ac{0gd*TPضFn%j|cs֮S0sh3s07W|Y?6m@ A?+x /<ƍ{_YoP']sqY Cπi8-r5*THmBsLј6yA]o DT oZileW*d~l9f(zU;&lo7f)`$ܾq1g1Vf~V~C}CH=7W_u0ڣmc3H5?}m#1pfHmz`cL DX!`՜9㑷zIb+@+r;H!&3Ilg(|omGRU|ֵ <~$UI];: 3{:Y:zU*IlÕxk x|qH/:}6{w'9 \볕헾Fېea՜Zƞ8xo74׵x{[L_ߏE&gйPؒ]|fJ\fgDt%D݆WY!֭cܒL ;þ_?Gv/`obʔ鋾@"Ȣ ǒq(rV°d(lGkP;:bN"C?c3v9{tw?vx#m:—,׌aQǽf&N z'3#{0-lf3h݆/1{rcpW'C$DT< ~e}[T]`˩t<"f>!x[sXo\U8Κ?w~֐c)MJtPM>XE'cW[}ki}e96Rv:<:BnǪ˰5`Kk%  A=#m'4| DX'PK3/W.ý?&xuªI[[QJgm\~Ey:m9VŞz1OIl Վg7pײXΠ[j'_J2N!؟{H6M0X`<|}!S/j5{?\>y_(K]"@+~>u;FuP{8/S@6_Le"Na:b?} DD#ߧ޸ \ 1씡al _o[kۭ«G+S0aEG~F1`ykN1G-`,n7-ڲ֙1A1krȻJ<|IK"@@Y='upli[WX pchBۡXW`FAlca~TK(VLir.XrjwLUg0HlWmA58` W6&<6cd/j%ٳ0Vw2'@ ڶӏ]g R vZVLS D(-[f׃{ԯ'.\ mi{* RS3 MsEz5+ cVM.S}gmڎUʕs*P˧2RVd稪Iُi%S9[F;ԚŃEۼo_F^PcƧˆISqhJO)1i~1w'wI%verY"@@!o56){ڌͶs|TK;zW|F6 nVQ D)(_ Grl.{Zop &1MSSISp4RLLk"gqݯTp~45+;ǜX:BL q,bLNQp69a{T;iDLxU)1tOxo.Bթx{B=ɅJ'V1J17loY^?ӕs0]ur`'C,`:Otg, DNkqRoR})ޘ4b}OIGvz8h/no蛷ë)%eCKO=|8 ~j@y:pqg| Gˬ[=—)$D2mg-ql4~GbR~klm/BCfh4ib0eP6C]SpIDѬgm^jɈX7ƠЧ1~,Fҳ`?dnEu :{J*Ny-صSs=oڏû>YQ#~ 7m&p=,\>BH`lc/F.\I7#7AQ+} W_@|ʷ9 օ[`K 1%Իwaq ~>l$`圯{brUJ_C C%+nkKC\2DTv^9*2Omo1.8 =ʠgG|~elP]qYeu eA.[w%a'`K=ಆ}맬3.eB;jE/8&p66'#m'۽mn.A)g%Т7ft/C[0;p0]k_7.mT G:ɥqA>k5z|; w?&@Aniz|jf$a;&Ŋ:  3wk/LjICD^HeފwC`G'FgO^5bЛsfcЩs1'ziO7 8! o򡟱lw8)~}#Rof^ § d:] * jvsȌZ7Y=`>vdBj!'ۖRS舧.ǚe1/.0GX>nżJކv hD85 "0?+)}V=+lR&w~h81Yu.?BH ,nJ,:f sr 0j9(ڎr@n8sU49|N0n%P n DTr\Ēb?UjѺ Hx߆ˌ'-݊˺/i Ab0x">c?d߰OݝAT`o l Y?]/JTQ[@ w[9kޅB}1_8"p (BCCm? BĨ#imݻwW^YAD[L_MⲎKT3EnHLV k39~v}4)zu|4& Te" Աn3pgv(T27~8ڊ:/@C[SNEU3V~U )F@ `31T D'ljv{v4E Drڵl$y_!Z_wK@(OvxP%0z u-РFه"&7C<.c\ D0@Qv#9Uj^ƮnKM H 4&v#ܶ@=k"@3^ t;!(D .:a} L}-LU{G1|/[zrqko D(ݏͨ ǾQ[lpo8ޛ MجnQno⥳{ >hn#WL~1ey}VD;V?}-VQ~2:w=Y3f 5s{ϰ'쳅]`˩t<"f>dtݷQftyP2޻tD-"%P/3fZ.笱2PZSy@#E@@lyX Etj{[ B T73*3RYK Dۊrrxi9bR÷fg_\{SzcI2(=uKV9A,|2i_Xzj7+y.[fC+tP:Nي~uřCom}Et*C[|#&a!VSiH%DX1=CW ܸQg_a3oaQU6s=Ep?^M<|2Z{SP\ގyg.kSGҳ`7̷ 0Q 㣰N1̊E7;0l~}Cm I8:4R"@]3^6Ƿh3]Wt#$;QQF&ˢ<)_w4I}LJ)5ѻy=Qӂ=ECfŃ1󛗀 l-Meٯ>x-k6 !Ùbٴ>>@Zȉp6vԹyyF4t/mF[Wl(fvj*r^#i2l\UɄ!Q@MJ*sC?|f̋/DN$?3Ĕ:%:u[@EA&nDM {vMKު|Y|l(X Ÿ T=گEI D:SݡI]jVa8x=xs > +d%/FrD <zA;~4 HT@7 ~4f?+qQ8ұxǓ{?Uqz`uһӋq`Y}c^8'_{R!`-++`\C-rg2G]7-] 1-˚0]X7ی(Q]{P|l9tn[n-1dw\Uly׸'Z d[A.=UlKͫc3M+/ '"`M%L'R@ܩhll\%ڱ/M[wbla/ځ_ק+{qId% . \Y;sŒKб}3_Gc9G(`0Mu;b ^>j 4y-:&DQvތ7P n`կ+>;rRcMyPfYO B/ A޺˫bmnXR!'+,&WMl/9#~HU ͛Q-I)_EfA}:[xSл]Wtflֈ %`n۲mԅ2-hſ;pۑ:0g\5RYnYm *Ư><9 ,EG1sh:Af=j/Ι\y V(ޝ'W65+V4 "@0 }a0XKL*`f.:۰rӘM҂ʼڶxkNyy23Zv^%!~y:kC]GC; 4g?ަ>Y؜0b>OsRw6 q"PY 6?& ajm1Vb~&dI fu c2[|[ -z{[' RV`VGO(5_)Ðb5=Q+8Xhb'׊?Yr'R|FTl鋝:dI7Q$D@) o)z&DB`̏ *g"`F D,,gZ^nQINLKJv}bjQIkӒ][@j"@piَR7Ff7Nmn\6Ȳ~ _s ) Dؽ*r:L!ofY^+=ƹE{qk}kMF߼=^唙|{3ӥׇ\$zKʳ-&EDܹ3s|>khupQ =6s˶_]JD"@ o^lbBοgPuxvU: 5 Dex3nfZ-ۺa,l`!PL DI~fŀW%׀?> Ǒ̈́ D"P< V&|%׀7w@S-HYzDJ DTMv^]NoDm`-ԢU  DN4;?g¯puԸH. D*IU. DgDZzʚ햃* "D"pexyD\RݍMuiHU3 DJRugD"@L [@S&D"PJYyr6.e/1- =me.e%egmy1%S. D;Bgx˞\PrGT D"@63 *[GuC3P"@(7}s5^O^¬k٣=j1K/C Dk*+3D W-"wmG&:bγl@ DI/ժr̈́؃gٝ,cn#Ύ D"9գr͏_kN"3x;.]AD"@JHD7Mi:".SS®: D"`uO Y7&2C D6yaݺ6N>oɻD"@'WãXY +aqz^.5 D݆W0eM DVs5D"@pr $"@;r XMrcUMpJjSǟmbJLO:%?w$"@Uv/"\6o oW"@(JnÛ~g,9O2I?%[+"@LUY:}X1u074܏ K" BQ͡.ID"@5v^Ev2GLƊQdA _/ o"Ӛd'D"@wwJx@KC0 D"@'` QhOxTJ D8TD D^^RN^X99 ]]JT]ˋ)tP%"@ !Pg7!2.: lX1 )D"@; o>[ gC(vU[ww„خLҒ"@-vMcU xIukڒOD"@  /\<&My",< wE;Ws楈mI"@]5Ov~īU&\a-p'πZD"@d{5_f{5/媡fG1D"@v^WU6۫-tEM MǶYND"@9 zͻ_IQ`2HGD"@U^m6mXhDXテdYMD"@]5>;dgx{@?hA+@"@@q2L܈ȁ Pzr2@ D]W+>xO1ͨ5iIٮղ *!(w]vSf #0Y$HO:J +1** pwww` Ҕcǎ}g֮]ݻ$"@@) Ԯ]l.]J)f~VT"@@ x[UmD'M[7%-G#WFڠ[B DTyV oX?\P]ч1p7CSFY"D"@[b)ٺ^~ !7j_M5]k U4~~ D"@ X5!m<0]aw]oZЌvxu/ @"@JfmF*RU&Yo-Od2ʜ,QV͞[  DTcVgz&22]U<` x5BJ*"@ D"hEhʌnHbxyO9D"@@!WdOIGz>5-u}g+@ DX'`˗ĮLF7.žwaHlF՜֯ ԫ c[P D"[N}G> 7ٟəԷv{2xsmxG,MGO֤ U׉zr SY) m"@L oW~\l{ϟDC'vABhr'NoOBN{'Y:HzeL839 ^}z"B{&Mg@6ob]zټbK0`lK "@C@Q&[FcX_Uxpdt`ڬ@IDATlݻwW^Uʉ@  }1cSF35JZvqg0~6,s2{A,z =H)/KbMzx89Oġni_-[M ycG'̑ ǫ.BLqD1"##qIG~6]vlnjjB {F-KЛeL>MD8Uk- :? :5?bB ~uB'ݾkc^I3[cI"ub8V_AO}[Ю4W*P p4IGxɇۅ#ߏz}`MAz1Z(O)"@JF+-`Fz\Kns<7K6M2!OY͛ElB?巟jlUܤxc]_1> ~Ѐqg $!f\8pXmlNſHY6㭘 jb4ظ {DtzS}z7X1e`l(l kC("H sEASbHM,zߑ'dU.=,:. LVSaqܫOqȋ=9{{}sp; , 1V4>fߧzKy7f5@p; ϽyneU֬g: D@jx 1GE~Z2)&D/E>Cȫ\`6c\z#L$^hpv+Agi#c32jF |4 (b|g!*(?gs h,VlsN"b聐9:"z>m3,zyb`?>Odc7"S}~-?N}=$>;$@B9 v,6 lTR}.ft@#X@2h 9:&">E777'uv#9n9eѥ"@-Vg6:yDcs]u b[P! D"X7-J4>uMgĦA͕]nאxER踛"@ E X5[ 8ߗDن.,G4vcڊ `A1 D+^kn#:;r Dk޼J5n D$`cUT"@(r XXT"@6r X/iG d'C D. P0-`HfZֱP{+ FZN>2XEyj- `zB~<\.ro 7t("@ʋUk- 'vA __F^ -`[JlD% !5q鹈g;d J\P< D5PsM"@<׺[@S_`pa3>G /Yޒb3Ԭ4/q]!LVI'jl_zE7ipuF@ D8Uk- ͼ8Tq!.]NHP j⷇J4\JC13ٲ+E6.1pW]_tnN!lPvA D@=K ҅ pw2VF@|d*&theU+a>9Àв7z-Wp9Q4"@Uës|vxw ߾=k~M3b2Ʒ&' *L¿oDx TĺB߶6:0ݎvJc'D0Q#v%gj 8p-jA&b&VJj_;ԁ[9M"@#`Zq ^SzQ}gu>y>uNFcfbD z\N3(UYs1.'Jxx sx)DI02C^|AhTքqqoQ+IlolAҢ1n7v [ta"@,jx2R#馄 tAKC/j藃Qc(J@]î 8_ב5)"P= X5A^3<9r 'J%"qm ۔Û"@#@n Skث4|' %#q;3fuxr/ouK "@nKq,w\6vj&\ዯ. D^ ̓|Rg!@n+LfdF7*D1Y ``wL$"P GXX<*x;Sծ-e& 'kUpl<ϙN+YcM>p+-%0r`؛(q8yZwXu,|^mN, Մ70Gި!_~F]-Z5*3<>LFO_<k(5 DBۃy#bF8l^֘UPMb>6(^vi -M"P XZw XoN'̚>.0+w׹x~f?͕_¤[͵FXR3z; iYHOQ!'#YyɃ-Tkئ?}nZp>o?OԮ>,WεȪ+VtթK!U`\PvPM;/ˉ6q.ΉF\z>*_mSh%[vٵClD2b_T$%d@vN;zc\`s-ls>f}Q?BѰym:ӷ\#: lޢCTxg<18}&*2] k]olG0E ,. bVF:5b4̸^kHIcc'|Zg,͂f^(u@J@зYUZ]_*r&yN6;~[㷢 lVlNuoV oqnM0ӌJn-o8]IGGòFZl&~,%Ώ_[/aWZ!~+gqro(-:;>4xӈ7Ӱ`r!p4,ŔK_It&L @?|jpOi)ر4-;;w&U-`{] sCc5l,jzuypNw_|/a˟gPP׀LmZf|>,q2Ǝ.,#͜< Jȱ4@=ђ VSb84 ~w3!;[ nT x<Wq#иe]g}+,^ &2RU.gm?{ ={^۷8(6K+R %`r)?.MG|J: q#uf f0@"Hfc)R"W>/JljФ0*3VM6_~7n (̚5 [_Mz!{62*JsG#p` UgV6ϣ)F"w?iP1 l<g<*?Kt]Z-{AdA/݊qUrAd?(  -ҽG&=%L$}4gߓ9z~.5O#.=^N$\V#HQ4755U$%&M 2}ڭoZX2u|EVw<ԶpcC^w|a1d#V!-fg E|"ێŁۺ}3jAw.>PA1j,0qV.Çcdž-iQJSN_-~y3 r$@Jh2XǧjF1Y4C*vygכ!E:tLC"((QQQӋ]/"=9Gg>|_[ͦ4,ZGPe>$3)$8/vIIM_lݺUjfeeI㷢LuMW{= Fl,`-c!|r`U TN5ʹa裏ЦM꫸;!^_~_]%v'^6T'C]?Uto{^ o ji ȦΞ<[qvXG<{OB2o3rJ|=z4+*~u 7ŽO 7w{ɈFN=ح;1埥2ª۰*4(I'BXtceTYI6_*R6{k{qe6G!UkZCx,}p8~x;:up(ZXC4C8*9fO&\Rk8[bآOqrxȅ4{i,.7mbWtޙCC=19dlC@xi4!>OWONZhkx%YW-?,ۀ5|H~Wt34!AvrQ54GkO/21ջȬj A={… %u a꥗^Q,\*s?Q#QUq GL#G _-'hO{Q]ڦ{ O^1񶯑s ۓ'#Z{Gsa?%u*X#j=lS԰COLHprKodz~T&\ F l#:SriWHS[$LB09Ԙ1QnDsrrvZ,_]t{'v]Bu]s]_9>cVh"U꿷ΥS/h8}LĜ{Fq?%`귀C?&JxSz+;FBL E0+&C88@c+O==/`,]A'g$ZӜ4 Z#MLdOBb[U[88ț`WqtS Q8Hyqd"%-DGB*.0)φ4Bd~hpz+`ʔ)fhCeqӒsE>=劏NG^buʜjy[7k+UF9kxRdGm^K`Je )F<(ިV:#'QP%ΌmN(p޳Nt~ѣGK49]sK %֘.q̭QԄ2K]9Lڮ_Y2qlo쪝w =>HsGRg,S=20(z >Y@Q|Mqh6l b("&h%frkXpb1Xpba h1IZ6%\xQ0?b޼y8uꔤ+ڔ4^;oGWRL褐fO#H/< /ī \3hLS,Q\kq~62xm+ 0Ng{O/'5C6Xڀ;rsTsji3…1vXt ţh񆆆VMR"E -zQKO~K+|UĔF3%t~w2pd9rf>EaX|ӹ4Z%,p+]&^\mjI0R8Uӽc4LÿCT@y+b %:>xJĬaMBw C! V'4c1=?O~3x& X/}RN[`֒)XԒ.iQ~Y-[]vѺuk\3.Uw2qW jvz.]6'_aTȖSuw|if4?w-jw#)'b65m߇h<ǠՍt侅Vw1ҿx+>ZbkxkTFFu/n(bMG՜X_l⑵w. w pxb|'pssGܤe ,@ń/nDM#Z%'6jGW8[SVR WY6^Bj%\+ h|Nq?Vյ+: rDi.3eJw `~f_6ִ&'˝Xf^EhI;z{4IJL1clm`߁&TTؒbulޮ`VhKF?yU[_ĥ 1nE^84pb1ȉ51iNTCK@ڹZ{z s@ kı>i&e }*N%d<6I2{j-4Y,&J.G=ZШQܥօ+%j59Q C[MU[ٰ, -S3.i+J]rbaKN,!Vm А1 &ʶbI@ŴAbr6CKk0}uYh aV#`uTEfMFV~-'M/'mȠ-n>-'%AD ؄O6A./`Y@bWw4 ;5hZ?@ݱ'5Z+٢@.C6+} bE +.[=G&#(+IO*S*9k ^4d~mѧ@jFڹ^-eݲ",7 "E?^mۡymkԁPFn97"XωMW ʖ B!1NmpFFrӆf'}FݿFϞɆK7-p/5[FT誆h&ZjZZU-s&`~G+,Q Qjۓ/mX-}اJh>ŋ4dة/>Z藵F_S `~jR-B=g㱎]N O@O?^0aWަ7߳gF klyY差uZ2i3t! AvNNM0JAOa<^yb%nđ_W#^{[J*[i-iYYjr%s+SqMqykL= @9fZ_[@H^^p>t3G_zȳHomnI'+0DBCCqK^o&`lm+Zb[BZ5I0'a܊y RKޕQ9 QQ sk9 h(>y %KpML6 ,@>}yfLý+g~7e.mͥ(\=:.MXE]˲L~h&0̽xf*vֈ[}勜= ~Gp%[Xn$7-Xŭf3=*ζ-ōD#+haxoMq F"x|{|p,5igI^wwwg~+?R9sHb qݱrPk)@rpc f;XyP>5TE66RY({agAt9 =߽{ʕ+ âEniCo.ixG\lvmk*xvC6;E{`'@BVȢO{a)IYL;2.+˂(>=SgW̅\ =0;(?C)1Uwu1{Y@;ZwCdiJk{籎/%"'bD\}ѣnXer !Q/lp': !C&5_5OOnx$bKU.G-(t #KЖ{88J{M| :O-C/1[zKb , X3Ǚ a[-.5XR+ 6{E֭;dcn~ʋZPN3;rzFc& P/xC;zA+ S¾Wn[1u/]ĉ>7W۔iG@Q8pű8_TL VIxRąq\R /Ie !NA 8bCǢ+ׯ_]vI-7xiiU@εnf%#Y%]QkFWiLK& <Eo=c'F=+a.4D; (բkvF=K(۷o3fCǎxRW,VlX|+^L._-^I1ŕ˝]T!-\F5JFxs*lxQh30VWkí^6@Vw #vZiy6l.>|/ HWOe)/0SoA` W,(D&^ j+tn%90%i wBt9`„ دwI.*elKI874r5d>߀?wpfJ.iƨ񝃛b9KZ@\j -%\C#(pݻY>4gz oi+&WA?L\8w #׌ NTv`wQ܊ؼ* t 6?[^:ѕ+:$OK/h)H3OO__,@-6Ey\b%6|Ɛlc7qn֬3i9_-(xYކ[@8p NZ;wƃ>/6{\fɓ^9 /@,- Y@uGbWaB9RVh{PLgw6K '7nC;v,Ə~٪@nZ7fh}%Hs"w9$ xF%Y@YBmY |g;Ħk^si{yB~0|~;k"}C ' n"Wd鉗_~YrA_c…X4k,HÐ; :%ڔ:i|o3_PØ<Ր9{01))q3yEE޿nXq鵼˂ oEp!R'rӌa:!ا7*/6#6$G@d' *li̇ZYH+wbk֘dv^qIIlgϞ| I xb;cv wo3%6*էSNpMΞ,ԴZݍT*I, x*=C/ 5ģF/bMpvSOL6Lԫ`Ie)Z^3h]*.6)TyїP4u2ZdSm0hlJw@IC(=nptJԩ3~\L%{>>2_ QQ\ŊO Lvρx%|?Cw;E7*uv.\>_Ykl2Lry׮]a,]T ݿ~8AtQSέțD\SnXM"7›FCo6Ar K"]=ѡGLbɮci{wFk\~Dž)Dw9sicUMD|Omv;>CZdūvWZ&ذscqI}8AZC ߀ oK>6&>59t3pXgQ"27T񍍍ȑ#%'C@IDAT?@NiH9p3l9zcLד?aU!ͧ@ NC!z]oZl:KptU=C<FSKt8l{"UEsIr^`{{RguLþPe|':-5œaTfDgoB(i.ety?Dk5պyZtZVm=J:iOiY`-^"b /2.L%JJܼd*#Qϯ7~Jnndr9رc/w^ XR-v1 wVOP) k[[u[q|G5]Q}݆ L橭߾HB-䶥)3UU2ʨF~t!Ţf,fB-:+G 7'3:]U;vģ>+W4K[ /4!~ (_b(=̛m`Yv%.\4YICeЊ;M}VkI}-&A۷oիWڵkRwذaǻ/, e3~G7G=sŚ0gbq̳jل+_k֬ 裏{)_v BqhPIwIpt3'RiODn)zq ĐMMqabV6 mc[=yfl9f&08?h:uJRFz7pS٪Uܷ ؐJ:h܂YY~0#4QMOնVGU&"RLYd%yH$i@f#SӴvƩ(zL>,z`Z]111R˷[nA =z # uvaC3$fZhn{y`e []:"zJ 4[^y#BB_OCI ˗/Q ;n8i_+:H͈C:!Gk_HS;rdz0X UWTnvA0/ ׿ pl޼YRDHBk4#7fpnƨe_bƥlYE3,.5[! O 'wNLR( hkӻO>1P#$"Z|.\ I>m'Gl@^ar$}-VXhű8_d+[ck{&*q3ź*/;:5Z, 0b&ߏEO/@rAe3x>np0nFY;[,MInb"o j[PpV=!9X1J!&3 ۡi&;͈N,N1nミn3>Z,deǰ?>bkpA1dzltiڂl& (=ۢ'JE {QGE|r|`ZڑSftf,6669s ?~|pל>U/J05G3i+l[^z(X $ X ,`A!I >,vT8qML0`)|\N4j)r'0bM\Ch"0ޞ--Ni {U[Z̈́,P(d,<<:& Ej\cnKx? Og톴`2vkVW"x#2ƀȶ#!6)M@z  EB.)UGV-&vĊWw<ߪlm߅A>OFϣPch~~~xdڻ})vy-pٙ4s|dar2YY9W"@tT\#O;C̔Td9[&bѢ߈ZRFҝ޼lȨ- q9 q %f^n6/XB׽;v@hNtޚnߩdx5Gn|^scI(6碶 U@UbR@i+!דi9אu>kְ έց n{wRS~4uʺO 生x1b.$~齫2@V~vr'pעJ(f {t6QqY ɋGN~2+DaQԺukqPpq_%NA,^P7NË:dLU6I%264+&\y8+l sjE: dumZjh(VB]"6FWKu66AvNa{ nk4M':z8sVh,h2mh#CN?&@5BT΅Ήh~V' X5su2>5 4rh!L! h;c :{c(D&o\Ȝce3iGZ` 4{6zVĒ/g W nxlt5gT/1&E@MH<=ɽ9$ <`|\R`c9 <}Hkh o MY(|Suuڀ`@,``LtesqbZ&køyI7gtǷo`DZШPr:N1*`-N[.  ^kq$a0&a[ocJVp ; ?Da :Qa_AbyPo 9 ؞.Toj 0k&% ( ;2uyto5s"i﮿Zhe|hhнe"Ƥi3&`itZe(/ix +]pOwcݭA!pgV?ǡ˩#& ѱ[K|ht2,ja٦?9/9~h)z?9|/S72[I" B0/`z59D: -n l ''t@\z>~>Q-IOOwO3&ixk月>&*SX? i]?>=X.$St T%Vz`, U?j`&& Q@6[-GYb*U=z%#Rq#5U| Sû~"dO+ 4Fb!"ܖȄ2[cr~&>\taOyR[99`#& ()T7#膾wZ#:%od MƊ(^tLOl{xWG_́ 0&N@mz!~.=WKq9LD%s 6δs+Z8D{3`VLe |M!&Hō|$dd@UbX}`1)hM6NYBQhs`L d, ؂-,aVL΢-Z*iƴ%(M]fWÁ4Sװ#mN d /{q80&XV&-P֩80&u;[,Lx!  i?G|c_ `L N[, t3l>ȑ&8`§0d fL 0I@]s>ڧ] '7ɛ_’)I#˖e~L 0&P_: o]e*3-Hl)@8/t`-n[, S^'˿CfꓜK0MBOr&\s&0ZוY$(),]R|uA s93Ct`Lz 5Bp(=̛(4,WP,+xlDJ ^p͘`LPtv5& ؕf2']v.>#ѩeJAp:L 0&24vܜ?J&b6P+[5%`L 0Fixk!:p:TP3THKۘ`L : omLf (. ,$x6sKp=`Lit:Bm8`L 0X>dL 0Ke[3&@3JY/PZor[q#֌.3e'`U4|cDw6Yi$!Mc/8Vg{sO7ŋѽ{!Liifxznez4+Wpwoix,O^'o:D̓P~E3+ӈ+vvv`W-̴8L ۘi-pyIF+uLt޺dEl cӗdtE/^:S2E8&`C@ %"##q-2T#Gxw&g[p:l"߆ @Ҽ`L 0:6,`$/2.'@  җ@[9\ 6vuė`L 0X/]b. Jp/Tj&aQ7%`L zGf, ,+]S& h OkqBcW 0&@]tdwVM#4fe}2#Ǣ'=6B:`L 0H@]0עR*X"9 UT&`L@vY@ud< s`jl 0&@M: o]U)JFd`L %{9| 0&h իi AL`LDeEK}G[mYe}cqvƌieBr41\v$35`)Rc /=`L ${rEMЦ8 ڔ) /_x9ЙdL 0&t޺dKNoOU=s qv`L 0t޺den#|5 S#_BBnkUGL 0&ixrY@1)t.I¾ja$x@UTfT=y>bL 0&mx%Yh5e y )֯"t[/`L 0&@4ttaalXKbd=Yi&`L^+dd2Y@Fe2"##A äSjUy`L !6Yn6([/g`Rb&`L6: o6(ێ /Xs}x@d' oX`L 0}t޺d}fOfAY;\9KӗgL 0&4u%\G6rHQTg`L 0%֣:%4u0&Be]&`%%gaJ°4̴ItLubiIf$|:o6SԉO2&0cJqrRi|"8T`L X .Y@ jN$W 2~/VO,\ &`!. MY wxi H(0N)9U&`VB@MP{dH0a`pm W 0&6^IE >,V'x 0&^u"S,ܞx)(bhB5@ ́ 0&O@w Yu$YWz L/!29F⊝7n9R?i`L4viZ$݉=olM#\)Av#+&` 4:`ȋ!q` `Фω0&`[{>XQ {xˑL`L J@wWH$\SBa HOWW`L 0  ovPA絓'AO6@RRj~i2Ӻ5:3m8`uju ۷Tf!JM lz"B5̴0S`3111(,,5lg̘7-[_~`L Dl޽1g`L1dKr3[}|W •hT=&`54ufG6i1,F?9!`L 0&PA@]srq8)L 0&$: om* DVK`Jer-\V&`&&& H ]MqhWtIo|_U"M\xΎ 0&9P[d+#mdlW$J6`L@7-^O<}/C3DNdL 0&ixkfCes4>E80&`uixk|$ː6b̆#0&`N[,Ů]g`K*E1L 0&'usp#Guɘ1& PX`L e RjN 9ՓR;Qϕ0~>4 hwE}| 0c8s挱e^#΀ &Q)J|H&Fb0-T_<%H̠B\&B,` y\M+$oSMtmSYsK 9^^>pzn#>,ɋZ2zx,ՋpiNBArpi=}WCs <| `D4l@VlĶ/A?ГcNܑٳ~mrN/~ üW> OΝO<ҙ/b1o8GDwi<&[U{.jOȮ^zGK| <G‹bkMG=Eȓ^wc={ٷox }<.18xQd?`3E"6+¢|li'k1nWR̚O'Au\p'L]_o^)e}r'+Zfkxf_\G@tt4N<ӧ72%6鵖>h(K"-rY 6`ņx3HB+Qt'f?\dt`F_J؎Yzpvoѥû ^c=4yVp,f7~HFj0ɇsK"|<|YftHv?pXEBWݡ@Dr[A".(}4BuD}fǏgD-^=T Š__꾽eEŹZ'd%v˾+fށs^Cª.lah:Q+G#_2LHp4iGvV|eܶ8sFzC/lBT0T/Dō@ dKU*Or(BG@( ]9qb^jS6\ X#1qYd?n AikTt?y8o)=Y6A̅8y+Rzs_*'y 0kx,}Q{ |=;7S6181KZJY- &?1zjpOT閵7j(-Q1yxKMw s\/pAO8^9}"^v\sC80&`H: -ߏRN 46ÐsM;E N@cxsqnvE(&bx|Xw7,/s\ts<{K OFe ܤndsU :-_~9g{ Dv64~́ 0&`.^O]%<rR@!G=HȆ08a~;l<>n.r4u<2#ҤnVJ4is^!5́ 0&^ RI. UpY i#ȉScJN]1GQqIϴAߠڽqZ4A7[@\M)֖GtNްSX@鹈L X#=( LYe\U%#@<>sbʋm~._Jgkfuh I`40?e8c01+h;?;nƦp` S\L&od ' ^.?!DyV!L %J~#l SEAVDT) f#SE֙CH Sh Wstgp5oA}  : DFKkxUU-PӠ. Dž|sf ̢"fV1z8}- qq`Y@{d [z2 ȟ28u#4QQI(90&`X:juԁVzMR1X^B[x/?SbiB\, h%oz11>r I9%f+0xVHNNF޽~$*NϺr:89g+Z$cJ0.# (z!k-S%3}x{6|ۥ+L&È# /~to{:Fzd CiHܦR!@p|ߜ\6 W{PDûU^^ &`xqy31 Y ?G- YИ_<6u=-RMQE1sL8;;cҥNnD: .Y@m5^mXt-mn 6BhADѣXv-I:`:լOP/)/DVE%4,q@nF&<}Uk\8w=‘j1M/>l=4VvD9wLմِ[| > ///Cn=%($dB'% G.z;RGSO=ݻw#<<'|1[J:@l쬺g .ׅbܻ ,kYȹ-* ~el;DX0!!cǎիѵkW͍bB@ὕ, dc{?\&ڴʕXJ?3*bx7ۇ(N*e吓_m-^e3ouȱL*V9>-ƍØ1c~n/D, hO gNKb ?[ZU'}QBx2sb@e) m<ѻmUtTL-a޽,hOi , h ^{XOŸ)Kѭ"C<nbM^pZj'e huu Y,)6V ʄ`Jr*2QҽZl.Xo"\hrbw'Án,1۷Or&rUaxcIdQ(IRcGӪY4j7j\eK/o'oXdL/bĉ駟Ю];ƭ`6F@' 荁 ˜C#m s:jfcxE_7b '$h2F"rq333ۅ>s=`L0UHs, 9I+ONBM.xd]Ha1{s23ݗ_ſr.--ŨQ0c L>qUaxPV\)vKw]T=0P@9% +Q`)pbW36lx5,MZ>KLGm4gΜiӰyfDGG7Z\`VëOܭ.m᭛ʞuT+b'&٤|\$Ov5JMMU{0/[ }$h5d%֘qJkNn>jv[XX#GbΜ9@vH, fM|{I\&MB޽!<91&4XbbVkmiLjQnEE>3υ2[ 6RNLPFn BLJ>=NNZW m"#P WֳR)5WZS<-y=c7tLiz]ѣJ36Yc "f:ExWR~w"۪n״}ƤQǰ93mMV5^! xiY@B43iEyXhYG4ظ*B(=!;Y) 7N_w̔ 6Hձsg UQy ]C$kGWMgoF!MIq?n!x:.yu>,Z&/E‡7–R?q~u>hwq_#] @琳Xx-YëOP^US <ϭmD@C=Í.Bo` RٶYp%{]~chZ@D~*~#QAֹ(=ެ$ 6^hD#+9+S Y-/g]: /,`1Ȼ6.Ϭ'ѓ \/Er2ccƷd5;kz<>4S‰ 4l Bzy۷:V* T{2 \wO]>$()RA;ߪeVW2bI%5R?d63x9 RԺW)a(euH 'o[+e\$cZWڝÊ%^Fo#26k]}|\  bU2 *I~4R7r{s;_@VtUq`^7߅d`KZV\؄wη mk]SW,`9Rx{0oCTb]);Qe8]J2lըh2`n'{+ﺮaC2k)*ÓWfe\+14dI' w?ONWWE.~u3 F')iA%'# !&WH:.R9igz4ihL~=z+U*kJi A"(c^V˓K}1a# _?ѫ\ 7~B~/^.݄-rD+׈5I'Zy8Lg2'BҶ1;Z_0 6_0W3(ܼJѥ{LVL:kpps͢!\Rݢ? )S>91$NL X='׫OQL+%`g H8†\K*ثBM);VSSo.pQ81&`t^ǰuz3x"R/ȆA].@ tn1.dgB {S ',2vF91&`t^7u_{]( اw/x?Fř٥~ uRrVVgE: -d}U1- 7BBG:Fgى 6ϗ!ɇ*kGJQ/L* 0dE?T(}LiC1clwael nl63VShںJE7Z{~(ikGK}/9Q?ۺF8!ĴuSx3H^GL 5 B&uKE {P;cȖr)d_MȚ"L' (ɓp>9jh~~G-Ӵ5ѩ7mN?I*P=mM[P|#̸ۗ @nw~(|>}% XE qCO$T/ҁ'톷 G~YZ>CȢeWvbjt~wM!?/ vp(uekYtQLES⨗Bi ǧִ5ytewq}]Twc~k!J`.ݥ2͊޾H=ҏKdgCV/AF܎>r(@Jr]-GFv N;/8'?7tik//U!ԆĴ)Ь @Obد!{J!p *oK^qp~['4ROՏ#dz'.!xx%1͓k1ml#r&"XNE^6j+^E3DU~28 @qi9SoC !4m .Y@Yik/gG X @S7,X|,]b?6oX~<+Tac"yw*&}\+&OJS\2%W1<I2S(Ŕdž!LJeBVqXM]e}mnm1jO[wPMٶmz5?_d&Щ(EO?\DSR\j6ITGqZR5s#&bhI %Q~@, x[o0Y5a:[bXд|89B4SXB2JS;_יPlܰc* jg֠|r)ľߪ[M?w*t_kdIy>\G&x#(%¼li[-0U^qqN#4T9s&1n8ܹμL\Raܤze->ax:fp* p$,_o EVeO|=oNg,^&L?UVb. 0axw[q]maIL唘Rht‰ @L#$f 0o&^uVȥ1&`V: nY@T. @D_Cڬ چWo3xR|" 5ȉ @[Z¨νzBtt4NZ? gLB 0zdidI.lc5ٽ\3Gki! Ąk۷c`O@8}kOB<(_hL. BX~ H%UTk/vnr@Krؾ}{]'NĥKU\ ` !eIx۷ <1DDAJn!Jr.`@pT7UjHN͵N_!й孷 {W#F@fff4keL`Z ;yW3y/l;.ЍĽA*چ_KP2⍺. 2JQT;YCmtka ʌ30e3 WnI@D,wR~}_.B.d?TdmAg?gNL|H9Jc"r;}tD(pbLh5LĄV| d]KFuitg+?xxtӴkf[C8ľAW_ŢE2&H^-dH"PGvveORLC%HGZֽ}ַo_,[ #GѣGf3yZN˗AcNU\ބ9^g ΞV5Ŕ _&__choL{ Gr#x0~8Hg, HU͠!lx׆=A3IpU=p<=y18]ڷ1% 0(b չJ' X^By%ŪpOXRVo3ݻ7"##1vXCo|L@ ?BF{}%R)4e(£> y*St VMҔ!CEW*fR-$u{R~,dE z>-)yTKPD8ˈ]s%4ޟUa~D 뭋Wg&@nt*c5o[nСC=z[y#AVω{mﶟ[]7럫"ek& YcG" ߢ$zzk8n=ۮx}i2MZGZgZjԽ{w\Rȑ#hѢ>۬@\emm9Htp+-@}vdP\؅) j|O2+'&#>ڭ]1oY@cI <߲jtZ5Fmh5shk(QTJf5jF'0[:Ж2KOb+y|w}OzsYcBO E ng*: ~Y}xCQWxH IM*ZLNVz刺k//<л齘 a* 7|A^[o͑l1vu^ !0JYϰӥꥂKa<2HIBKHaa R9Vms') b9hb~uh֒HljZdO@LjW,W7u 6}*ܠo nw5GJn G2#*ډ…>=<>'t߿ZLA91&0:~e-‡ 'ʪdD=?(:/?m%~aZ+0t[r~jh+4%=rOCM6X~zM[N ! `^h% bwp(E~NG].*ij_YoطASxvdHtLD4x L6AͦR\d FtkZ\ixu:ʯP\!=`B ^." qËݙ=( )#i˘ɓ'ߏbg+ϕ^}>KqJHD,I` OgG[8LRb}b,6HFC:,<;t)Sj!L h' Yfe;K𫀦jI ` h5d%!ANʂn(NNm짝#}1wDUsPgc5E$hZA8jrvvƆ ЧOuq~&ë_Pv|>%D |}8R=:`09Dxb+H/f/< w6=f3&j- (BFn-^-f질} GQ\@i. })R'v+cLp6%3 cīG b7i~PK H(6ѿ8Zm*LjW̉ 0&P: /i]~)9?[(BG=qÙnZ KjY@]U}b~%T+9(1VAV- X=Ghn&8hӉy83v-Z5Hx)9'&!XJǤ\id>Ji ҅|^Sds,WXmKɝhU7%$91&%&%FFh1J[B\J2M(J-#UbhGu`L ^ny9o@9xU_uK+jY!Թ#>Qb))vHEJ$g#)sWJ*I+2p o0M7]tr91&- o5@ ]zb Oү5}% ^<ݜ6[}ee/VmF `eEp)bG:\(؇p|#|< u  | 0&JS]bxq?H}}Sc~9'vnz5cȅ0&l@Tu{\x_=QPD)־IK!Avވt@f61&: o|{ˆvK ;(%2̟wdީPm!Q?. &`f!u`&( *V}w 2%:lǦJQU<ӿHh-,mB`L #^W8A|$ *WEFWv1JYyG8Bx|1#L 0&`ZG#ZD񭐞И $\ۢo| D8W]?9iYB2Mp#ba_W~㔭X>0b՗`L 0&V[7z pj:(Gf'F~#)+]Y6~`L D+dSVIyHU>rZ)`L 0&W׭*(4_W:`L 0$MIfL 0"81L 0&`lRo֨P hݎݨʘ&3e'` M[ X. (+/̡-Fh O0AGS8w:ut;=:0S`p6[0 |ҥm4d%iU{"Wyf!հJ==Y;0Rrqq35 L gehNfj()5qvY@R(mz3SfxWo6w 0&ixu Nr">.(t3'&`L: nY@QCi #RȀj8 `L 0& h5uecGYL 0&hUrx Y2Vg! -U6,| 0&M^}P$)/DVE%WբM&`L@jx)b͉j;W;&a 0&V[7[}Y@vYug .%5~`L !`YTı} 0&!z5r#aL 0&' YlYӧ;`L X8ݻJM,:ȩz2|^']!8Zv$35`)JcL_bc}OMz. 0&(.ɚWq^=,7tN7>tK:]ׄ '&`#CNG1YL5!:J5^k,n[IM\*^ 0&@=F )x6T׌5vV@CFs(nT]q8gK81&G@3pS=Wq.l8j{jnft51̆ pbL 0&Ǝf1_ȷz[Q3E@ktʉ 0&" 8j`5WcU * 0J\ZьvuNL 0&@]m8nixEQ芌+ 0lx '&`hV ;9xz+.$n"s.^‰ 0&[{+liC|V=UYL9kuy+qbL 0&ڰGbXcŹ潸mL5Ao 8`L h'1j#KY4".tKIENDB`././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/radar.png0000644000000000000000000020305400000000000014124 0ustar00PNG  IHDRdsRGB@IDATx]|^I B   (JQH"|<"(<A E@@)"I5 $zKݛ]B27|u/H: ImA p7:xgh/Q:*٥1<-woN08gG2ڧu |ʕx:\?f3̾֬YC SڊTtyꥮ5eLysf> jp_~) Py0OJd"$˒&Ua%BŒS{ii'1mVC՚5Qݯ(T.m,Ե_+!h꣭Z6s5RvҒ GjwkMhېM~\WnjV=}^zV/[mFƫ/B|lG(tfѡ__Z}uYJs]< uE`zԟR"V5f//ۓ0?/ϬY\g}t}I,iaㆣGݹ0ܶ'gexj ^6m.uU>z>Z'nqeMlɕ&Yi9h,Ri@C?O IM W EIL;>jV?mg_H`63rr|zeXS_:{yӪJR6b3@,ڭ,-Y^'WSLi=iUŽ/^rZj*mRqv"WE[_g~\ޘ9{88f=>Ϋ-f_s]ZJj&\?1 g#W.y^nj6?㶳L2l?rIV=ر[6\.R~6IPJԮ\pl-,,`Ų? Rܭʚ^~j0؏-CFhB>$2<AZbY=Yݕj[U29mR|P?iz!{vM<%2wV/FJs߾>\onkc<sg앟 M*? ~E(%b,bMc2ymgKk0T 3&-Mē+~kblkX1,\߄xHQ@^nk˗+g<חٸl[~0vYsSx+ªfn̷-X}џe63џk0'X6[ʟpKO",KN)ZwP6.,)QB|nfWG|4{<ڤ1jLVpҟ_t kEJnjw&O.TO`0[Se6W%Ⲙ͌6}㋕W.`dYpx{-\I&9''Rs^*;h㙟cZ q^ܒ m?_0E7BGԔp*__^+Y&y:Zv仌_} 7+,zbKjaАߟE9ӧص<ṵ̈̄xY37Nr[\Y w xc%8#*x^f}E]_9:J,e37/qlu'3eLTl@vvk(&n8 =FnU nŭz VD; 'nЏ_ǝ#Wb◩KfmX_/˷dN5ݖV3n^Ӭ5~t?S :cscٹ=_E{7ޒAYֿ v}SO}nP9RtϚϥǾ`Q5tf|UzzME>K3ƺTF3%'NEgew5x齨'} ;J_ Lisj{^zi z՚]=&`T 88w([vLK&{& lb64^afZҿ3xx;اХ4'JW`ۓq?*f xʀ#i9Gn8c?=ZF綝1LHEsqqxxx߫?w "?igl8U&nKYoOB+fd`,It.CiR_[d4abhsґҊb#%-lz?qi.,.IOu?Q-=v 4ѿ!:Q&s*ex”=i z?zӭR~X8zDI B4DLihd?dԻ+y};.G&v/6t?wH  Q$?Lm y-;ݦՄ|GSc.Q "8r}^PhpWF-QKl]EqJtBIBmO>t>ΎG?Nn;ƍĿt(^#ʚs77h*5bnE m᧔<9z^}rU>-gۧK?釀ڢwlĖk#jU5Rvd5zlH<6w_ttkK'@Qu'8zp-==65T6_pd\u ;)^ӠC2Jy}B"T= _Z/6-)◳rrIʑx>ʏFQT.ma.y_BzD)/(U99w1&<GἢϤ|aĀUY [Θs%+ŗ}HNdHIRQkOq2UڒV܏3Nޒ0N.Vd#ҵԭr̻l7aw(SbiXe%JEFXiǎ GH[صkK3k?aC_i+a#J_2H˩ȴ?X;.; Z1&=I:sӠm)5뙇^ 1^צ܈D}tH:M?({0_dĜ׉l2 9ZVW 5x}䏔bMLUuvMK{~׍~W~l &,Ea}C&dEב4a>c6^D*"0/= A-~zDG,|W.-:E`kU/uw1E(ץ}F^duQ@Ĭxx &~+RMKZKxq|):~='@RZ%oyRDZ ٚVH~N 3ɟ3 :e!}ǿ!~^6<:xtcNZ})Cg񈍟.5 pp_n hea9A !,ejşqcZbWgm #A@-6zQq+]>/ۓ(}Ӳ_"z{}T3~%n/)Z~ϲ4$Dú5զL4=2i CYBɴ8Utp*rIV{٨ x(x~ hR1kJUhvS8r2Lk4lmr K (kljFxAӰ+0wS{MfVrJ8S.eJvU|x:%(߸ 1ʥ%zL"u Ƈkt!]gPTTh;1g\ 'XGLxԦJlF /{=0ҧއ10{45G&-ТE-ioAo3fcxѧrㅘ1S<=iߌ+%~?p|{h4aZM q:i^uS\@7{":?|`hs] 1oiCpi| ;ۧK?o y0}!Xf)A?;ۑ(ɏǷ'Pc4lOW̆DG>PP9s^^cPv{L#7'EcZ+3iNqӷip0EtF5{LМbХDxPB2&ak2uOaeٷIg(t#޽"mkHYvG[eMc-+ ^]o_8 r;}VRv#q쳭:`3ggAz4}^-h?;EKm4N)mzhsdq6츘g\~.x-lz=*Xef"?*jSA -Z&)uJIOqϘ2Ѕ[) UPG 9m@}qud"zCn($LKlϒL%s Q@߆)F1eP_w@*٥k(.ڢiȤ2N7V W15oG6t=PwiZݧyiHC}7X4~(ѧ[)L|BbK !˯촹XEsͮ[:=G;b_/tE|RޔOmo7# i Q@ĠIԨ+^}̣l 0ؼ%:yڔپ,Ss쇥.4Vf~m1[^M5a6'Xt2-YhsdG ns[Z$Xʾ5җ/8h_6BY@@ pS!uHfٕɵ8ٲa<38Lhx-0 j)iousZ ׿Ak b+OO3m.2gR Sa%ULaWR+iD@6HB#+gH̭E\w`o%&wjiRAI7^ƊĿ0eY[Θ?O ODdR$aS`&/;T9j-3> !kGLxFFNĘqgWC:m-,8"O&ـX[6a`ʥp2,W+K6aX2}2,@<Ǯ'э@f'0=1<ˬ,YoLL1 h僘4k?t@kk٥5nOWZ!m9c6˘:n_c~ZthMvB6MPݸ4sh5}70}@ q o%_V*W?m&:?V Cӈp:x K1U@4V}Tgt;Y'Y>=p6U4* +Nļ@^=zj9;CCuթ@N!  < OLl0Z&Z"+ ǎמ#3'b?4*ʎzf4RQ-D%2@ҿ:N{qL͠qmk6o_gKtnGLK`Yΰv]o;ň`'T~j=[k}._;qt?!70_X lBOoTچu%̥CWƺ~,T)2O@1$?\۹a 0Z Eza906|{CD O!{S`C|p# #qH`j 2S]ǟ_OF Pp%t7,Q{G8!K1lz5>3g|5=Gbw8rUّqLݴɢ;>8PjȹdB k 'a* cFކ}%<\xŸi 9sjlBUͲW͘1ٰ3f`޺cisp.P1Hg7_dJmT *[?9ɦ^[|ȼf^(-CQ gi8;.×c%b]FXBt'0#A)@֨Л%#ryn,ޭ>X/ It$$E8CuC__ SWXNrjtI,0e+Jez-N62!P$ٝ,T>D}'sL/nʤ/{ǺgKF/Om碱U: T9@k~ V&nD9-$#9YWgVWPŢݵ!C÷6;#Y!|ޗ1ug X9a|ud#FR^"#|>nɜ zFdѳloGe8T~Z2ϼt&EZBqDlmL;xS``ctM!:w &ʛRtG,„8FH ۛuu%%w:x[["+* ;+ {ª>+|,奈WyGC^[f~oi$aLmh>ъ'St[:LÒT7A%_Tm8 O? V,Ⱥd $<>+~cLFRDj`DbDf)PKV2|-BgbWrPHum,Dex%)hB,š=g>ZM",XLmwD}g\f_.1 yA(+TSH.ii?~_Fy&VײjA(R #zy>oOAT>e-hBJc]&vim4 JO:@t,Xos,Jѣ_x@@ ty 3oFYxAO?M bU,LT`y~ʨ, |IJ\i1c&Jj9 U&sdik)DȓⶮNL%LN؝q{nTEd* \M"? +ej[]Wf+ nڷ :siH;m\#94G; U'r !bvdVCf<""Pֳ<" רԱH1$!)ý(@TPs>%xQk1p#8a ,`tWt^Ɗ7K ]=t"mgWЅQݍ]ߪ0}EV&|>%Һ/1Z6 T~mEy{KOtC1kd%:dwFapTE:oqGży@#,>Lugnjf1 ĥqc>dzF@Թ4dFZ`"e&~4r PJ|SB'hٌ-]1~\$R1e@[n,{ !1Vxe#$̖9Q^L'hIEҕモ~#]1( .Kr܄:` b|Vri *+T+m/0 #!;i:]wwJX9VM՝ kLfM)ɑx7(~J{X,]3 KO{֦oaa:Lt'w>q@: r]Pe2Uڪh ՛ݍ)0T2+djƒ]WFwdӱNStWmv];1pq b1h֗1%D| A\;^{QD:}uS^Ju_mł:"(O@քcG!66ϼ ?Ni3%`spM"]=_W~u?K1U-vJ(C#@Y}=߲1j`_1#7~N.z'XFTM/FFuOcꬁ͙?o{Wtx Vds\:4 r =$'v\" P*ZHxj-,?78, Muj/vUk+6~Y#QK0?oeSYNZlJ!Ě3⮚Z;PKs)揄- 0ddZ0x**ʙ2cO: Pڠ ¬n LLB^P(""¬`OYׁZM"`iLØZĴljTJTw `@8dX/(7BO"PIn!4қT;&aMi[Nkч1l^;(S ވV: @" #\<SDOo^L՝NHw%it ~i+;݆-1vz }b |skn#e]wI~Ph rDF# @?ߘJw`js{%V,]JwgU }$D| ,Wq-/WHhmZVqW0Bo6yӲ @6=/" LcmPzG3zt$5EJJ:/?$]8N+g ]DmWz=:g9&'A:*]K=)m'i&}7;m 7g+C[2՝"-gYNSٮO&jU!EU~Lo"^3@nkMzc_|e!r*߿%Q{F-@_,5M13kѾ孨~krfvo*D]:vh['B_eӟz)b׮H̵(,5*]Z6A:n4nov-iO6Oچ`Ƹϋ{C.~ ߛ ). `mp;I=JQl &|-0!>9}T|ҫ + >^B!fjtآe.@*V>‰ïVU6^I6lXd 9} rlNQwMį&Һs;PnOQH;b$aIC >a1 iZ6z)b79 Ϯ?/mMg_?'bk{P2ڜdSї)*2˾23ۍ±X~^["vӊIE x%vRl)iG6K_4f#g$7C7>]䏩Rq6~G/Gn9O)sJ~(rU ;iW=bSYZ¸θbqoԿhR"64]礧9sDBqTޢ͉C eFr,dØDKǓ$RpE S#gӿ6>7%-A6>Yqs3+6jp\yxy )oS p'2)7Bg6z(S+Ek6-[8|48= Ѵ֔ G&o4q3iނ=ZC->4C՜8e2'2QE[?"t0TtwGBIӲ铒qUWʹtvBIVhAƩAuGJ'@O;aVHGfq-~ZL"gpa G !=oW&㕟!`]u⦈\9~|#$,:yb0$\!pGa* AueebS@_ vic--[I#ZcWM~ Ѝ/ kG_<ފXN1Ϭ>?EScѻkCׇoA7lJg,Ðz/cjH# ʑIj.0e=%#o@7aTPo8~?|~H94ϦN#j-{a0#лSDtas{XODZF-@)>Lu͗7!}sy4E~h! ݖZG`j 6}lȭh^'Y( VX&; CF&UAscZk2NB0d]/BPx1O2΅DYi8qкhl)C`jG)}7k?u8x8@Z'Y Y{)V%  VGQL Q໛OjX 0]:hb*Aug!u$N`{{?ު (t(E(/1xZ=l!6vY( F@PU08@@ Tw7Zi ZAvmL q;@`6V* SAuggN˸+W,Ӳa2"s7xynI)s~A Pz|5bJt8QEuS"1k9@AuW֎dLo@V&|NXH ^I6GK.-[ʉ.d=K-)"@>Lu }j5Ѽk[c4wбu0"gĔΥ^iulc`M$Ξ=+ŝORl KgccKMw`$G_]TEDU#9zLYWD#r]N'H ҆IK)]ZܧʀSY LMhe~Ʊi"8eS Ck]HgZ]kTwZ?QͿFO1sT'O9tE)(tl9|;z BQYW|`iV<:%&ݑTweUK{cjecvW\&cLOm;ۑ(ɏǷ'Q|heZ6gظ/baV @+HLmn.уmL m.f9ޔ+/)㱽AZQa;n#"\.sg5-ڤBu@n .6VKugLFRNm:湽PPY-Bu WTw֎S ;۸Z1uNsqͭv #ڭ0蠐0YX"ps9Twqq' 0NLD^@@ ՝ @@ (#ꮌ ;YϷT`yJVØfŲ *H:pٌв.Gxә gW㔃j|Ѭ7p@ulNٻcUضi-}5xf- ՝| E 0-[5/cǦg;atz?ON±"0H7BVn}㝹eqQҐh{*į@Cr9I{qDŽVcmL88 /db_*, މ%coV5AʱvOr1ނ| Gc:ƒ՝|AiLŌ{)A9 QW;YF l\o;;?ιIw6U3]ND̵<\ r) 1l,sXlL9r\;j:t-  h< |t386t>ߣdy -{},<%4j(,NPA"lhaZ!YM+_#F<[Cv~i\.:c;"D P6-[*Mj4?C{Fɐ$ RLlB6SZ IﺍTUJV;tjͿmRiۅXM%I'qCBNhVğ<2J+N(P$X#l֐˘߅_inC:O}71-}SX a؁=}B%Y)Fmn @ j$kR3P7V.I60TKݽG.%$\켆 Z](#lOھi4ź'׌{sH/͓-Y7[SE %m-C߂n;$cGd CY'URfV=S+9<'-;N9rp ҲK)V};4e+HeLØo~XQG}BU;LÒT7AKb]н5k$j lPP~#4 ZnAhU\L ;Ϸ8ZL- 9˘dJf ѰfmӲ9io\'31 yAxNKFj[Ƹ;Au'!BJQfW;%#Ay|}0ԣMl6Fš6M:a;BCybm>a @@ PV]Y@Tw^}mL q;@`6V* SAuggNͼpWvB(>9nIb6)Xk|.q>zq""##M_g(ܡ^QL圽ߙ1?­qI1Oظo~_=߄ t&yd"}k'pܗ*$|a]b⬙؝mTFPYqC}>LuW&wm֭[ӯ:F$))ש|S'}9{ט_нMT[u]Zѱ}4fi첣T"I+_\E:u[ cC_tȜ$?&>ˑ$:`ZwJJ>e){~]A-\߲ MZfFo%7#r=؍ms_OŠGdDtQP<-{ E es{ȅ3pxǟ} RĂϣ6|0|:sΕs4lӛl}}וVTZѲS75,+wHD A!VZ×X3/bYji(P:H}D,8RŽlHrjN|d\j^K|7_J7z|o8bW݅;u=CӒr_LE`5-Wy !YwԤ[=,]8κE2!6BTw @~D[NMѧ_1Zudcncq^nEu'E0\v z2KRZ;ǩY2Ѕ3NW1`} UQ>]n<{ـ |Ӂs^t $Lu%ܠ^FVס a1;pwNO"Ln ӐUv= Ooޗƾq?cN A!VƗkSȆA m);IH;3eIR1V0LݪZ?/_bMj⿿g-sju~;kF?SKnKF+eUUo^bM#YJ)rw/f~邵5RxrE-iLъU`I+:kRw%5#Vk~8 LGgnhX5Z=cMWIZXtUnek]S}X<8d,.qzIhLEl5%ťV9I"z>},`j W 7ļ˪B쒸[KH(.r'غߞ/ۦލcqC&LdCnBڔX3o?3TZHje\,~c0L`v1{c{%TB,jWe [pLTYtzJ)_ yD{ј 1L= |Vn4N>1ĉukɤޠ %$ZS@8%"ܒ%exTs1Ux._=LDƼ xDF%TB,JeRpқC2xSKE ^k5}+8_ԃdk{~B+3Pb`1ɵR93a*>\<}z]! ;ܩ`!FoVL;sMWB拀JEW=,>:3{XGÑ^kјbE#0ٰ:׫݆ҽnƘ:I$9IbGtVXqҀjt4®s1[h 9-.]|9טn=MwN֢ o 8jkTt?]1nٲ?$TB,%˲.+0%IyB: ZKƴp5 ;{0bVmxrvц)}Nc5NÍjwxsڞ)ϩ'mOKqS)oHFUƣ/\ήؖ Xmַ;3 %7e)^[RVcgqZlQw/"dtNq-|ڢpup29|-*4j0I+؂HKQj+xg1yϴ*!l˳-ﰤN3!k-Ӡhc]ٖuHp]\I2'yK4t{NK1{:7lԾ{6:o8s%UB,OE ƴ hCZ041ϧX۵PQ ll‰tHUE@&T.jCˢ(",PfQM2dÃ"bӈAH1uC 4bP3j*LU n("(EE`;^(#[S/gowyvrGsYӳbܥxYgcx̚{j[*fuƢ,x:z#\r> !siH6ԝ#g1N{ !ui~iTE/rN[|_wu]+rWͶ~< l1/YM]18mJز>r Y32V[,,{Dn5s:Q0O/D7gg[V|(._}fg+͜-+鷈#ؽx kKkBs ډM 2?K]5锻'[Q.wՂ?'Ě{>viek,۬wbJ?Ŋ~K iLyާ3:$9?k[9M`p/R7_/$^`|b'8-,[6 ǧ+ٻq rW߆܌mUqg-dQ{G2rW7WNcA*&jLeb^Iux 0鴾"~a/1$siH6+-QA3I@ϡGN<;1[G^CF8r}R< Yg::xxF}w\uP jeqY&}1HD85__"eɷ l*F\ |qDC2N u;wT!'?JDQY]`y ~qNsrF)=s^#΃70i5*pQX|Vmwqt/t8.Z0yM)UB,*+$Ě"֔^{떮%RwU3_trw?u^ŴuY/.J?;slk:)q|tTZmfjU~fYZa]Z]3eWQ'R/۷\RW!Y)u4 і5x;ҷ٪-uDٚ- yȓ1ﶢc۽+]XV))h{I25݂}V^*tB)Eb+=e_%-[Ñ~,W2bRw(܊tE$F紴:S˙%).&8 1 wkʲ9}NBlJ4|Zj2a>&QE@PA@1PE@PD@9$1TiWL#9Uם("ZDlLzo%Ȝ =gzr q-d/6QX;௏Xg-fop`o|H['I$e.#'$g%X΂#X&YN]{w#\M|Yɽqs3p`d`,?&^bJ8{q!Fh|b?x+qX\:B8!RwQR-\Z!>k]Ǯ!mu^0Fuk7$XBYqy`2╙k8w_SP8Iy{GgOU|S&ή‚o^-w.ˇ C>\L3ՅBkb÷Q7g)oTِTUzЍwH1{ O{$_-vč#}çRw՛g"'Y$ba?KQO'mE_G16{l=j|%Rqƫw#7JҮ~rX z\ < HIo~or}z >{/T.jKv\*Z؏`gJT_5H-bP@x1 aMyGƤq۶M( p৛GEv<&yb+nEW< |G rbN"~^aal߭JHu ;Bd"%c"'n7ԌN uڌ`n]F|8=|lA [}z Fy$|Er |&X_bM[: O{>&6FQA[t#W`JԽH u@GRwג@eu9aK\!/pC$ۂ]3M/V~<xw> iY_.Wgq&W⨾NO;u>)RwN_l"|~$N(] ǍŏSV›8-Lh]'wWp8%4C}_{rE% ~pXS0sgn_f; ['67<=(agPLb#O€}SWC'.U.} @_mΣ on_{؉X[+{vz]ې5xkֿԝW.v RTRSj܀"IzgJ ᚲT;fcCn1O-հHb`Eo?"RwT`czp2/6)GG~Y6]ӰgrX dvOJ=+ >hdNl0b_STމ"("Ф]­SE@T.jbz\^jW1<Ҋby"cS=*uE@Pǘ;G-u,K|ưG 3=>+ M2*J|Oo:/JHz~FW* W%v.g=7yxz zTAyN ~xH-X0M_ƂzHݍ}Qv >H_*۫ΙR^7@0),kD!H=x{|9seipBBT,k{Cԝg[3%;l{q˜1՛X>h"+N%\>}3.<-i3V宂a`), [SVmbVZwubAS`2 S^P-3DnSk{ߞm,eCp_< |OkK'AENa`|XYkZslF=Ӯ<G}N/*uE@P3 Rw8n\x <ۊ"("1| ߯1UI@G#lmg' [)8厛,Ժ("(%vQqfƇ`JwHM3WE@PZ.d^:8frzsl>~|,? םGw("!RwU2m+Ǟ=^Ej=>)5"("b0|OlGLZVNUXDKd0uƟjdkE@PE AGWɩ:`o/)mRxj"("FIם|tlG_8G|u.X5#=p:lڦ:nuCPE@!ـRwI۱vvY%uB("(6d m8ؖoańˀum,1R"("|0$[eC! !+M("<1z"(@"RwM ^LPE PXE{P+@"FD,S@"FD, S^wE@PH!'kr]66} <[K`bUة+:%{[#G@"("+. &uWW^p]6^q("(5RwW RwrF2θpTR%++WRE@Poꖺ#Z YՈGEw("(Ddԝx"-#I"wx nIb"("B_L0/ާ# OE@PEpӑzI]8("h$KRwN\7GzV>* isMdTCiPE@P`1ـRwڢl2?םGW=m;N7E@PE6dIu1r.U"U+;j1"("!`Rwe[aSB"sRx!;"(@ 8掮C'hwá"(@H]H0i"E@PE"fJ)f F@ 3b&`!$WLC)$MJ݅Y1\PE@1YRwQ+ [f$whDvI^C)"(-CsWFq[([_^N"ӛVE@PBEl`",xw6:zɝ]N62sKBSE@PZ$d^(EQ+e;E[d9f`wHIA=[$Xzӊ"(@8 $uW!-lxךlS7V[@# PUU˲`S*++p8;R7E@B<^Z'/B%xr:Nv7 oL@֭qo'TI֍n(@"T PnC_ZNǪ8[5,GkV FG uuSXtI H]KQE1pl{خ3rJPf>ΎC^Hihl2m.}?E@P]X#ߧDax#Q=;JoI+pLP9`3;OP(El0M]p;QV!;6lF^ސy"ȩgϞflb厽mVl$t(ф!`RwqغIp 99ΖD4݄#`9~o2&K3k,5F*DlPQ^^w21@VV%}FAA brڴi {_[bŊh߾vbӺ+GV1<{s1a̙1[dV{ fٺ >siF2bI4y)tÆ (..Fbsjds- /|8 Bi6ѭ[7aȑƢ'H(3gcuCaG&-Р(@0t 4 G]cM(dɒZd78v|r{׽MU꾠n("cr]=[xt)"5I($'']xYEK⋽ơ<>RSSѪU+޽Yr-M(@S!`H6]WJ_Ppcpp*^'`+I7iiif,HvjM $-Y%]+@ `H6҇/+&%,OyĐ6t-h,d2pwl"(CXj$azbUf!@Rw!ل՘"~NDf]-tsB6XϠFNh"D3d-uWSr,xp )VXsHFBḭ95"D wŊ|{z!R` '#@5bƌS#A)@##$YJ݉vN7#+7u@$^=?})sK20E  PE^ ,uVbY@NCѻNz]KORE@PZdIݕ ŽoM@l֢ћUE@P!٠RwX YUE@hrj(]7"n:pRÎ;i&/w3oܸQsb~hTJchx ̝;~rA8`{rjLnZL41/75k7Č3o4n0ԩ"I£g$cl9ͼ?H1{}F۶m,{ *{iP"ըRw~- L5 [l}g^]v5/\pZ1 IO^{텋.Ǐ73`ٲe:uq+ ⋸۰k׮F%Yjtx߿?&N}b۶m駟K/o?7mj@4J݅]-zBdeecA+@IDATzjt}~N;ʹ,of\}8#cecҥ1b؊5kWKxꩧpw7mEGl-ɓ1h 3[G6-?}L7XGcLRwYHOB];b"_vbxt73gΔ)?z&';8g]lu't(ogY5lݰ}_n^̇nq_=wosܐ-ig9^ƌW_}Ո<{?d~k3̮N]siœ=CO_6Yu Pm2W\\l/yK/Ň~'yP3JI?1p@7wߵе"$`Rw՛Ǹ0*.7MR@HE_~^u{?u}F>3q]wB.iguIpB3?裏[l5Sԝ$>(֮]: l_lŊ8.IDMBb+y7$_xw@[1Ix@ ,Im0i0a=kor)x .?;89ۂ ue?nF??x.2oE@U?ϵ~^ĚzZ&qZGݚY^mYW.~ew-c0В iY҅j 1[>W j؄:wtÚ85qUUUfy]ўu.LV^8!LKlw\~~%cƖ;Nܜw߹dْK^8 '%%ŒCA#].61Yual|gx2c}GZ/JN=8%cC)#W>Njq2K>t|#Y"YNPYCYLwv<|:Ю;3׋%-Z ҥK4ak^w_@+cL>ʏVl11VqM7y9&,/acl$UFۙ-q5jr9l=znH TTTvJR+)e_pmf=˜lB[= BkZF1zX6qu `Iݵ=B_=>ZJBΖ;1z/zKڱk/8.&ځxLcgy晩?|Y{z3vϲ3-$Oz9TZؙ7Y%Kw)eƅ{m;un6®vvs -q !zN9Nc+Wˌ#ӵ"u^EBV;z#;}-x30x\LP2#qj'ql L9.Jc9DZD<['rY`i5Ĺuyv VldٝLétV%[,]ĞKMM5s39W/ʲ?S# 1ewӻͮ[צ3 { ~TqW~\Y|[ϡC 1vUӳ3=SNٰfm\LYЪJœ+''ߪʬMt D@H֒.QKp,b]jpzxq4L?dK|[4fIi(/K^|y1[>%)'vx=?`+KN9ӽ#Szk-}\G%@|8:%ھ}Jkr C0Bv"X7mlǑen$^ZϾSxI(e9kȑrǛ)|tyCwZb@dSx$Y⑘++:9 \"`#viZt,,p:,]cfk`SC؂w 4ܡIak^$.R.OCzfimАz2kcʢ-zucIt]ZQra,5_IBkkE^EKJ76

&jP?,X;@pԽrr,dVu6q 0~sfH[r|*7W7&`.xrL"H= lt֗JeDR'ՅHOO()e[6};%#>g~p M:V`(.b뚥Xzb{SE@q*P\Rn*\)ag@UI!vfέQ()`amY("(7W-\# Gl%8-/DS֐![-"dffOKKC۶u<E0$;xǭͿa,۶{~ճ I:Kø4?.F2p>֭[B/O4c=LGV~^ձn$ʠy("ȜgP3&(@qez|wꍓTcڹmFdl-8.֬>AQ@YY͛Ŷ@HN(j6l:tgxʕ={6RSSwn\0z$ME@Pꅀxۯݙ= m_݇3z hc:#gGi5(LIlT9/ʖ 'N:-I>cdgg^hv-ҥKyAE@P!`}L߹PXm11jg8h.Iظ)VzP*CWeonn. zG"([׭[7Z:ڭknýW@ 3QڅLKLJG^Ee e%K@{dkG'$@TWWK];v\@k`;4f9H/6-_#䓓=W믿_}ڴ+g3g޷999K5=N1]+@t".^< 1GCBP}]sT930k,C@FMk+%._فhZp֭ѿ5rfdd4I*p^PE PثF#]wuOq뭷bM+{Yg.[n kO=W ͷ`[\-}׌KV7>elal2НhΝ}tOy>swwp)5ƺMWyT.櫸y~/X?-[??]t`P6֢5kٵLb3Ë/Xxڴi-gOA"چWsQRmfE!`d뒺#"UE؜6{CƱ7iQ77ݗN+ ^31ydV՟i۔lّPI8BniN.h<ƅ|̘1ôD=H6l0˴`3f̘@Yh"D %15oRw̟C{>&tmzQw*(5Ye./tuK.tعs';8}[)-{oڜ/\yxG>IF*򣇺v_(5VbTMj1am)޳5J򰡢-% }BIV=_]R9%ƍwߙDK!ӯ_?eZ7:V0߲"m4Х-u#8T;߱ hhP %XF#8.1h0HtoGL닔+щ@SY8_R ;d]λRE$X5rjnꙆZlUݫKf?`yşoSڱcGC_|5:"и;~I55XB nXp$zGE{ |h̴fN/XN35(@l `H6ԝ[wXZ `VL@=ЂwIK.5$H$\Z{;l̪M:>|xc^NV&B pTaGQ9vٶ:Kj"e&X*珒T}[`Ɩ$[\hPD6믿qw-IVԍH$ZѲAP7uHţz|"]~{x8h4ַZA0l߾ݴr飘m9tkeNh?:OE˖E@h8VgZzv`K!% zHߒ糧Sx|$@U& [mjHHl5$bnSv讑t "9v ORw(T /r95"MMZ/Υ/2.K%tQQr!qeZ7th3QK`#;Bc7wNY`qZr4^N4gd Op;G|5ӑ-wY^ڻssg-{{[&{PS:tHC9~2wT~J*'uHY(+v~'e.s3׊8w@[b LR+㨾#T&\hYJ=oh&XHVh\yڤkO;6R\:8餓 d TT1dj>cZϗ^zbۇu(@P}p]Ǚi ~nX?cx!CK!>m۶-Zt=Yu]` xŻݯqV.e.2;kvGt2A/X$Z98 O ܫ }lew?˗#;;~'O ##hҵvE E $ϑ;JL⮸Ucewص [uTc 74$:g}]TWWcҤI3/P;vW|t`?n8sή]H74YO:GuTT5]nLb W =m{sjV-Ǥ駟7>YqPTT~~K'N4ǎk#nL7E tD!MӕLCR*>lyEQݏ _VVz5\N?ydcZ_r34ұ>ǙZ.|f+->~ Xa3hф4SK.5ncpE"G  SPP`ZĹf@ՠ(C@F[54W^Т~3nGT(0VL?$p۷nۍA %o"8N̅\1?xʏ'C=Ԍ^Y ͛7{e.O>7A~+W?~ixCƉuTT<\STp,6];V &2!|ޯ -`)ؾqɯO0m:wI%zIX@[鲭"˒ S*"?sC]hݥߩ;#WvXf lr69@ dJQAe"}.|"0tTW0t7y&|IrL/˘8N^lV+?T7Q].-MT"?jYW VI7ke,Zj AWUTʪܖ4ENdBbȓHKAhG!l&qU_nr.ܹsI3چ|xr M%mz{%N[1;#qy +K~%׵>de!aCz2~`OtI#Gx3ݦ;PXVν0o$; saVd%jUNWtKf8∰=i,$M>,iKpܦHMlI!XpOIσLcd_w>dʇ8&(مOC~?={4{͹Y!`IoHzZtl]ظnڷ+W-իޖ-[0rHeA; 뇷 'a3z SSc*?o>zuO(N%SYBw!ztGXhWWT*%q“X 1:d1Sca2CtGBsh.;[|Ϲt瑁 FW]u~@ A;+~<g߇[Z*U3rȰ.$v-5DJ-I5&S!6@VHJIFVj-(rI +Tksqxiɣ{C֮뀬* K.7YNeB1x);/@Oм#%! NLfXfM]|t;R(G&9$K+1|b6S=썘ԇ&\>Hi54;8mgC@9:Y`c}C$ 6~Rf~6k#zJ,VT{LV)jNqӣ&Mt0!]r Ix\Lldv^̗`lV,!˼"טF&UWsb-naoqJHʹ0=h 󘰤l1)mgTZΖlX7w茮Ï`$L$Fyo@yf߸si; vp[ow3buh*լ?-65bC7RdmQᔎ$ks^ 6~uwS/6)MWpc{X^hN ɱ% r;NؒpϢ=ik0ǀ.M:r\v:.kk']OuNס#Tn|OꃊЯ) x,C㱍AkL<6NHjX TW99$ik:nJcsPidT` Iűs^WJ!ޞ JzN4"$IEi*uAޭ=:Х矐[W ss&Yfp(giA[x,E ]nDݥ{&҂XTD!XF]F9A|i>'q)A naBTV d9.V dz hPA f= kvb[q)^!>K%b*e[# 9M!R-XPUNBTsr ɕT-[ Y9}^9Xbw@٢e~eyTK-8P"[Cwgؙ?Zu&%Zh"h_A-kJCG&PX9ߎV$6a & BS:eIDGIBzS({e~Dya6nwjcLߡSUDSٰdG#۶d2s_9MG׶ɑX-X{텟D^&ޘrsEr6T}罒M m0.cωl=3ᶋrcs2]pAsl $\g3l䞌|co?&Nµ\91qh#6yx+쵙+vҸLs8n{DbP Pe̙jrM( DN;PN!$7\zz* <[ld_Xvj&Wl1))5s&X@y6Li8k'R+M(dϱaZ:hiC$/`kX&y-fYC$a3G֌wuZ&׾yH1W垽vN$/=wniΩ;pH.T$G;wlIQ/=ޥ%5%g}|Lvۘ8R^pDݎmtMߌRJ+%R>p)}9Q񺈺Acp;\XҧË&/SoK]/磒\$dg/t\;uΝҰ,\p8쳍N&w얲%lO)yxIFd/NsZ@37rsG&$ʏsvxm~oL5hO1]3[~TdY> 9/h!i2ѡM+d.C\csgJŜ~ᬳ23_}X}68Gܖz%N…-q(v1U2m+Ǟ=.EI3Dc%Yv/;lf/"iJ6h`1;wyHVbfw\tIL 9HfLe2k:jt5 }g;K`Ų7?@\wGLs۷>$ٳg{[ݏ@j8Y)"-aY"{,Yb[/C=wiOnLqv=fгq9|\r%8:L ONE֩hU~+E|IyCl1N5y"qUb}g<~̓Ve;+eW佇BVyXbJNl?ބ#VaC݌v+s:bK&9Hkc'cP2gIdA7s|I7DBek)^z)Sp={$7񒶦r;NVsΑN=|j,~Z 76lXj&B`%@*gy&hĞ#~d1 wȑƀdž  ᲞInɦ;h oUKP֭[jbC,:*xXL Ya\zԝC?8v'XXy3v`EV9oHCZzȌєx3`ks6r&Y<+Hm]W1Szv5.㜖|,.nOFfEQkV<mK9 USv{v5%$KΔ+Uz,IVek꧹m7cu*%iFeK㣏>2C>./Hr opW`rb̏-cuk`)uw {FvT#P_Wcmbz\ʪO*+L鎡!9n(錥aS<7S;#qT;$lr~8 Wkkz#kW?T b<](.[M癿5RsU HLJDtyI'mѷWss ާ((i%y Q|bVb-夫x$5勔݈ WCCSO6۵#$^vW^y!Y'럁yc}݆`)x Gm]\,B/_*1j,K$Dz |S)ƚ(bg#D7lBbQSdI"(bl\/yϷS89nfI:w"gW_.U:1>h'=mIyJE':hVvʪϝ}dpC}TrɴR+_fYZ?MR,34K맡 sgye{gc`ї=;},MR5fH7E\UW,*J^!U{slTV6U4NT."H6s[?;wl nHgskTw]ïGz]`|6kfu]2o޼6ȍ7:h\~ 2 |;qB^ EX4&[o5u=֒[ʟWJ <]sf! `נ`X4P JAc~)!(ԄA1ǒzǕS<\5$ZCȖ]=%n|3quDxZL,)9I^]^,DZ̗#˒Ǟ}U6KxAU4[@k$PEI+4!dN&JJۥTɶH\ހL%4INJDCTɐ U`WT6+d Q5P B{ʪrn *5;-HިD:uo> jABWEʯM;UYFfip7@&!ͬT||UK'LIS$h{2 7ToxhS)~Wٱ l2C쌅nA~mDo}"ZqUT-%Jd@PI\!cݪ$̫iIW$Rt}n]c -){J%@vIR:7 5PxʟFKg]<Ư^5RZ9&ؖ-~5c5gjnIGwM(CrbϱfJiDDz,sZ }LYo.`8q;2 2*_:${]3p?joFbB\~Fu/|K .FC!>UKzO mWyurJUo#dN>S>49bҼ54= R/ERy<+F̈A Oqՠ)Yҳ$Ikh$C*JzHjN}VV:y u\PTU++ᦨZ#Vњk5XFU~P R*Tjc? +6^_drU1jD%Wִ2eyQ#p_FAHHqҜX1ԪdwU<'^8_Ɵ2[m23FLb ,GL5\n)O=yk%̎F2Y/f,`ҕBwysnUf][I3Hk8{JGjdO$ g^t [+~r1:2 q6&%*k:Ir!UU[%cPgj\bVS-BMHT4iHP1^*G$%EۥdVV 3]#Gk>eTFT^zh]TTWhNr9dBL?I^B5^W@XҲe&+i Aof(G .?M5 Oleu$YseWKkLRu됰Z)~'L1ܬY:j3P^ZU(K?"{JlHiV V%[Jn~@Ď|s0I΄9lO\%*yؤ{/{4R“NtY%,#83GLy1?„j+1ī$:0uTP)vNFIPke]P Ubܫ6 \BX buVCz,s,7daJE`w6I̪jOYrlޠqJ 67=Pӟdl3pro j"+Ov=C/~ay%,Q_>9KM"mj\9ʝuxH{diZ!pR-dѻ䕕ԝE_BVT*y@*zI*B !6*0َB/H}F({dIS•=Km!l Z!kݧfF )u3eR9EK&|V kN<;wqWV 6`ċmmjO~h)kmƌ8NњD7Ǐ9Ť-ZԪI46eFCBŗ2?巿- +W5pب^gq 咏뮴Ku>>YW_N8!0ޓL_'O 9jj<4'4]9;"RX'k/1TW]uyN@|^؉>TLnKj7"Sk">N#o1c#x j@0X``{n?f_^[|Yת댺h(E/JJ\?XWj\tTzL*c 0$NDo= kf Tdc{SsdT!f̝:X^ZI^xoJi\j4lEIGӏ~RZxVm<Vr5f|;Gb\MZ QP4_ގJ՞8K%퐜}mgc;kouG{$=xsK,@_lGl|lz$x ȴrwoJ$D#Hl*' elOaƄ\u" ,dQcvM[*Glc-H,*spGAlK_+;%[)%])ݱ~FR%"ڗh!ή+9*Cw ],ek`|޻,  ]q4[\TU>>G^N>\Θ1cfak?2뼸n!Y$@TURjި!u}W['j[8sc/5҇mK֡u0]^G¯677 o{JKdyۼ M<5\6g_E{Һ!(RH4ž]jQCK.: qmm`q!y ɒnew=JJF#e>Ըp %;3.WYdFN-s䐥ˋ5RKa2H[ErWj.~}ZW}ϴLD^Z%&3⦒!| 5Fw6mk5C[mow1fڨo JAC[Z&Vg:3κpMW#z:o=!HukΛBo}CdʒG~!ӛkIrWNnm)p={ ;ۏCjiy_ N Q< a Zϙ?b;$(+#kW>HMv|Tż[:u\{C% ʶr}eBNܬ)ڲ],\9ᎪS6`ut/ˮ\fmm[RbZ3l.TJ1Dmmzg»=޷wĴcn2d̨c)QEV7Hjh;K Y7 O7!:Lu+;7TH HehHWXXÿ5x qͩ3%EUzJ\vl5zP}ז]ͧ@n>Øzfjyhl YU/ҝ)`O1x ;8<I/uYVڳ^(bO_0ƿ:]SҷzG}iz]_%k{])~P#)6$qӊt}<2yk4v-#2'5_k{ymǼh݇{xG mvo`z{M-??XXgL"r^r%k䰭m$ڥ;P.̛UB%N>=QH]Qy֯:F dRI6ٓ֔>.mr{4nh[yi2 fkt=vj*Ŏ4ɢ&&,ftV9逸)w#@H}l޲^2G:kl,/RɓO>)_%d!ӥMksJ)?9y=BWv2RkD ®'sh"p´imm)Ӥ*bcѓ8e -)|M9sV[xC0%a Рur mb$?<`R.B헿JE^Y}k_3S3~]wɑGJg6g!٫9?@\HgeixIg5/ ,bS-[f{oݤkCF$B߹ҿ@]z,aF$$P)T%L۔ܼL;s,\7Z >I{ l_9绖96 ?ٓEn*aQ]~yМwy9ebB)ƂRlӠlMC4xFM~3B{]tvO<\-;#=gG5FrĹHNN@yG*eҝr)[5![;Oڐ soL2Eۺj^)$4EsQ>Din0_6^zh-Z$~IP]W$3=7pb2![rAKZ/>me11mk*nPםFݐ 2쐑dY]vyX~S+tIIƶ&ʘ1cAkdz3zDD*3R GMA/kFd㣏>[nE:Oj\HVd.2y뭷"QC_ Z\^ &fm#[EoDf,ohK^{QyS#loaTwX@mcm+F_`Tv ֆ*s@yY` 6wC!dJug׼,oLrvWî u6 x0u*1CYq$54${+G6'4Kd/Ѥhk涖=Ke-IZ #>Kђ3}-y"j&gQgaW_5Plko9vw anf _X`yQCa%|#1: Bek޼yfq~ac;#n;ky & 3tg{8cb9=wc: T0J|5'W[UsHGMλ(3Gn51j6,hLקZ3ؼqظx멊K &"}ܣ=5^ÂO%K V~'1º0^X{c+0ċ1 ]埇wMuI5R)gȨtH8Sx0Ñ;Nc7 mn-&Z,5Ȓv5u#j?F\19}zQ6Ȕ^(E3ZP"IbtUŧC\~AՂ8.[7 ڎg!_TjC >:HuV'm](IgZw;X|Fa:WaXpQ̪/RA#%Z,{*lVk5J|dÁ(  %%J"irLu}9>f|v_my5;u{ġSZuOٹ]WZe45Fí >Vޓ&M2\aC >|}Z׳΅xU#*~|< 5`,u*rv{4𹯉$WjRj5I4]_@"auF9ه~"5oKٴ]C+:o\O2U"n.RD@Z;0m𫏏IZM/IMudo59Y JU!k9jU:UmXQ+%B* diVI6CRJrg_(Ņ`5WR2o^JV9sty<&ݿ@o"䥺.ꮦV$?Mkߐ׊!WK2b7t$Z 2Be>}YwD bIK#FEZwB\:hl/<G5Fh tl%[#*:ֈɵ!PC!&+ZɵlJ-Ǎ%5UAʨQL.^T„Dō*lT(bϚ5N1|bΤ[z=jysGKB=(kȾMar5J$*],7?,w^|D:3+ &Z?x@*dKD"Cxy2gmoȚ/O &'e@/Giq(J6,lH tVrb:4D$M@}ɱN5sc8 bRB)dWÓ{xN{c3e,rjbYR63_N;HIq2[3k?̻@O_HJ6md2 }YvH~岶`Yf,SuCeV%\B4Z0Mjܤ` BJpue;NDq:U&Lb֌Q"`T2^H~~ @ۆ`̭5{!IM)SǬ|SȒ*D=!}vϕ Z"DM2u L!)-HZ 2HXk6#3UTRq">c`Ԅ+FEXk:))eȉrqst}uYo&W]=r?,r!8"2UEx3FlɃG~!/r64I.ޙQ[&un?#D It*Yd8y ٵ{VPU*q&HC_J(5l".rf)QsԄ䈙'wƷ.FH=AvuQ%?ܽ;&:HuW!G?%5%UBNAiR}wϠқDlj[Ϻ@ZΕwEv$) (K#FNapM]P WKia!׉ӦːFZ4h B{wJhuC!HYnmXn>)꒠%C[}@o%=6 bdKg}FzS>ܨn0';]tUHJzr1+h5 q$+!*q#bչvmb4]no}cvMܵj!EH$͓yc䝏VD4JT 'v $Z0 ~S%%%`O9#}v8HC;D BHU!#mzM6nX.siJ-ikNL"Nոp!}}ťi~(0ݕX-HciZ-)Rϖi6\!W^{ԘK.N;q{jn\@@rGyDN"YS Zp >1 D(iCpR·j=Abl#XAH~+[s!0k5%;d"k2i0!r- {ʚmR%'LJ ٫ZyG$ES ٬\R/^I BYTת^)|!yۮ;Mm۶ r/G$bOywߍptphEOh$Ȝ\''}F*+V0yPJ馛"${=șg)i9[ef` La;<@ ߵk!]t`i; B~I;i 1ѣG˸qd-=͛31/2&&`ƍ (=eL!?¼ϗKM.|X1?ړk1 b,<6qv]f<&.jY${キ!IBlhǎLDobrK\w!]ܮXp{{rh1%[.Xv٘u ?dbkrٲemv@PçJY4IIz9^y\2Tc7m[[ya\ɔ͇ܞC!p8"le_R>Ě(O &u,w]iBˣ/w$w!Ї |"ilh2 Ϯv8=lPjun;oeQM,&R|L~!~vj>ܘ=)vЋ68Eq8݌m?'eoMT젼4!tRu,`Su9bG5]KC!;ID<21Udzeo@H SKFB E\K@o"=c.InVԥD$Y^7pS ɆAdO'_:PDvVJq[pƝ)"C)b<c}sϕK :m4KK_I@}tt$K%s( cn*-+Mr&ٴMy{D9MyUh^4GF+:i7@~Zs>:G{0B!#$d vOql5sJQEw-/ =8 Y0'OwJC"Z;~_nfƴ r#JUUh6;Itv m KrOsʥ6)Ueƒ wOC!VT]\!7UK9aԤ|URS%*Ҡ2+C!pt,IDATj`Ǭt IP-2]q8C v\رr-C B;Lw+C!з8S[!JQB 0}i Si#н#6o^^^hfMTwvq$F@/S[cel/(q2$#Neԩ]ȍAaved inYvm@J ,?z8 9 KiO1~M$''ôul:{aY0mΞqvOIKuwՀJR-||i'{qq[ 2 ggfp8>l8՝:K6Hu'>gd[w'zC!p8b@ɶNH+E"uQk18C_#0_#n!p8]Dl[Zɭɶ;p8}h7RTY/U53$HB)%ٙ) 8C!Ќ@iRyEz,ByKggs;C!p@S>/ ~e=nGycC!p8-0՝Tu.?{ C!pĂqS2kp8>c'pZn!p8ӦMMoN*V[I3.2H#3#aڽߏô{d4ô{wT\\w#:C! fMTw۱}VIbj{;C!p83Jw~@H HCC̛i3lC!1J$sa#$KͣJ߿Vi'xt!p8%R݅$$IT_"׏!sp80km I]u)` "r,5XXƮ8C"ШMu6$P[I-Y7M. MTu"ٺ -C7K;8C"u׭Z7"'[1EB5X#ܠ&#YC!$-|g+ZN5.e^,r:ձ<6叴aO-[gyFh,QLA)P8+Wb„ F,}*R9K+WZvVq:7~m=yWd2:괶V\=~48~糊Phھ-Q}ӱV?Ge2&4VҮ/-Ѣ1 *wjs>_\ݟ#.>郠d#_s›_QW/)RrV$\m)) Qhc~~>HKKGÆ dX]*3p:Pgڊ݉"mKﵺPх@;O,yo .T,?w3"D.g˵X6C];&-mc!9,z.9؈|YѸ2£% GRsl@Mn١ۙ!5=~_ȌO~asθ0(LZ2֓/R=Yze$C㊂b{Aʒqu pqUwo~) qy}*SY}HOcW+eM-8<<ҟ 6y#Yr̲+lR_'je[)HvS)gx|%> YUP7ե߱7of}Ju(A;U+eB~q45Ѿ =C[pJ@v9rb.I'Nte/!VdZSsLḍc 2[Z䊬t|h2B vo4˅. ˴l٫Cdpt>K92른MJ(g_yX)cGsT.XmfHD\ZҎړ)CO[֧cٿ,Ӌ,i9:-ȶ'PLʩ cG4ר b&k*WXAʒcc cY&cٖb (?F/EjzNɴ* /!6Vʐm) &ϧCd{S7e bu&T_KV KԥʉD@QqHTWg%!JQ̣2W@[_[/ߌ$xMЋ TW۟X˅Tr)Vg9,8.Wʁꏣrm[{eU[qAה,jv>i#ZJ/CGjzud_2zzc\Q[3/^>5 Bܔqj}dZ2_r:Vɴ.XۿX֓1+A\qYXVeL iW_SSe22.+)KdZTK6d+\,Lcvx;S"H:L>7Z ݂@Ϟ=BOV 0& |.͛iS:y Fƹw^\|5җtLieꓞ|HYɆ"C '7T+1&@lj?@6Q 7Tݵ7L/ڽL/D᭸o'4x}KU_ 3L' .v zL#p>CۇCp'p{û0XGOmp\aݚ´R #CUPk<-.>f&fWLɬLJ*}F6>4K0wdZG.V X iFx~ PX[W'KV=\"~q }&Uy<+E&,^4 M;UX2m0"ǯǨFQۚŏI>$}t7fa(~H]E^REy!=fY|fa_M3{a,'5L@$@C@z#>r~-xpSX-U[Jms!vV`)9%|GSǝm]SEЬ>DSŌيУ:>b_> iY`j}9R]0 +jE@$Ό•pl M'S8-RN՝ߝZ8Q7fb-K`~ib~Bp &P 7⋺E8%DMѤ`Gh>Jg?N<2De_/qNM1z`!^{EAY9Zi%ݰx> ߴn [wCc7ތΝnD0)5dh=FV%iN9*u V*ד?uiq0nHOC\?'W>0lX_~-Ɖ6s?l 2A){mruqp41aE83"4k`};Odż19.1۷ؔհx>& L &Y% Zx#kt_skxl޳|JEZ;[us!H>ѫBF֖3?KL .<^x.צ0dU9M958liXRB7G0㲔*t CH%ӸnqނWX{TBiY1|h ק ƍ;@ORikNNiY 0L,+ԡ>\14Eԩ!M[!2}E{*N_XvHNY| Wޏ{eaSI;q1SIc&Po 6$w>껬|!I1&P/YGP-}RK188tGf43uGg05%''l/_%=I(7LITs2'AXnNSfjJ5i5i,>°Yu@NeȺ'4ؽ{7F'v~a ;Ss%t iV]_ZS_>eٱG*TjTٌm_.Z%L0=Y'`hOX`9xtb:?F7UMpӋ'܄`LtH56ew}.SNcɩ$IA-I]jXIw _@╍c0fb$F|t)2Sw8cM0dXvó/V(A6}N_q1g.wqIb7ab|bABvh,e.ߘ#S/߷NS*'tbieu7y[^22Pb{÷$QQQ8fWo`%`m5ݜ:f5 <K|Т@fg.l7-n² -nls@~SYՔ#GK)=\tGa;yCе vрq0Q8W/ڷUt +ʌYuڏ qeInžPT|)q0F U^Ѥ׋QX43"LXL_i ZpݻpuIQwS/ O^ o4M)W 4dJ9:m>hZ'Lc'|ֶb=/0~0_Cp-T_1BQT ƝA>\f|ў]U5.ahqdxL 0&@蚙Ah/L 0&'vYnSgNũc/Y)saL 0& cn؍Q,\;]u"9L0Tn[`/Om$ X pf# ??bcՂ~H47nõ:pUvsa̚.MS+gg9nHa `J#?Wh0:\aX^.tY8'N. =ow>Yp_ k!rcUT”8B٘;5y=/qmU+V?\uۊ׾vjqgG4#nYw= ȅ%dbC3gUQӡ`M[toyfm:`B;?a޼yxo;߄ݎlT]|rq-ƹ0l{;N]+uG+ۺ4OaEƢk`׋/b}`r)qNZ:sȅa1㕹xmjs?,՟u", } 9'E9Ӯj+FԬ?zz2&W ƹj%\}?=]q&X{0T$#so2:\.um Ρކyfc KP|q aL=3%wQ6 noػkδW]IeqN8\teW-L2]' ;;E op%\\;pUsuO6 ρ Ca3`. ) F$st VSq&N΁7LbRIZ25@bW]5@]9E{$Y p+ 2"XZԭ.+`5N8r 0&3vgYnSgNũc/Y)saL 0&T hR(FzB,bSxsĜQ3gH2ݞta6gLL.ZOIx&TQU:7ss6[b%XxRxG9g35ҟwm^aB^]ХK ROG);TRw={^p!VR_@b ,3nɥ2SgG`16ө?`K2ʜ/Vןq\߭0NsZ&Dc-p$e!p+ ]2S+'N0RX}cmҦ9U_GjgaW`ut,Q^2v7f F4uӡeX$;10 R\C @. 'Y\2S;8 4)ظ;6 \ }Q]O']WҲj6&3VwSl*r&mow86̝;o樕[}b]v+o!ᄸ Cf8 k CPQ:pJ[dO箺b*rUzaBT*M" 5:EXly& BFUm\2Sxz4!,ૼS5 x ޘIr^5 8rVMyQ4>,^{ ;hviP<p}aƇ> AK#ȅ!3>_P2y95E ̈Fإ\ڙ; ѹW/%]S~{E#:#tbM~D9p$`Ȱڢis? 9ulƥm%>r2rϜ,>4k)ƙ];a_\`bgeltS\2S]r\`Xr2 )ɋG.Bߋi؅!3 SnS? T?ΣbL 0&|6LY"`L x0v'YnSgNũc/Y)saL 0& c-IOBLB[׺ҩKvk/z捽Hqey+[ o͞cusM8\ duYi/×ʯV2鑺rg=-vonuéK]+`H:6nL[R5"apӋwM7`>8~fہW߃[V `[I<:,桨l䉝8]g.E3 @~P6Mǝ= Y°*{ނ}H&~ ? &qMHODv7KPFgܞ3=3Wu+Muݟ(jCYvqG`\X{5=.tm%=avXhF#/|"!?9ܴ'vqw=#EC\ػ֗c+s0FX?[V)&a ּш¹1vVcG0n_KѲ"bv=QE~0hX|< 1;+

QZ8 }7'!.?)hp-ы1$r .DҺo*G.\mw&w.B?sIA(8sY"'z*/ǥ|EX.˄+C+59fA|+3ӕ5!aȈǙ q'nEjs d&9Hvq㊏zbq."ݙ!Y}`uܩYw|߆n@ia|@xϡ8N)qŧnD 2v}Czh:+@?hٺq#DVCClc[fdn9`gh\P+>!U,7M^*nǞ/=~kwϐHJ;(W]D+;#t q aWrřOW|6Y{0dX22/~<i(i&98sG_׵jƔ8\0;.#]T:cq=C(3q2~9 <;֭ TvqV[+>fZ%ܨ~0lXᛋP+G`N!n㜂0&`qn~%8͑cpԩ8a̔:%::eq?7, 0& *u:"$* qm.q{c uttrKN%aL[&ǔcRY0hX:W^yEb tw/[=XU^xカY?LUpGyG"qE|cn4r*RVbivCEN@11HnL,8, > .Dv7лѿL;@lW!wﳄ8?R۸;m\^2vvրӰ`: Iݸ$ |캇&6y;?۲pBr@S1 ͘Y g?I/Af fZ;.L߱Zmz[z#> v%/ǼϏ_~^ۃmWت)\a#F.4) (I;xkؕ5ٲR^]? b۵b??Ğ QȧXq Æ/|Oz-]@>s=sX+zdT'U_zn8d: ocE}iF#7dJcv~wtT`<_MiLqg0lX32A|v EyfyZUb W|b57[`PRhLqZCaEXN qÕ`LC 3bQ?!pe!&_놇`: ޱ6Bf. hY j'\q8`H1^J|2ߌ~4/3`L 0dXM l )SDA$K&`Ha-=E&; }[ݏđz 42`L 0=ޱ+l~hlۦ DItgL 0&a #ձx??D#(JJ0d<\&` VSv2G?E㋐F(B¹8d&`Gakkǽ} fs{,0`L 0G VSq ؞:bL 0&m|:`L 8s>,7G5t:1Sf|Η9ܰD&`zǚz(ai);0y0;:`L 0r f!VFQ#[Z{hghrr`L 0zIYٮUӰEpPeq  0&@U 2joQ'p]_{g^nֆ`L 0 C;,DMH(5pX,{k 0&wyᗈ76+D8Z9`Lc 2޹bYX4:FIۄ{E@xL 0&l 2x';EY9|WB 7h,[|`L 3%r7cڜxCgL 0&%`Ȱws|lUx5Ag%-P>fL 0&`Ȱ3qt|}akғ!+&`L@CaUژQ;wԨ! "Ϝ0ԶeZ"?fgLDl6;)^}m*!Ǹ-XڦMLO2Sp3g 'G<`I&U[Q˗/_l:cL 0&P#4i;v8F۸9e `L x ed s +{bmnhQgOadL 0zL@m+m[ %o-}[\V6٨,SL 0&<u{{(hRضl`{؄)t `L 0&it wDwt Ga$簧ЄA;MOaڑ`L 0&($#(@jqn&E^pcd p>9Yk*yLyL 0&tX-L4VUdzݗ(x G疻X3٤ʤ&`Ja-OԶ#"Q<\8(&`D@߰#%%iy# )H/ m0s Bm޷ ;׌ Zs`L 0&t kGk i;G Cl6 gpup.v}.]w'cU90&hME -S%ш(DRb#~cNKD4@B=$q`Lc Sb*FKqґZUtPq6`L xG9QXP6Qq:I 3S>uJCa;qq u ̛7GQcܹ\6sɓ>|{yB''%K?~P\dQ\r ^|E5 pWb۶m4h5d Yf"wjU[cA駟V s= `߾}6l/^;=oJw^-**Œ3Ąď0m4|ܹ3ߏo\s O7d`cZpmnT믿{8pbLu)SN;ŝɈX7tUt߾}q뭷bС曕͛7:Q \=$Xm\`ozRqV DF0ȰѝwXr%|M[B_}&N`)=NU,<;Fᢋ.TGcƌQ1Zٳ\^bbRG9b+B|vܩ9qF7b8''GC%6ݵ^@=;܇~;?U ttLVr7okx[e](T?MxG{~yϛf%dǍg9seOV{#/0|L:ڵûヒ+wׯW |C … a%JWKJJаaCQ.](2~}QOo_~OPȸ[N Xt6ŇV6ݻ+۴ic?ydJ?￯JFOu@ %Ǐ?}yUmKUNa޸yO=a2r?jkwt 1w毿Le &(uTgŝyfql:Vc)QQQJKV)k={yRO[QwQ;Q%_~QI@#}a䕺$h?6nٜkm&ĕd%'@ 8{Y zHAά֙4z|e{?-Ri&0;v,V^z)1=&LwuMnA9@hV3^nqweÝwisUW)"7oeuL Bm +/ەp3d(e7d$hRٳJDÅ/ʣ\q d1O?L9tuO@IDATĝFh',vzxʣH2h@zruPW(zd, 4_5k{[ ~27"07&kX-cRXuALZ:i$Yd\QН6 LJ=K;ѬW2:oW_U-ǣTW ,߅Y0ˣ(YFSbL+|#-!]rMD$2{7+(dcW󙀻нcU%mmN0D6BI6|tu}_]|3wuk'@]#СCYʲZ2\у>]*)҆4MxU,6X]Zj# D$44TY+Kwȕy SO=DZs-T +ݩҲ13GѳgO%K/)z^ZcLW[.g-Ss N[g-vHyr8 j; aad8ݦBϟ7fazfqFlԞ={|vlg2&PE>>>ݻw[s3#;^aI&UX˗/w8JKKCzz:^xO?4V\"'' 6,?=6PXX +W3bcc.[n]]WW XS0$::d\=PW'vWJNo(F_1AAAˎd;ۀyh8lSHg[ wm]]уb]lNrL.<ހ٩9ޱ۸DE%@TSf =ݻwQH-k@N5++KѨQ#;vPѬY3eBfL 0Н6H(D"C +~mG}#%%Ey+YiwzO390&#kXmn{  xfc"\ս-k^Wwlbd@r>`L 0"kX%IN97 -OqWj*@`90&pD@װ껍Y3÷V toÌfVG 0&@EL^ۊ(_z/̚5 7nT-O<~ S֪֠9`L {Um\tWdf#Ox{i`B 7hy_~eE-ZR\vg9➙`@@װ깍#('N#^bo\9 k60ѣG+^Ұ:GEN}v 6+ 0&j@&/VQ$6/((;վQ=N7l؀ODeٶm[tMߴE|`L|~w -aYFz谧rL 0&kWn$^#9be)S_+U2hO;^^O?]v"wŊa^t)ڷojI&/ ޸{GmڴiӔsfſ*fĉ{obܸqzǎcΝx[9J :~'~4Ho6UCt'/Yt$qII";p^b.qpRZ3%yJ?]+?? ٿ?:tW\qcر{ѕA{(&4J6 Kk;=Cm뒖wBna|f[j2QLc+=MRRBB܂amWVfqkf<˒ډ/ŸT )=mڴ!kLL h0ꫯc@hVmG^M>R[_]уt ]!&}+ XtqI.%Moo|r J3.uE=N_7 ֊P|rO/QבוT[VWe˖YY| ;PY@wP4]^ ᚵV-9~aXXvɓ'{6uD{==Xٱ&L 7k֬N(u3ȷ8Ϯ~! qls?* }~vq&`uawWصKGNwU܁*L ]ê6/'O-56^=%.ݕFYnrm@ouBt'+] wPdc_ԏ8|7{QO}:^:O֠F(ۏ|my*a}g9@ kX: 0nOE#$M.3fuԩhժhݻA2ѻS}iӦMrڅц5E@ #"F`/ֺvxkNkN0&P+t khSNi>}ZyK{t颼_iߩJWD ?'kŻrUńF_]:8oCx̟־F?.}r`Ln7n$^zڱcG̣665ZN}E8tzX܂r {ѭu,\9̈́+.*޹޳ʰ2e}k2c&DƩ@Uڒgfff 1#/53gT6}P5$(..đ3GYefvn}wFmSWGLbN4sOLpglZo-\=Ke˖HLLثZ<,())ѳ[Jd WNvBǖC0 jiԵYmֶR (6[:h׵ t&*E8r S,Yd{|l>iR:% /^k%7S<ІʭwޕÕ7عlÓtF5%y+bbTݗ8 MC:,~1Iy`L N^m\qN|loy"FX%q/=Ow={DAA>,;w/?l_I\0B1,(*ۮD4 3}Gz k'Ly[3) TgteE'53 fsW~׫Y ?MX"nm!ڒ0""jXiJG8 dtNXBL")ҥKdpyԌxIN̬MeըTN^X6S~/iѪIOaPoF\'6_%' %ik?i4 m9ӊ켎.]5 ;5#iw9$4o(̯ 0Ǝd_qz>eĉvZ:z(ϟoIO[lsNe^ֱ*g;XUƓqqq;X ##~S@Vh<!m![Υŏ,E¢ƶGWU|jV1Q8)B)[sĐTLPኡ/2W]ê6䋽 M XJg=F}ᜥZ&.?^vZ=1m[Hl]TQ 6O>?mOV5lxbxK7ڸ PI~7!h6VZJU/nϕ'իrgC{ιs@390FM^u⚵SX=qC`ژ*҇BӲ!˥ȠT#6 ( i`J?.7a"qM&Ç)xz7AWbcį u{T-e:8pP7=h  ٳA4hۆ @ml#ÆZh_~Gl.1CJqm'ދG)Q%dH@cqGZ1A ϴ\ T'"qqp^&SX|i">}<Y+Y+QPQRTT RB I齷ݰ&;[gٙw3sϯ5iq*#gΜs9.Hj6lɎ9T"N@``*kC[f*{ƩTHx=G­-FuFhpG;e3WS~B^+WJ׫& 9&&w>2??{ӀS!B %~y,q~3gQ]q'3eb CTj\T;RLÔ#SAbBZlk$e{Ͻ+UەmqƠaѼ8S-vWl%M&NUХfCK5V5؆E ζL5 9E1CTNЩ]OlsuβQx8Sj._?:Ƙ 5ULIƥ")X?W^73,qͶmt`W-e @sXG:_lLJT2OE2s, rpP9C@iymѭ㉈ lixp@@9MED XDR? ?dkO= gKW`ƽHql8p9~ń'ૢiazisUtFl),} &̊sL%ث0 {Ҿ=Nj#XˡGj&WZ%x~ӱ 9Zqjc\Ʈ DѣZPn v}<;~|3:0kǤio䥍,3$ŧlǑ}ʙif Ѡ-@ucwCmbrO_9[Ԕ~d K\@H$ ״ڢٕk֋/'O֧`~O>QeeZN[QsPzT/Hϰ Fz{jOVQGK U :B S VQYݩ࿳];*pSx+i*WS1~j}TRY!`B޿l~"J9]vO,viv2ɩz-Kf&5knrv„ Æ waӦM>It;h#ua9םV{ZPOݡyW%~zrΨ˙ B*amrup%'V^ T sĄ]\QY N€ ?vWv#دf0ū%>2gG۲HK(Q_,ʡSꥦ",&&LܱJy%V S7Tod E999CϞ=k]~GZk6:>5Z/ݭJrQAH[FgЦuKTwpC$pVN5M4B{ ?ꁺ'C9T\wUFBLTuν?{J=R>4\6N>Lؠ(x?@EJ[o˖-{vZ]ۇ =RuTA s;9P-?Ȳ5hw*KƎLinGo`՝u/-{;`.ʡT(GT8T{58:f޴L*U*,յK$ײ:ʘRMq9ʼrRB _v_|kJ*:.C^i"{ҿv5`>*w 6"goޟ{OGQQQ+-{cu$^KQ#¼v m#$eSSeU9v'-(BlzD"UdpNowl-@cLLL4)e٨QXzqq1*|jFvtnvt@LiDžVVbU>EO*CC:.DC*T)'sCzCҵC_rPJ0flʬmFFl۝Ń]tt5-Oަj~߷FLz9IhTk91/ЙY^a*v}E9~ O qG9&{]hg57\N8U ׽{ 3nLݕׄ"BVqj-d j4vr!GugtN9V)k3)V(&y}]j_vb=8Sj|o]d3wVo.ǶZC?uM*0}B_%-F6/ Rc:Ѹ[ڬ3frj--ąY{8}>ֱH<>U0vRu0gG(ס .zN*QC6rt-I{LPl_[=Lm㤖z 9Rrp$ujjl)=%1P˶+f/BC*KӉSuGf_=  `?pRZƲqyHͫ>Z~:G"hxs: y7nܨ%=fQςZb-X[9TIYt_A\=?Ô(Hl~zJɱR:F/,P1ʡSktrbsI*qt+3*\(//7j"UơySoj%Qju>s:yw Ýw^=_.Cqwi4sUSjR9 W;d&jVLVKV]uX+&OchUZ]]o18fwr\zaCԴOFt@(v;|"%<$ o6yrpsecQǾ|r\}Ն%?;v,믘3g>G3Sj&ZU"_ ;GyIHrI Yxv8Uj*X^z)ƌ.U!QpUJ+'q)[۴8WMa1fWww4@bz zVn`'<{JV,|s+buSN +_99{)8-rȐ!;xc/a }rؿBl̾4pjQ*5~zq!xYN:<\fTk6NfsXq6)]E$*1U@0ݚZڹedd=.}[c/c]cRcZ^z%ZAl2W;33g8Sf۷n?3k*[vwXͫUs >OB@rW̏mOx֑sWTq/Z'Z)?\5*+Yk2EB=MaI6v% ? *9ZE3) [1ß{p.,UacۏhlutwrssuXn򷘍iӦע%^xvǖ-)𴘘qq4ӧOV=fcc5 xظr3;#ąIx# }lE1V1! Z0^tqJ6ffմ?@rq :Qy͎k ɊoSL… AIOng#5m߾=ȑ#+xzy ~gU[ٜ\6Ne NEtY fٜpg {1?Le8螟e֞|I=nKͧ$~ 8)Kٳ?Zgoj'88nu.a*F ;*'pޅslr4s報| 2:(kuvyfz~RV!J^¸5;O'- ^c fbCe'q$5kcO)Frvuũ[NwCP &l2 QPP`8']HXħ<ֵ6&m|Tz! 2ՒWH#xߏk[j:U^zm{IczF6}`499$$D@-aYtFfql=`yo+ΞPOK]쿁fZj֫n"XdyD6([>i_s˨͛7Ւ-_\Ǐ ر<:;-gAW yD.##GGHǰlFs,u]/1jC)߳%v5bB@! 2j,Ǔy)qw%"=zof9{;4b]Tvv6̬}vs,2U;-˫B@4Ցl\Ex@EPe1UN%__`SmN#'B@+S-w\Kh3)'{^upL|5~c2g l"TaX7[bB@! \EԱjٸUݾqUw$[&V|GT]Ugr9cРA_|o))ƉMO&! hSǪerQV55کF]jWDaN"\m?War%&&jKQQQ:#j"B@!,@r;mԼո{f9u8/>7NgEzGP)/XˊB@gűScppX:az%LD]8lL5i 5?B@! iT0Ld!DU!fT5韋 %W*&d]N$63~^Sl_.htU~ަg lmc״JsSfԨQ5kaX2f˭2s5?ZfF0]ߏSO=lWl7ufqWMwŋUoUfe?\he1t Zb۶mG}E"TI*53/ UٕXXN?07#GGF8lyꫯt gԀu:Vsٸ\d8O.(/B#Qw 1!#)ˌI4FϘ1CRu„ d-e ! NɝJUqY,yCGx/}]ݎΗ;SjiVXKy||MZJLL (SG fݴbX#֤ReYI؟6>*Iu%2KM19̩y6n܈ɓ'7fV>k[[E,l ! Z?D(h@v9H nR̄i` >"BMᤞ5c9ScڴihɅ^{GlvZp; fӧO_:3~nX1uץ%nP5\,?..N;RjFFFa7+-sbŋNE!<t.2Ұt[vʔ) p;s ֌{پ};z!]#GW*1<=?^/##C,^oqGLz NKKO?kܹSu=a(YB@0mƕ BW*o!ۿ{i4>ViwX;KB@GWhy 1ئr*lbFl88aت(G+Nymu! !Pc58ueUY!C4|t&dzѿncW٘1c6sN]we]6! h*D6.M9[=1 /džw>?/ttY-ٳNQn>ŪQ! hBL6>X +2u~߯ ]Vez&r*! hLl\%|+/E*)WPR50KB@!`Ցl\ƾ󅷚tyMaȁB@! KԱ:>q%1OS! ͗@kB@!IZl' B@4M[3BWkO>j~ѣG"gB@At0#Ӑ[\]/& biYغ/AuQ~-E޽6ls7mڤ^*&Bc-܃WZwZǔ[G"BeH }ƀcZo .L?btMFK+,,ԭ[{\E姼ܽ۞R"g3IMMEv+)[`IDAT~yf*+6w.Lňëpc`W02yuTBBB5p$u[-XSv.RBՄg3ŚCǪ~zWX&@a۬AO^Qako,vXw.-K8$$D@-_n&72KbѾ)uz'Lo8^7#'#N9Ua}Fϊ箃(<%BE "-CQV$S?b3ueiB:VSe~9((EUSr_H߫1לg򼹎{Iڮ?\RB@4cwUw/Om7{ ɏbjlV jd ! h kexk쨔92aDE68jlB@!:V&!Aӫ<IJ:ί*YZڸ5T _|gxéB]w;e\~ˣ> R&t=r+0m4ݓ!\mtdl).FZZ:*rE6n7sێen%m vY+Wt[-{ SLq[=q}n4BCCu+ٓ֫Uᓑ#Gv s]^C2Oj<9s f`ھ}[|\Eh*ٸEXij]<7o-2+sxq[賯²-52j׮]d 0`@COb[p!֮])}[nEseF-jԩSuf-D^7zVӧ+WP)QU/:ZwuА;u9pBTnyGVaձl?|ťmzo'QR[^G@hW[lСzG=s/(noYZ jcrY'28pc}ō7ިsawyҥ[rwc:pƂ RKCn,oJ-hų[aaL̳ xٳ*m=uT=n{EG Yx;o\ýmf[R]g06<z*~eKȝݞ{QXXh*h٧JrqK/mtaPUl\B.Az-wɍPK98UϽ<<==~*w𑝲quʋē6)qU]l c5"ۄB0tdH%< ^LIEVPgby+orB@! c8T$^Ó/czYɊB@Hб&5:%+w{u^)M̮M ! he kmq=PV1B@!`%0*غ! u" qu$; ! @k q.56p}PPڷol-B;Bք>|w>sPшW\qf̘rsNuW_Y6ɫ-qHGqKL8b@"¾r9u$@!CW^x{rr4}bVѣGkU:^vB0tUqKP9Çcʭ#Qf^JY .V~C!h53K>@X.FTYjg=eyB0teBq…ݻ LX,.ۋ[cjF.`/Ua8Z&M`)b˖-xᇭ\y'pꩧ͇“O>YިQ㏻]֬fc|WXWm DJxT ;6]InUbh P8Zcj7aL>Cԩ@zeU#ˆC)m1:.e̙?ڹs''Oݻ7ڲ7ov0*@uƎաl\% Y$m5 À;XL"Æ q%`ĉǍ.6ѻwomwx嗑e˖Yi@}_IuA~WjmO!B@d*~Az{ 'NRw /P;/I'vuUuʕ:]<-55U;[nT=44\s /^ !9[~e~ W:7b C!&ϹJp2;o ?9݆"lu:۷V/m*guVSKKLLn op CH6n@P}Pm`Cd.MU3bBrRp.q͠AUcgq裏9KGWRRRVz}| <`m/&0tdxh6˥/B^[:n JY4b=#/ Rꪫ[nEXU1*:wGy5\Y#B- #ٸK=#'#p[.B  @v㭷 X5v.]Tg`2r{ڵku˷O>] ,StHit,e!["n%`Xy!bŁIC`ԩ:B\}պ]vaٺSL1… Ltl}2ZQ4sLp: 7܀x@bݺu`jDqb*>+SXlɒ%*Jn!Ю];pqYL8籕3 ! h1VGq^Kl\>ʕl\L^pl]j" ! h c8XTUSup0Fu'l\ J%! @c:VDzqM Jca<6qiʱgm͐cB0tU`f* S-)[SLIt1! cu(x>A܆9?C+quӔB@VO>y 3ٸx1c 8?B?f)B@! Z'SJٸykM3A (aꈎ{?3tƱʾʩ2)be{Dɽ' ! p5\>Ell,&@+1llxk ~5n YńB@zƎUUݼ ;" Sr$~ icЃj^iY ! #lw,ڞˆr{Tb=vLB@Atdq7ֲqq>"+ $Nj[m_J! pDб:;*G[R>Wyc#,>٪PL! @K%`Xƥ`+RαF~TeE! @$`XƕUn4s5 2Dy#cM6S჈ B@! Z16\B@zUNs]aRB@JOOwc]d n6_b.ځM!sԲ)ixeoaZJG֏W]n*ʱ֥%h(r%CD"`/9ʎ+| D֒76Wt|'1 Drhֹqf64ol7zs("@ʌe Mr{!&s"@ <д;@M췑#D r D &;D"@H鍌 "@ r" D@oܤ(] $$#=-ZqpFUFtN,y9Q"'~QU 6WP3e*-FKα_I6w tMV<-$ Y#j껵U5}$YGs)]uEJ1cʕ;?mOã8Nڂobshs( {o"ŷ]QP"Μ9w)Ȋ(g CJ+ mo˫ͷ ]HU\eV<;crT*c^.88i]>3T\vB]UǓ뺯Q]v}tdܨХ]VKغyt jTֿ5ʟO:;..pbVi"Ɓmp(\}? ,ם}ư~`mOQ\4'Rnb#HV7 ;8 _Mx+銧0Z/MUAӄTs_Lx!Édz\T*tjίXy OJI?v Wn^.^T -[`l(0,s)GFRΓ"&&{ޠ.Wl? ]lsa=]d[orճ>^ŷh ZقSC9@[af뙿g҆xsfgt?J@Ɇ$;O&\g)[±Xf^Kܷ{UK˄%} 5vjN7NZե\t=FHG ۾mlw[lNR_[p%f%!Cjshg3JCa?h)jpjC{`l]OpX8*x6f×-݂6`ݵcng|ܮNĵ'51l[8izOޏ;S*7]9vګC Sb @Òb Ngb@n ̠_ȷe*q| fS~όCMfsGe҃Ugo˛KW^;{ږTo;`܌Y$"V͸ɭ;#@cR"|.);5wY=' MVRSRg:طu3ա &gXw޿'o?7,6q/ݛ;>+7n͵|Yr5-ՏUMn3N~wK&5GZ0krW sS]kUY_uiI"`d,U}ն_~Ԡ* Yj.n2OVPm8]88Tx.[zdU䝕:5uZ Mh)GU#?[T: %N*|70.߰i[U|?/ISU[t˫ W:00DI,\ɡy07%RR&WN+l.G f:qқD&R`Æ] lGuo2Y]Х]e )əL8Nm_ȉ-GYt!{ À%HƶGlnz'?3 a(s2ƾu4}W֢_G|Cl{rkFQlEj}ȉ̡N5L;D@7|2 8G&LQ"D y#!aIKF 2@~yz4kFfuX yc wdXjQ"D@hx IF  f 8*F %@M$#D r3#D &{C"@H"@x r!Ɉ D@ Gň D@HސdD"` RnbD" ^ܔ'0!@6x6nfprpN"]7xJD+)gY'wT\H)WݧLB Ah9o#̏xpFZSpW, e@Qw7*kF/XI}ғeI'8wZqpϙyxxN=X\Kby;xLW % 8;; BL6+R/ D@)7-K e)qD"E %DȰ:"w/Aе@n %fT% !#:k~=qqa TGUX:rwD@tF?cLǷЫ,8=/{pgϬ4Tܞܲt7PWxJG(q&M|55'!PZ5CE-ӱ%dLf-G3H:/p?3FM}BX̜CQ}$$$ && )wi=aFh7'39,%E2:ĩ53,D8 s#`y\Em'k?7ȷ'0%ǐR${l3`0$dJ檻~etaUDW lVxd:Gs<{2"k"I u?w5Ӛ{s + eHrrԍV=Y W j2[g+q(Q滦}`;g|L~#`MZ+0+7MZ p1HbdӮ^w"5BRg"!HކWR"uwvDN֒ ax 8D;:S" qZ*g6Qrg;HS: *7`mc`"* . Ƶm=kܺ-llo87CZyyir*2x?TI>A˹{eWR)p,EMX0A, ' |#[pv/᷍ÿ>lj_p@԰H܅C36̘rۅp[պBX=a]psxҫWv,@{a k[2&)<(=_N  z[w^C*0/'T&F*wLܔQWl@ UsԊeot~܍/H"zDR`xxr22ԒY[L{JX.< xȌK\Q7rAZŝ* N'H "<#2$;O CQ91Syc0qd;tz;<ܯGSIB<.,DAY١jq.;V'ŦZذpt2@ ?I@!^ce]J"?u7]H썥t#Dլɕzv2o+G1π ]Q]s_#_p>Eɣ@v6g7<4\yzVPRbuPh}`h_^0-/Q߱)VF׷v&&5lf&''SXגEB_+ W[Ij\ytղ|ԡVZF̢?v jW*BJ@||WDͶ&[ j޼ c$/կ܂5,;E)ߴɕj/0W ZuЕќͷBGIfG7Gc\ekF! ݰN1:y_o8 5[SS-u66A~?"lDd>([Lw"aOax~/c 4FƂY M>fȆ5ſ)[-M;T{HABj\ld%*@1`jjLj(1V$ SY'`7^ǎt$>Nvjn 8s\[JQ*'32lޭΨ:;ș[6omjx9, 2^qkU/dĔec$M<ĤKr}BHylfVL e3K8n=N@0jg s}rBo[>Vy#SnHIewj ֘z9Ff_R(ϗ~8) nBZ!_Od!yW;/m7(:@MT\71xOj4ПA3d'V}v k7R<"bneⴙ:-nKP--%p7`Rxf˩k '{''ڌhˆ=@ʍ-Z{sT* &b{`:Ff=+a~Er2bW.EUj,?[#Ogn*͖Sl%c:0H*d &Wn8\golzkZm Y0Ұ|,X1G5lۣxx(akF(@D<s?;9in\̘[>6<͂93,WڣR3;V"Ebd~q۸!0ah„pKjT),uܐ>}_Y1eTW+߃#9sjD-XDV=y aH<UFP5mH.ΞU_f\FΓ'3 o0.;BwreCK!;%/~3|7%ֵ|' MPlid6/aI~ ±i,Sz$r4, j^S"^}q@k,| жc᜼I\ؘ ,!µšIhhQ w֯Ax3Xٖ Xq)Xp5o)eJf+~&O/ GoR_QPcb"C!䃶tD&JQ?FOs+Li->371'6i;FӶ>S."bsQj_FRS!z,2-qX z aLMog?ax> |1gF]qL2J ?渟lB4Jф7Ăr^v06>y.6 nQ\X8y5G~{ NF6ndsQ3UdK.Ht;&k EPV/ܵ8͟;@G5Da(*䍽gSCI[ AJHdGs0Tȷ[B"~6M+m^&8i.2bpkx`UB9:yTp-F)FLqX3~$Hdb}DF*MB12m`دOf6O[CbZ 4uc p]"B%ϝ!3>N0;}XۖYK̢ m\/X:3|Ȓ~2~,rԊ ӻn[Vz~ijw8֭cɲ[ܸ$vB8~; 脒nR"v1RlKʓcjiMFr%x$6 >é)~NE̥pDD\Bb9^v7(kT.cXBcT Z*|ysۻ,O|)I%? !8~4{Ǯ, _qD! iE-DFDRd$"-25Ktq1A&e^~a/<)]B٪1 %> pzbl߾ҕF2csp,,0r *Յ_f{~cۮbQJCXe-Pf_ⶕ W›M˭:Zw܆5S˖ ΗQڼԵ̎HjVYဴ'XBh=9`N\.Q+TؼL?qߘ-ʮCom٘n˟/ZGp+ݛ,*쇝Wz+/#GKYĿZ?nm!%Eǭll ^'L JpՏ$.l X\h2.aZ@~6nn3N#Ss[5a_hl#&]09+7y|M'lɹL!֣1d> zm_O0(;l^+\삇}RhrQMGHmڟ7eۜ1uQXmZβefBc6E_D|3aY6&ĭdA\#zD2 т::L .]wL]k{e)6Σ:<n`*_[^"qBNV1' %5 ۳!9]ԮԬ4b(mzT,)8MH8+|L/F'ro>C Aػ6Mgǿf[>O ,\MW7pu.62<om<9[ 5)Jُ(27"/OWp?T݂#KMwXq9!o\4vf~wR%$os&-3!..\MymXfb4x$n,ͣ0_UŐz׭s[^Mfkþ3nalت! ,Oc]{W{˼-⮄}0lX03흷wO^*Bٲ '܍Wgv$nLƜ")pql\$#$3z< ?PR߲yQ@Z][.]x^"6.\xc82_fC,MQQ/Cb_bǝzj?IonCKA]ϝ;-ڻYA2;vb(ٺ6Ψkam/Rs[BG"!ҡdZx;| }qJ`őHeoxx\):6G o[LVL{,֗+Mbr3퇕Dzqf!c4*r-Zv#q'؇06WRaoöJBTa$̫ˣӸn5w;"*Mm[O/Tic\CfHU鈺:z+7.ww#{o qɡrM$" Մ`wM䉷_B|ċ~aN#99iLSf$n9ywMfɭeTn`nTPM{;x. ayo%YżI5ʚ-Kq%"%7Zvf ZS ^\ܥ# }\fO65(ӟ! 7K#YF%1<Բ;M.d[TlBw6 X;@՟C~&mfux]%PRh*XrwJ${hifF'ڠ3T+ʠX3U'%Ϙ%o wڡvgqm;*6ey6k6F85Fn#ߝx{5Nl@9IɧN0wRBo˭{] p-93xg`g? oKOuy^JB-#T8}\\0U^S}PAÂaY i—|[aC\#q[n*uY&N/Ӫ'.T>=C{NMփ ĭJKż{(߿pkCէ@Vtd$R)[.M4}j}˕zіNcɖ>$OZGdY5mu\'ApgY]ņ"\f?:8k?~߇7_h/5(%{>Z80-Ы:#8.PMZ4,ذl @={wQW|foϦmռ3#͖ED(*@85ֶ\"$.kx8u1AKz` %̈[8=<Vk`}ӿIm ]#A7.KeԦق{vPّǷx\y:qͷW @@B^ mZHX6~h߹c=VMB+>*^10! P\Zkػe-挛oXJSߏ%.!a.4/ C(2 6qя0QF /"" UPr8ۅd~ܮaHT5JYg`>h+ScE݅KkpjBQ 2jFey2 #2ȴ1mZvTiD;]gqQط2`i U.Q"Z8_/:IQ?cؾhX'ycXvJnXM3|=,e*:=[Èyr;n kpOcS"xuf/!<uMTGD35N8瓪$"|xwwt{?d<4HǏqs|ǁ7 [{HeKH J=uKQ)9ޝJXk?d‚%oa[/mPfp5EPr(pd*6k v#W<(6U8aW_;|pjÜS}~18BAL|hzr%+2śUWO /CqP=75{[8,TMHSj`M/e?#{F邁 \@0\u{aM3jZnV ieIN6$O 孹ngQIS~ [5<\!QuHs GS˄Ӂ3Y qPL.Pj èTqϙ< ԧ3rfY9YVb;V#fR:)) 2ͱ>$/77O774?fX*eϔZҤ,W|p&FYPVT<pO&ܒ|f\Op%i2E!yw,Uӥ~y 7Ƨ2M!.,,> _f+kkuZʹNo:6Iٌ@@7V<@5( Orlcf &r)M$ VP~s7s ԬWx9*f,QY{P~㎔WJߑ*4; ˆ+{_݊A $dVz"J6YwZ wekuHe I1aX3!rNJL\=gVͧe5*n,1AIgZق,6tcԳ m0ѕEn%p6h-T.], OKBITVָREo2;NUIYNw!!; e`G "Y n1[1mh\7cL,Eߏ~ơ˺ZDˁ&Qn@T6;Mm:HrMPfj(SOpk޻z+5Ya vvo+[Ȇk}{JYy٥Dvhܶ7> yU^zu$|r-h-.Iۻ5L&ǭS);O; \wMgܧȀH"4zb)U[>xJK >3sW-) 'Q'2wj ~;lw 6l>XPn?w֭:R)_`hqDxGLF)+ۓf% )NC6>˹~Ww,Qbo*mwĭJuKT sE/¯[ 2 ?(ۑ;I2ٔz@bXK&QJųF9 j6r^LfdScߛ8k;2JH*Y 74d|.aHYpMSߐS|A3Xrk{YiP*u/D4׃k,q߳q'|Y ՘["~$F%39̳{˅+XY ;nR,ě8۹ 6 a"!4RYVmUGp1(͈(Z6a{"*T[߳'-85HR=8Vؗp>łYE(<GD@aw)(w_`Y*lBQx)6e0,8{eX:͟-Յ/zǛ8-oSs&b[jbkp+m&p _ E\FNAtYY#$ʭka=&/ID  rOn1zJ0>ir -O+IFIM nYϗDKO#,i<6!u뱨pڏqnLK[v:e^L!"=_G|Xb63^}h"}Ɔұ:Epap2 ٦"" UPrqޓy1]בCuh܎~ Ge%ER%t9 mF~+ fq2wv g*uѽ#&2iUw&)t:P [q *' b 8IX히?Үa>Slnc/6,1DnO ftEfUIh"&1>Y.N4ɚj| Ka1(➐h%rSF MI8q 35s}VǓu6?9q`*Vb>Q+KFgW$ª#5-N>,s)B5'䍔f1Sa%oAԛGJ7wf"7E\ٿ>ч}H6È[Vn؝ lHa4nB|9.6j XIDATS˖5MHI@MlGeu.KAp<:l +PW.~y϶Y >.Xg EBZ\մYh](X6],qB3-i\dYֶEK6]1|M5ڇK8ڗdԧ\Հ9HS1l`kSsS}r06- R +6qPٷ15|- 4){ž= TȞ>ч ӅVx|WʭlB ؙ[Ag[q'u}d3e$n-h97dGc5I5v)q%XR$nӡ@"/:_:M-)7Ob)JL{DC@8:[L1[Zذ3О'QGS`/ހe stɢcNd{ f-L(Um!,LLU߂kD.}&`͢-O2N% *$D,HT>Rt'@MwV"@,)7 Q$& EѶ6+:+]-Ĝ[9OE"@!? 7CJD@ @on "@@#@ʭR Drg"@ ySS D@e2>(/ D=aIG"]7I="DhW1MuQtvZ>XrC$P/x M-#C~_#+,If6MHܧNfdd@TBs iod+4>mZI!HBp$LyO$ ɐڲe !_\ְ=:ɾT@n:U~Xr'-<|r{K牋JBu\qQO̲K>}lGGbWmBAx5aoĭXL_̲qNbd3I. 2jVa0T"`snD污m1Ɵz1Gd\~vC8V& A~s"qom{,MBbzԬY3>1ơY>ͰIڌZ>$osq&?)72UU R$n!k ,aÑswrWyiL< D@Ш D)7q"@ @hEdQ !OG)[qˤ@d8}ʰD$5_+En¿DT=usH;7%1X,ף8I` ֓OC9Ul )n#Bpɖz@FwsCQ}$$$ && EpG"/Q!y [q]h#A }BXqOժU++}7_?2NcW̧Wե%{_lw.sFh>A"e.MK̖G~O4i_F"lߐ#UIs琌*pw.Yr$| MwNFvm&fA>hXЛaCE 4lܛ&E#br&jlU@Z^?޽pk; e>h0cP3Hl i+N R,/cx$!]V +~ h]5 H &Wh+,SiW>6hbQ4d(M>\ χm,8VHN_9# Ye{Bܑ.?V t{?x",XFt3SCVcҘ X`L<*yh>KZ V{ FƂ7~h[[Aq2!,<+zmm1UY=:P}{H0xgNT?QrP]r R \hiGÒ[EK8UJhƆibWǵa^vpL]xOC>bp3,k&?zAh[Oͫr7rZwC]W(76 Ə_U6Xp/w$eBOds;vKQDuRa"P2?L*i޼yjD@Gʴ4ٜ:2̅"s5%ҧJ3gϞŀrY܊ z+9(P2?)H .c̀rf*B)͹2"@ fiw%Db r+e DK#@K  V,"@ F1"@%@ʭXD"@,;F"@)}BHylaD D@(X ɥE@ßF摥5' 3;OD М( 07XKjVo" K'%Rn-C(OAHȄaq>47,!>?HIDrӍ2%vNhϸb^^r4cu_,ܗ#N?ab E^)aGys kiju(w_=/="Rnz%b߷Ў: ]aS_Acњ:#p60 }A5kM |~=>ZڢbZUk3`!kqU3ux(:@DLΨ( 8kV۔nvü¶*=6Ot`)h!϶V[}#nȺKY@צvCڇ5#+?Af "@DOoQy.μq~:c5t`1^T¡zuA)Y؂(埰%4WK`"~n= vץXbƳ+vܽh4 /D #@nX7N=  um{;>3;@bcqMe1LkDa nt;ut폯U`< $$@"o[ZrI6$# Z h-#Aǡcַ .O SjNu.f$ ilpSҺ&,!v¹ȭjl?4r놽l̒ K޺$8L|6)O! C× YyLX ز 8|՗"WK;Wvn>:x2q`aTl;|BS[aG^~=>De fYLJdgJeR⣱拞3p~ɧa^;v덦}%˾m;OLgC;O>Jnxya _ꃾ"@,@A?-?$̕*=nY49W>`g0[8n|czjq? 蕛hsfQyQv˭O0G;3Ҽz^^!DЛݳ2#S!~~B_C8Mq`:㷍aΰ~ݔj⍏z .g)qBVbL;)c} #'kh]"`q$ϟW͛73ILf6R8 CQE5amxJ%Ù6R;q)ED@LL Ξ=#00s2y6kےs?1?I!oJF͏{% 7.#ES+HwJ+']# Os=#)H@l )tI_%lCk!FwjHRNP7@'@ʭ?e[=nbMO`KDKLŠED Dr;F"@@H2"@ fiw%Db r+e DK#@K  V,"@ F1"@%@ʭXD"@,)7Kc$/ DK… ~) D$BJ"@@;;gҥK*xYk<''VV4kJLIS]1%'` TWBTڵk# >>>zE"E#*1Yi@LFVl+WG;C^ț *Q헐1-!1-!D"ѫ3 e&DK @H z .L @%%"@"@M/\"@,)7KK$# DhdM&$)3f6g͕m6<6l#e P"DR!2wJYEQn*:7yf^X,Y'~"@@)(L6O\Oq}Qr]4B<#/6b>)7 D  Qrq=5os4on)6~Irc("@@*٦4opyonxF+JӜg DU|~(84Mspʍ+0ċ{\is R"D"`$J ߊUn\xFbʍ+6Rn %"@(7ฮlya<)7 Dr~J{4j4Óy6zk("@@i0js*m;S| D$Qp"ch>LµhIENDB`././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/secondary.py0000644000000000000000000000157500000000000014672 0ustar00from openpyxl import Workbook from openpyxl.chart import ( LineChart, BarChart, Reference, Series, ) wb = Workbook() ws = wb.active rows = [ ['Aliens', 2, 3, 4, 5, 6, 7], ['Humans', 10, 40, 50, 20, 10, 50], ] for row in rows: ws.append(row) c1 = BarChart() v1 = Reference(ws, min_col=1, min_row=1, max_col=7) c1.add_data(v1, titles_from_data=True, from_rows=True) c1.x_axis.title = 'Days' c1.y_axis.title = 'Aliens' c1.y_axis.majorGridlines = None c1.title = 'Survey results' # Create a second chart c2 = LineChart() v2 = Reference(ws, min_col=1, min_row=2, max_col=7) c2.add_data(v2, titles_from_data=True, from_rows=True) c2.y_axis.axId = 200 c2.y_axis.title = "Humans" # Display y-axis of the second chart on the right by setting it to cross the x-axis at its maximum c1.y_axis.crosses = "max" c1 += c2 ws.add_chart(c1, "D4") wb.save("secondary.xlsx") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/secondary.rst0000644000000000000000000000055300000000000015045 0ustar00Adding a second axis ===================== Adding a second axis actually involves creating a second chart that shares a common x-axis with the first chart but has a separate y-axis. .. literalinclude:: secondary.py This produces a combined line and bar chart looking something like this: .. image:: secondary.png :alt: "Sample chart with a second y-axis" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/stock.png0000644000000000000000000026475400000000000014174 0ustar00PNG  IHDR}[lsRGB@IDATx]|^ @@w A@ET6 ?((  4 H  r\}w{{{wɡ2ffywf͚%I"-p> |@> |@C-ŦʄXy>eiSNKsy4{xu  <\YFsLpeTyo%~#+Fo^Qz}\~}D`OK3+05FΪZjJ+`1`~.ԙexI*P'Qr1S^OiBl$#DbY<M0)ψ.Q63ko}ufoyk (4mZ_ہ3 GUXADiT\zY#[)i<_>VmROk=' "Q|ET]"=m>|S⧺)沴il/_}Hc>纡1S~O3=YK85^ʐa^XGE1/M͂?)<ڴ QPƙ x:iL}}Vʯuzz+H6ż6ϖoDZ{r)xZuieٮon2L#_A/_w9uGo}H?~JG͊jxmzz)3oCRsi}@_繱WjJ4R9_ʆ_WlcqJ'<17 s 2+j"py.S&ІA$U-;w6䖭.-ˤ--[.߻`䐽V(89YG]܍:,~U@=_{m]ċtup c_0~Z\B4!?x٨`/O@խWӿQ.7'!>v:Ƴؗ|*>.CfOeHE7@)@~ݟ (G>pY?˺ 2<+P<6 dŗd c fyTڐgZ_zhm&:~*K8QKxx^QzIULu^'A/ŗR냊 n>P &~+{tϗį?Ql%0 /`Kz[Tw0u Vѩ~|֍~mFvʻhu#ᣏ~XOƬ _`GVg@e1/W'|hOeyl)c2hdi>QHly?t~+( *npryy+7TZե\\K9:/ r =ڴ>Ql&_ x̃쨥O| ^Ɯ۱x?ԫ+N iu1d0ɤsVmZ_h[j;VVXB1ua{l1W+y ߁ꦘsjD؊_^_s*K1SW7߾.cd,5'ޅOj+sb‹.\ߚpK;tJȿtv_0E_9kD؊~֡y`Ii<4:9S sb+{b+~_kie] OY6vxb mï=NemZ_h[Skחʺڟ~ƕtXo/#y`V}VTb+{b+~n?1]S˖cuk[+2?*gp%?餍n9M.NOvd>'[­<.`FZQ2{*XJ}‘Ζ_M+iLBWl:|ҙSF!h8n]mM>#3m8o#--M6<"qaycBwیlibQOy>ɝ vs" ][w$;6G~=Gqa'.eGz_F=Ys}BvS\]~&G\i,wExVJW)WZdv6yD<~NiLsQ m K[dE!Q!_S$;() >Ft#= c? GgʊnNÓH 18ݐ0I]qmvX^GޤӇ 6i'[If(z{GvSi颴:"+@KiWk?W/g,N,/F F&ꭷv^iQ[ڜ 4Yz44yg~׌?z2]i&\Y ]@wʳwjl;_͍S)+Or)GeVVt(9G0:hqC,3 L_ӟ뷒ge|w?W)ր<>NJS$}=$ gr+a .5 9HNզzx)ec?k46A`/p* ۷KyJ0yμWd('>jگGq ~u c7lsf:Ѵm6 Qʾ $b}d#d+y ݵ *C8Ra1+ rGnaxW6oQ짲Z< dÕxC쩟0y(wN57{EmXE>LgD>K4r(`,y[>գgm2柑Gb?[[?Oϭk܈ 6s]0_d+V:s+iWQ”:![<&yoc(V‘yPd}O`=Q8IzHwmצ[IQO .y)#}TQ'2v3FrHw~NNӦ)O&tmɢ(VP%_}q cl)O[gE'92?g '򑭌cC ۫?wQRVYѽmM㥢,7,y9(1JS>hURc;6$䲑 9?jĹ|',i?&>VYѽW}oX b *c'xJ:~)1JS>W)_O0ڿ@OY!?c"G0KmRzŨ&쳢{O5#O+$E>sb⏾._o TύҔ&=)沴Jhz:? xjD {Trd<⣘e6ygd4n[w ITT)7QN/WyʧXU`D*GysXɳⷢ_QTm|:*Ȫ3mu@hWTby˕ę;k҈p'rMch\pGJ:Nsrs.{g߹1 /{9%`4[^bO/w`} ؛_ME=^u?msWWt=cUJuEs$3;łBlѡ:\m/yks TkIͻX-ʫ U?P:K}hCaז/4Fu&Lz~=]_^v6G&g(~YO򊪟~-i1/ T\{?}؞Fឣ/`MS=ګ'맫=]_>P}O y|̇1>i.ʼn@yѢsQQ;żyYXIS VYѹO|љ8UN1Wɲ,AGi#~m1v/\Lj_I~W$C>7•ُKNWYAey~GOe_ͿԔ zr(Oi<W$@t}lDhiy>Gus~yQsų8z".Cgf>tdhʁRt7 ϊeP<?(m'ɳ"DL jC~x,|>L tPݨ hKλp c4ou~G_@|+ŔO1SLXK4ŜOqb?NNxRm[3E/Fb}sXw#O+C~z8lJa?9l1G +##C;S[ (4JS_6)-K~9Qr#4֖4ż6}ujD1DXu|wJK4ŜK\q80)mn^9 ~%_xFyNz eND7MG|<|4JkiX+~*]3ׇh^`iz*;x)_x+hRb}}dP_c?z(b=yJYe<گ H>Opٔ&oO~\4JSyiP5OXSѦD˳Wq}:t*'+f9]e)M1զ/K+P]ןŜ OFi-Oy!\Z*J$nݺLDS%0K~*0 >(T`|/Q鿏){j:yeG`,&|A$@@ @/FkBA˖u<60< oNDbH9c}5_^pƦ7tx#]p Ao2{l5n-"G{cXQop?I> pb)#LC&Ͼpt]sZL7SqEE@@ \!&ģ=nAP ĉob^g';8Wƀ &`dcba1Ѩ,-^`R8^G牃'v:ď{Sqd#|q/]3 EpX4RvL{q'UA\k/iʾ%/ӒB-ĒAJfwcOC/>AN@ $pM؆%[ΡwM6 r;]4kèX7F9qzۯ}iWi] !<){|EWFלZԤ<1RvbpTQ?f><5*Ne6` ضz6JWW7Q&lWZH9ȾW.3(tMʢ]ΨV2;Y_\_ 6׸au9; ĝƵa^?Vla[4-ʳ.hZ6ށs΍QV!{*-MS[4 ʫߌcmZGС{ e,E9DKtf'֬=qs%,i]'QkNd܃zMQCk˾ªUX9^?4 *xdTD$y}yeѢ[7JnW~]ۙjlX3mhЦ WS8@"zs697OeHy U?bՑHTi7 .Ŗ'ڢʝq>0y aexY vϷ9~̪ Xwm5d>~^ n.x ư*` >>MN®]?WJWNwq˦Yv;oyФzJ7߸7Ԏ]7Fӓ^.hȷl nh՟ͧa&Y?4RquЯKA*lCnt&_K[ФJ >Y׌?nDow.oxcɋm3N>y-J3T ѿnK2.VlMD$Iˋ(~ד0 Q}솛 mݏ$ƬCY:0r`|9uF\x6A.xwmIF7\)}sWdX?~ί8:Fkga޷N\bAgl_.Z?y)߬CdD%=q>qv g?`OJyr"^SUD,@F=*U,jUbfH=rGgGHH^CX3D mm D8"T&lLa;#>[1lw6l K{-}yC?cOv5R.Ebn~n{B}_y} 8Q8up.9;"%(vѥq)jnNy+{|U_rb/%"OStmlEIfi1V 긑}lu@lkxNLKl>,m(^b}[gG|t'Ju:!XuL # {&htW d8P}leǮQQp4Z|gK@@ G܊~iܚܿ&ۿRߥ߉Wrj ̉ oݟ8-ރvmxtyEdL{,)؊ۡxU_Hj;nZZ=sAJx$]3R`7$^_[ ?-ݨLt+'Y\+cXJ'~Ņ]QmbܭYzڰTo0lœO|%{x0vb_l.g]M't.j: KmmL`<{*:l\$/Sr 8O#s~ڠ`%oЂ𲺤A{8tP^C{ hw ΧM1JnWo$}>8ՇkKwCSQ~ ߃5CmYmّ\qt/굈2%\/C! @ ͜9S6]ܱ kk1ʵ 4vΝ<\Z(O/, 832qt<{zgs@llvDĠ"ʡ+tOǻ$3ሌeػ8No{$%%uk{lR" \ `Z] gr?3_-Ö*>bn޳ sb nFug4Zi63Ƙ:YOHU}>f^tFȯ$hIٸ*hCAv&ΰKjqX_\ƘWk o4_SwhE;?I&Lp^V.8!c/p?”-_ѱ_^G4*V99v 8OxV'<3Ϳ+&Vңh ˉLabj '6L>Aּ$*?ʉ@@ W6 t05u͇ ZSMㅺW}b۞(WWJu}c_lz|@@ %OLDzSZх @@ @@ BM6-~]7o./W`y gv@勁J7T`|/Q4_SiD#|O#ӃXd.%nE@@ +w)ؿkmۆ#w!=&lG3`}JiN%f<+SW'YFbbzİӑK۾Pף7yξQ= E21mlz+osOVaXZ4ş}L2T|t" 9A |xj KxDk%Gp+lNNngcbu#~|Jnoir-SF}G8k´r4"ER !C;[:K_憒a*m"_O=SP$0 >SiD>l;FQvÎ^츖QRp#dL>G%FA 1,.|U5lǚ'σ،*ma='ѨQ.5yj>._jĩ `~P)b5~Hf(Tg͉t})w-D)\[~N6nHHEANG[q>ʯLɈ}Ͼju~3b`uq; VL;MW|]~F^_c'[Ȝ[r%DFv4m52Gþ CBb'ٵDFDFsFS1skUQ#3LmKXy/NX SrL$@@ Z%Gl}B|{h_..${t8pOZj6GV4xctKXڤ:J '93v]=?R51)KXBimg7G7fL`lDW%)gGU腈{]pM8 _+"ct|1f\ ,coT5BybH57kTx+^IfvՌa\'k!,-ߎV~F4D#}N,آ\|H,پ0_jC?};6EpY {$@@  Ÿ{|2?OG~o04=NH֊JфZ)HSSiBٮa„ /H lØ!..N>슸Mmt)`P)DW0m:9QD\3|*߅|F‘`ku))?1AYJN],o&BSh7xn)Z. ' {Yki*Mͤc- ʸ71gLԳ5.-?ҭtZ\34^%S >&r4\")G@@Nn'Secۄ9Yf/NY`cg;{}{?T8hGsG=x}" >A/K7zywv+0c<+/.leX ۫O= SI5B*t[ܴ'Gԁ?f?F_ fvh0U=5?URtșOÙ1S iX@vz%SSX2ᤂWnd P>Ӡ-tz;|&앎l>uLٮ|¯ԾM=!dNL1e&܇{~إk߉٪jR"P6';YѠq[4s\lyvBjxA}yx#uo:/H 'KFyDt둏-}cdLװ[*0<Z^;B"9X]lO)u'&X˯bŚWkyC=`-tQgXİsX]Ad$cj[ZejH8ivzqЩu%RsXqO|TWɕzjiN1՘Gcn!"@IC?OتhXE a&Z]zʕxufNdI#*ժ3ȲьK%V.Y1\bj^O4RJSUIIIhݺ[1)LJBa mLsgf*R"Y;ܶ3qvS^7|IBF+/0hn@yPUc5{_(?uGdjb _rJ"^4jӠf.H`jOa f^F`jOabjFzrb_(0'+6rש[-DښYVU`l* ,+Cn8GģJm_c.71 ̺jx|k~Odr L-x(nFlQs#b} S @@ `-zs~ABBn Xӱ_S4Lݮ&R@@ :3?ƚ`ق92imǂ]1;8_^M0_fC`Ρ3 6UކqumKx~y/q7~77PE#4j đ?@IDATFY_ۡOvnw?{< W^g*qh{&N\V_2 Wu!-X!MQ%,}no#'=5m3uw%%%3wbHN^TnopO[~ 6Be/9)GU@9fS|f~F}&4Ƅ^#!Db؜=&]Y/T_f~/QM @;N^Ȗ$@*( ~?Ұa#vrߐLrW҃4rƳt5g\ԌIhtVqHcijU:n' 3| a7GɆҊ JV։4I*Í"5ͬMYʓv]Z(g@Ws)Ù!/ wQL@9NfrgLV()}ѷLy2l@O9S~*IOI|$CV#ZJƟPXc/a,yPo: ?U3j}L LT`|/Q鿏)cĎx;eG#vTa>d:89{IjY\(ks>6/ dc3ZbT\㛶m\lDF%,X|9~ۗZJ8p|k\9}?$+˫cW"d)+YU`j' | aJXjC:-pN?p*phЭVϱ+*:>h۽.^tmp|?g[IŅLM/)]"RbxY;l6).ϱ 43qÃ{P&cSv}eoS.$aA Vށ߿-cw?rlh]`U:L~~}z|?VȉX YR9:D|ļC|1%ytmR͙ ݮp@m.&2tw%<#[~ {@_sL?7?ʹ2F~h\`pf#D_F}X &~7vlj24̽fOZ7BX[䷜)z*Zw$]∆ϖ&}z>^> R (c c?~\_U/K?-|N @@kW_Cq)`o`U,S/Nw Cdn0$bO%Dj~TڿP}0a. RB`xm;xfGrq}4"'˚t)Brn  f؟zJ"IW0m;9a"׫Pdcܾ]0i"HdLLea0|gGbԓ،f,[l/5#)mXy4JD;V(#uFu|&tj|Wb4L='@@ 0F5.ͻ5wR2٤\VCw珡҈l8i]ؠ+d:^cT{VA~HЯLʱ_a4Ԑ},+/a7 މAkR1& ofeؒخYsг*AbL&}Lt㹙g+5jn{X1Lxۓ` ?鄇INj-jES2nxM̙3/lgˆt+*ЎzS7"f5zywvڱ0]7&]| ݿ&6u۫O JgYڵ1ht3^2]rM=1?nj?G11rX'*T6c=?RoGv53K=)i}wG^Н}n`Xi_D^*o&'Tt$La槰cɠnvr7VWMvnR$1e .S6!),~᧩偩!%G@@ !w>W镡oI'~n|7_qn̎d4_Hv`{`ެ[/!m~? I+xZ˘l}ȗ%-V 7ҬMp^*Kxw٩TpTCc9k.Zd}lS){. vO}IIj%d&䅩i϶Ik LIFcO4~zL~᧐j_zLD}鿏@5~*0 >#/rn@Kᱨ_;/^,S138zXr%q 0GRCjnc?`K@x')K@ՠS:`҉:MJJB֭C#üMqvfTJr \nhc GdjֶL\z2 LF::JIIԙڦxSH}d L @@ *[R>Ysb)jw**6Eo'4@@ (3ww&EScǎ3@@ @6m[=hРY2o޼~_7h0$(е /7T`|/Q4_SiD#|O#;_c!Q @@ !hO{qT R2.xfoj1 abr]r8K2fk+(r~z OM_-嬍_#11Q=FbH{gm_c(Ӂћe`Ǟe8zklNQc۹@0X8m)79G9|́HÒ)jN_KM6cR&7֣e`jVzISm?Ǩ'-~:F-ŦʸT~xT.dbSL鳾40d0>RHv} _75O )ǴA@1Gk}~79`;r>رnW`W0WWg-s 2> g겷\]tޟ_K\6oBƵQֽULvCZY)qӽp;U;WC0q"gy w'#1hch.O]Jw!]o&ׁ֟{O[6lm2} gdc] mIglRW5߬ece0Q"vI91,{sLaV^{R"0eQ5FIǒW1ꤜ)m%:7V֘_0*yg4Hי]_O[t4,= תWia/@@ :@ӑiذaqW7. xb!6deI9i.;9,gkθsc鬜㐎9$id)<tNsgLII@˜5n9 ݥiUEjY%s8>q r?"e83%@=ӳ-Sg8X('Q;6'K[/IS}L.NxoCV#ZJ)϶Re``<~wfzOnTX*ylkEGX( L2"~ꏿ L%)ߑ%]t]}Y>9oY4x LG 9KɎGq;zZv4bGvIJ#:~|1o#"<{j 2+ZE,Ž5Oމ9Lӱ-1U ⛶m\lEF%82X|9~ۗY&8Y~5nB!P&NYbLw?gPklM|@KJ%r5ćGcumR|x9nދӮ/Y~x7U$Ѡ['࣭8cWT&tb}Xr%DFv4m-c` q[ ,3L- cF-Gַ!bɲk6 m8~>şfgvlߌ=ذzvz]@c9SfTXt,Jyck+AK@@ 9 t|6DÆH}>>=>肟NB+^A,{, X!x qnz k?|]TG*w9a#x5$&鷬6TadeƗۢi!j.Ϊ䗚OƎMQ-b8~7Omg7G7f`lDWQSmZ=;ފWYFxC0 j+Ci!{w4|F)C0v=iv\ a9l6S)DU腈{]pM8 _[$Fg-A⏿C|lێ?^킪?R1fND@# O.|jD?Ú36ĞZEߙ'c5Cݿ #ZQ'bO%DO]Ä 0u_3k/?B\\|냥q ndOa?FVtK_[mvwi~m:!S }s&\ɑɘ6_ oE+/!WSuioIhnK yս7K4hMi4Tnm ) =yC 7tUT>%twWizS)}4mve[%SAN15k+UDSVw+Fmz7>Y!s<+KᱩXS>뉩;_20U)ed2'{*2AW@,0 ~#LG YKD 4uǻ/G+;鯢&;SuH>NCw&Fw{ȼvfnJ!m~? I+>냖ps~Yl8^c+k 4Y;SZ tZ /8s/e}l)jǎ}'Ɖ߻ةw7V6&KIL{O^jS#aR&'KU4DzM*1Y/LM ig')70%pXrX`J]4 0K~cʮ~Mm|̘5!EECMvQ+W?MD8PG>h%P+> Ϥ%bj`)Dzj [Nlj+?)) [X1:8GdoLV6 oW!~^^ֶL\ajV% S=tn)|TdEq׸T0g05S__0tF`'[`JLn?(#0 /Ol6(9/f)C919q0Yd 9D?{wD6rPlQPPW-/ x * UʧrVn如 G9 =4i&iڦ&}$33l;jX\]!&[ ʡJzRP$;K[$.ģ8; 1mHh)zi_ɥ0a3+Oc+J}6vMwϲ*^m/K(@ xW՟W 4|}.>ʚ\i~[̑(P<|eaK.(@ P(@ b;օ;44muݦT wp{gl{)M/ϑ)M/ϱSmrrK)@ P(@ P&cOnzbo~%A1-gN|v;G33gWNTi4!xg9ۅ袱㛏1f\=ax? s r9lpo0y?QuwMo P׫X߁3G}4֍1ZX-ªw2X|\XTTkZX7`q?l2>p2ޙ-]E6vFS<N}!<)v7O66px(@ x5V.[eWNeGBvǤRb,lI}[c>-sIH=* /yE]6EʽĭKK|OڷD˖!ܪ1*;xdGNBr{pؾncv:lF`d^qyppBm=ehJmX7~zz6t̛ mk=׹çM1x}pqd_<s@-yq \%ٗ`gzD܃I-'xR,h}_fyѠ!u3.}:w J ֡ l!Dq0}żxȴ3SFLm`L89PLQyLģb3(=sױ}%ILbc/H.JϩLq oHf=dedHY4NےsSV )]J̔#IZ3J?*a)Kñl)r$#jA/iU5(#&Q2JSZo D+8/9v1liTduEԇm(;YPW")|\|{cGI̐e-m$,c ژ^KH0e>(uoYl5f19)wVkYoYaZж$VRxLQg RfϖّҚ\\=i=5_Mi~֛D/^#kxūx/!~3sfu .'Z/|}s[~:lBgxʢX2!UC+qH95Nk7oSqVG2qi;,3؊b 5rَ GF!l$;)xǜ|Yx{tm4:tU@Ecόw os-B ظZVBc?2̴bƞ6öw,-2pV2Fz1k~y- N.{R2tyηxPaZ |}o \p?~2!rҘKYɭa;t#N9On| \/DQ~*N:Ð= @c ȲmaJًx#v:5U_xX nIt}8vƃ6bjw|PجU{ʘ=Gst?~1& }s,#XP', j,ѭ?Q%WXǜfl]{Q WyLw6"vojݱA\M=cg69amqUV{:7)@ P.`n@}aaa嗅߾_nT ~@W7n$K(gFvm̘1s)j+}-"**:/7Zxb Uls|pwB͘N4Su#׷39^v# pT/?=klL~#xJ'Nh" 85j  Lnh)GnZ #a8Bvq]6g_ƒO>udZmKoo25G>yۋ0̅uaZΠ(@ xeOFhEލK5nBCDrVHoMX" Fgyi Р Zivyw|+Bdw;E~8 RóS!7i_vl;ک0yDE;Gz6nܸ?;A-=~ͥZD;>Sk61xxh(+ Ч%7]*l)QW/ͳpRzƵn]y?*u7 cy^xw BWy tnjS&]0 5O9bP0(`8Hq[Mα6y{Ԅl *Sg+og+`a(@O063r|: 1'Db펋JcNwsf j8ũ$70x>jzWZ ̼w2ruxp~i39lW=ZI_Bڝ=1d DvW^MxAwqn V;8"AkL[BK'Y<>VBtw0gxއ36ZY:1ƻu8(3H]78"Z {$fg0MD aUgb]U(j&V1Ũ..MwMh7^98[^ot6,_IW2ڔռl4gg8at(ƺ;WM;C3F0>o\牃SG_?լ>{7FX=F7BYɂ868SFVE#!x[=|f_6嫣`շ ·>RaL[AW+~`l[`c^clm)۔T+oM`:l(@ȏjuЋ:*AqGDD^z%"+ HE_ s k. RCX iׁ;*؈D NC*c3pὦVxfP*`U,G[xZU؎.Rj`2_0WvvLQۙw:p0ώwA0MX#s`Lb9HJS0.F$%^r#8C.)OyZ2҉3w'jd$ڿHA4ܛˢdP] ʢJzRP$3/ќNm4.Z5Ηﻥ5h:g ΅2- ?홂[?ys.1nfL PeT꜈Cޫ~=,6JFs5)@Swjyr3Σ(@  \s.]hK P(@ P(3;vt whh*뺍0_F/i>bд؄2i>bд؄2i>bд؄2i>bд؄2i>b699؅c(@ P(@O0>ZOZpt*!gbzϞ fȿ3tߥB.q^\sGD=r2'؊Velv7ycT?ĕ؃4f ˇ}j^D;[VOSzػ Xx&ϴhe(v!o27l=q-:u+D>e(@ U@~#?K\LnQ9 R!EPڔ"'3Cm ʖ6wӒD@1kI+Eϔv>.Η ZeS;R>[BfG:BCΔ+FEʿcIܮ%$Jg XFp$s;렼dn'ڈzc D[砎]$Sg˿oAͅ O2ͿVݚߝ4uszzMEcx5DRꈗtR? tVĉ?[6?cDdg8E$aˌm((LP@@9lc%ݵf96oޅ#Sg%s|jCvz1<>=,F|ѼGW`Ag^xǧߟ\}_^ CA+'LV̭ٞbƞt6öw,D}9 ܸDB<$" r7L!& 6)섳߷\0O P( 茋^X֬a姳sy@<~|e6Bbb#,g%Y,| \/DQ~*Y:Ð= @cC<.myU@3̵qGj1%+9aQwv|^n g'#o=ʹ^9*'ͻ`8￳{fT " Kً-c\t0ދjdnʡbv/cu\#>~=A=hf:6a?G ն@miidV6K08."x⧓z8G P#4˗S[ ,, _%_'$)DP^</1"<\]4v#qXǴ gYi׆ݟ30w?֊ߋ/긣XjA+)t^Z~-Q9+krءu*~z8އݩ٘~W]5wtmr%,Uz_S`e(|b/F*qr/ p5tD'#H#0`xg 3ݻx[!YR ~{xBU~hf/^)3 a1|iǡEe ر>v} áϺ][oacp`˃& XO]׹ x(@Jj [8S,QQQ8W=$s%XCibrlwxUDhKܴhut5[t)4Nݱ;PI*bO#i 㐝Sbomk)8g13WzOnGkUbwV4d%Dum)2W:㙙Kz #Gőj)2JMB5kk#//"BG8/a69ͫ~g|$9 `]#~7pf=k>Ho ΨWM;C3FMya|&ߜN .Wj2~/gVdiR?sO,%1j._ο`=z/d1U[#wޭrm&uݳq[O‚Qj䁋qrж]q;MuL6Ehx];krc?m ](v^>e(mUr5ЬiYVBrq!抓;\秊K/Rcz\iZeK…F*O7uw*B:XNlTċ;DFFCͦLw C*c3p|fSVn͠T\96|I{)XV`qoЫL=XH3uqy : \`y"WZR jQ7j]vnZainʆVn F kh&Egܧ8C.)OyZ2HD_9w[JCjxAM(IhlZP*5)$ϕ(ؕL@gNcGkN1֫K.? +77s!~nǞjWϾ6@T-heT;?uMM6J P%!`n@+KܸQa@Yh\q3 ЭbŋOѭhnLE P0 h.\t6K.͂)@ P(@ P7Mcǎu u[ýz]!ɨ}$A)fM h'9M3vPDbINS;( i1$b699Ecr P(@ P LGz% Y ̑<߃5(@ P(@ 0o]>+Sѓ[6 P(@ P@067g@ G]P]4oʌ J P(@ P^) ,ٸ TEo@`|4<jS(@ PZ|ysNu\9H|<b<<(@ P(@ P@0V'|o`+̵(@ P(`i@_}Na`\D P(@ PQ܀K?s:]F6 P(@ PE܀/ױ<σD(@ P(@ P;7C ,l8p5Qy0\Xk P(@ Pp$`n@k2.#fGN (@ P(@/0wrV(@ P(T@pB/K.Nș(@ P(@$бcI%4=ϜAƬ(@ P(@ PeU@\`Rpڝk A9Z;(@ P(&]!'oفPix InZ(@ P(@ ]^F@ReA _֍%(@ P(@ M+ W/_i_-@Ґ㶅0# P(@ P@Y06jhr vsYNY~ P(@ P(… .]@1%(@ P(@ Pd:v8I%^+C+)OYP!<<:tpOfETdGS_9r=ܟ#S_9r=ܟcId9R(@ P? Fw#g7)@ P(@ P&_)Իq3D¥F6Wzsi(@ P(@ PоAU9G~ۉL\ܸ9uB P(@ P^'\v7so >ˌPNl16s(@ P(uJ7*{ aHTBxὕ0AuA"?M(@ P(@ P&'o;͛V%|wD'{5@7(@ P(@E@m@^ޟR כo˄(@ P(@ PJ:ǿj!]ρ6ժ 7!3x1#(@ P(@Y؅[s篣تdv4 P(@ PJZrSl;f`x8"R10o4+Ri0oy8]Lni79yE?ḾyE?M͡ڈ*ִF>muu[^H… so^[ll,߿{WzS΍4usz^ӒkCCCVptm1# P;jԨTܑ999]6\(@ P v_,w@ P(@ Ps̔xDElI?3(@ P(@/] 9~]uPԪܘ?1s. / gѮ%c(@ P(@o Fʨh~s: HWaI@9M.+(@ P(@ PFry>gS7gk|Wg4;hkHy(eWniz9 )HdK лE.^ډ?;U\1;(@ P(@ P(NXKl f711tz Wʁ(@ P(ڰ0sųJRKK^[5qR9G(@ P(@ P&WgM5\>{ʉG\#5ې/(@ P(@ P$TogoZXW P(CJbuEVW#[A P h#""ny!X Jߕд ]+G|uGoaZH\"j ÄT||G|)5)?KzXneSp,+,up,P,se.GڵKkX[$`8~>fS*&cɇd6jB+Gʺv/u5^5)QQg>J9o{SJb u[%ݖ3CNu) HdeQ\W/?J:f; | 2R΢} LE@,+@NN$I*VLYkGǦ+БPKWbEcR;̾88.;x?n6.o7xTNsfr,. v_|K+ŅS8~W2@L~:=jۈ(@ x/͍硫awaRDMO¶Q1eV[URtN"NSA;Ӕ^VYZX2'x;?s5#)OcՒLe+Zծ ƿ0?jIxMoF{_[];[/Z≱r#qFU]>[?,W+$F/قK9j_fbРxKFŐQ괻~1p(yXF4~|gRחo3/^PN5+T#"۬*1_JmX (@&EOJ$bxVBdD\^=F_ضԟbq2r ޗ.(K\K;>˚cM^;C?Z&bݘg7B$??]<0z.nmS:-)j!,4RR^a2#."%!0bi%+jǷ+"\7b8,Lq}.\P@8P3(<)Z,*;;%I Ҫb3*2U)OLK{r+X8v1la%]Oن4OkKZuലrHIB,w9?ʒS԰Q$1:[I\nSQ6˴Ct"EQ)//ϠgL!}tJY b_6[?N8f͚\}i^WoV؎ض  Iڙo ׼ |^r:u[z?4R7M5#xxKa[.'l<(*zi[i9=Kqƌr.V]\nD)c,a<0Pz=iY#5lE>Kc_c*r9db6uGg!" Rf[=>A|'gGbN])fur1BlxM >q'~O;~i8SeN)Oc,yfp@*}!?G> .h6"gʈa҆ˋKbt,LV뜮ػ^i{%(@ P߯lSеbk+St5ἴ V3ſ+[J\Dl&baJJm9 Z6 x+mr,^đ#b׾ŏ`>8~MMQr.,.ʢ'r)Y:4yENOaOv 6hk?=ȝoNUHbQ/n.ݱl\W?/cMz}OcfuTW)!qoga:n/^<_?eY%lߠ(7)ڪ#^MD`ӊZutQ>C=W= d;vҽ۩H cQhl,y,|idӔP3k۸g`ML4|p)?~R>G|,Ѱ@R+ 6rX'3E٠:,.{v>uoQ v MeR8UępzffՌN]s*}2Ή LFoV4Aqlߊ'(sf՟ 0m v4DőK;ՆupR=Rk)p1e&VN#^mt7^ӟQĵmjS^/YM)9A P^@wQjޛ|uz<̵uSTeC*'o?=4@ǸQ#@ V!l quXZkvgo-5/xvq%nY:`/|2_RF; 1?~;48h _}?SGe/Qo 7+ip0P3K:?Or1_6Qo-j}xoAkuZXS{=px$Y {|E/D׶;p%P2F623q?Uj8P-]L4b٥-lﲒfQ6g+ZJbL *)gh .Q7Aw!h.JfG1/MQ5|O/90V>N^ %0.Sgpݸ]|M0k:%z\ ./C)P<˿|r,(uƃ.8r]ONm%v%Vg/nv׳-|B}JJDkY7ho71vV.b;Vv;1/A\%yO!Ex[G)מ@Wy# ooрIaH27DI_Sg޿pz} {ox-. Yυ;84iv ⥋0Zο]kQ P(0n_(^C?{ѣs'YrO,ZiHb̀+3*yf|Y%v#(Jt뉦সφ/m>SB}_º ,A|k1|>FuWq٬E}"hr'4}>¼~ zQFiu>.ߘ=/W zY0TΜkO|{'0ڊcy|Ҕ?tħ#]t MU$ !S葚ƙjS c{r]'_߀v^YX BKjdο-[VTl :A Jس!7u$LCǸ P3Sc6-O!iS.Ri|px'PyZǬ BGk 8:?ߏ;_ժ\V((@  .\-*eUt}vM}!R'jXaQV]qd5^YxRfPêit̙mbMCгK0>=clg:ȳB)ʹV!MHgl͓2_kl7@WxG6;S A-[xY~Z0nUЭ]o>$w7=!kqVz3GeX ڲk_㈮Z7e~Z oA-I  42Cu1?)Pt%_bC5%in,r ߛ!7aOHV!fT :yoR .SB9Ԇ.B吡j#6odMkyZ5Pјd^^ qBi֓kjeɽQoP囮<}W KcZtzsڠ;5&9K<^#lbӿ|0^3xQG6|< uW}?n^0| Fʴ#5u[R@h$3chQȡB-ʼ;_ȴoh.%`Hfu{,-{.ݧ~}=[{ ]K0?'30>Z%&p|IKeg,,CI1_QG(%Wl(i ռD{ϓNQ}tJ~3ۭ<Ҧ Kz3ExvT4E`|U4Y%q3-7_|y!K@|@j"?W+t zv```lW,})K岲I,SWYӵd.Ӏ뉩bu9u|E]) PnjWl E׎rxyp@i)b1}|aDoaJYa]u*x+֪%eJU`gUyRUG)@ P#BMrm*W%]{'ùA30|O-fUq#_8-J,W[]eF W=P* 3R*sw hm `P\xw˗Gp $( PRQxԮ]T(1rXq ֥M JȺ"A,8+ZםUF4(@ P(@ Pk,7f/f/@rн{U5(((@ P(@ P ۶ĬUwV<W.\BFmNQ(@ PI@&XMG|J:V1X.@skV^/.n ݚz J P(@ P0 hiXꇎ>0]mSTߖl@,I P(@ P^' 3W:;!Řo nm;\K@T\m(@ P(@ P^"%WezEgdCVayo˕+g7)@ PVVZhX!22һXxԮ]a; P%.J\}mhh۾pyoNmЬUOgyy:a]-.\@ݺugLh'.(@ P"`xX%P뜜HW}G2 (P%&''7,A< KBd/Vk,SȴLԩz%nuԱA(@ znowP|2SM!oLF'С}, 9YEL 4lWkn 5[ƻXzZ[ZT)2(@!~X PpveW^ƞXGd(OcΕ#Ĭ~!n"x0bc;r1]z2D*B(@R!~X Ppv@pmeT3` $|? lKą+D-`KhPQDi짡\=fG P-vs(Pm~F. ѩţprR&u+$s`P(P/KO PZzckP4}y@ q_ m NP(@ Pʈrh7MԱZ\7 Ia(@ P(@ۀ1dF/4u⹑b8W$(@ P(@ ЦEo:SQrTA?pNC4OgwBEqKn(@ P(@/jM}m#~n8Zߪnd2(@ P(ڰ0AvB43$t=uנ7VB6.\F9&G(@ P(@ P%W3+FIJCB6ン(@ P(UZ`f6jᅬ\ȟ(@ Pln=e(@ *p5.Qʴ@dzc2]RRxԮ]Š(@ (6444^ĔLF P(y:Bd 9992/KjjR@Y(699,Z(@ P(@*LGhC7mQ.'Jש 7h\(@ P()S*;v(g J)3#S(ڹK!ǯ ^y'>_KT"}ǽ;K}}X@ P(T@n~hݺxfY^ݰ'O*lDa (@2) !\[4[xe,4(@ P.ЪU"5ݍ(Am$ұ{I85돉aLDYhtg2VcxbP(PFN:U%pG% -1(PM ~='AuGEZ_?8hC4֌ЯU-g1w3׸X y i Pʒ@)}v={[(ʲ bF.Nw, Ÿ@i1'f7Vj9طl9RN'SYX8^|]o$vǗo4.ƠQ!d*|F|"qx{\~~*;:p2Oĉtø%=+8O.F,T^.(PZjqEI4(@iׯPEnn. YevBLR,~}9К A8tX,р.e6c.4ٴM̞L=2&_ſA۶+yt<'E6}D7z*ϝWճ΃B3O\ hh(@ P& p8 P(imXXy ш6O#UOFس@9q8fV&άE(Fm;`0[`pNx⊄g'Xܵ2v)o"_#;/EnƝKTn.B@ YqpirL=vNU 4uWb~[h\C"lY8,@ P@Yv,{,;(@ 8p|.i0#AN'gBzl*terwq@Y (dz %nҷŲW@Q<^/φ9P DFF:yGڵ **V(@(64TZB#2ǔ)SD9YH P ϻ: trrrG1yK~X` no Åv_pAW*TB;z(qvnU(@ P( N*bތeE9Hc@Raʍ,@f#F(@ P a+?(J3OV܀.b(@ hHVFEcY^(+wC7?g6\.Q؝þPVFfu3Y)W؃#E.gM1V./ d |/_BfPy_dgݸ2)@ P(Pm0 & 0]nǩ!5hhUcW 'Mٳb,n(@ P, e[fY)P|,f}$p-o:1">BF x{WˊQܬn7k9 {`ٻv޽{L{6K@xA[w>M4F!&(@ Pn@arڕ]N[nP;| n m^$MG|J:V*~󸠭&URyN%A8P(X]-F<o(@ 4j=+{Æ /LL %G[qQo: q@1ڴ t0LQ a(@ P(#F@ U+V(I6lX5i+BEaaaEg'D#:#5EO].UP'1W8B P lkNE P(.yϞ=6]i;d_@oNV9\ҖRz  6;\(.`nV7k^=rvˬmڦeKj,sCM4wDAQA= :=39yϻ|Ιyy P(@ P 8DL( 36ڳ~(@ P(@'8'0!& ыzvc2>pr=2KEh6ЛwÿYqs P#DG @ff&xKP&(Jhh166Ҵ NAa*/_x8GӐo/x\/ip(@ Pݔە0r(8C P#.D<9 #PmRvvvmL"(SFg%8kp{@<>k8qOvxTm YexG̙3U|:gM .PtVZCq,vcv lYLA!wv?u ^827ۗ[ֻTtч%oV|$ēeh/z՜ #m3[U!aI,STܕ˶.fz[t(G˲K/vgv=o͛Y#:ku1Mt|9S!5CG4 bI= >̋!hjzee!M xγ>/i#=5į 𗳶=|ܞо`.22y޽;BBBbP] [tں:GwÝVlkzd<닀}>o̹w 1c%]R0CƫKll:Ei $9yqMҽuB_]۰OoݮFȈv{W4Uk<;*Y8sUkwrT]1y[2w`BĂ/azW[g&Mj2\~o%&;Ũ{uo^G9{Mχ6-r@7bɯD(w=$1߆x:ȸ$futr>yV[rH]Knw[ D.8U;NmwNb~q bv0V6oHgӥ>cP4" Yh(@`;U bHV>>ob;81ve4 auL7"kddQ2o+6I/4gy.SxLYl n_,C^`ȉc'i6%e(@ PN w(@ s1 L/Uƀ=i Wqy2HtJai;iW ^xo&:{vj(c[, zw9Ծަmȝx3&1?%ńS).e $ ;5(@z%v^.@nǯI?rrUM?KG4%_xnAx 8|}tbP"1)RqXUfmSw6sx|O$OsުG hyN(@ P(ҍ1[1KE5g;ԠXxj}-/| pY<7?5nj&ǪS}t<9yש_t2wB܂o n E P(@ PS' LZ^h<[՚{X՛*h.c/62U;y@̘|ٛ(@ P*?קۘ|tT%Gn@t(PMW>(@ SoQ24I1>g?|=,P _qt:rN Pp$ ~]haP4/̒e2\(@ Pn"NJJtI\ױktJtnRbW[ULs1E<N!_KqCTbPpo>MQ2=Y6(@ Pp pۋ%C_\b@(@ T"0LtxoNFqv%;c9،ų 0߃+!՜(@ PHqqqnS껀N5 CZKx2|FLna(̦. P(p]œL>t.!;d,AVAX0^l0fN P^\nX8|\lZlj[!%R;M v몲p(@ x4{}CNnܗXrb xkL P.tmm~BW̉_pf(@ P@H)XD>m:`׻`}-*0U P tV5<'(@ PU@ DTqֈG~z `v~f)@ Z3OS8(nYiZ4k3Tqj4W"i~۩|`*h?.(#&C Pu`w @ P)qx_ (qv%;c9، E93!\ ѭvI}I+ yCU9صN!^<0xXoD';qrJy;O8~ٲʍߤMZ4h=;6>_9q=S_5C iX1{ 6&m܉Ї p$!Rpk@壱Ǜ#=zgΜ7 P@VСCE: Vk=(@*Yo^zrbuPuODlDL ޵ 3:\ bbblyϧ"5_xmq $}>Nь>pc<6͒!'6RӸ3; G8|g{Y)x['%eS@?+5p}b2) PUv_mYlۢKŤxAiZ“C0J\R\u-YrӂzL<6P}BHfʙݻ#$$\\@IDAT(@ P`a(@ T  ~7#W/.>b.bVF_-6F5έאbމ{yKV[U:Xme۰l"qy~Xnypر-+vke+u%|(@ PœL$%e`T8?ł+D P@ޞEW(@ P)6q_ѱ||;v ݉Ly'.S@y x~gooo^Xn4ƋG]܎&6oPc2柌jQ>Q.S(@*ˆc}UFN++w3_䍷p(@ T"&U(?]qeW!럯B`^}b (@ P]@]^ŧ;כ0`KǏ!U_>6)@ PN ]q22Q(@P_2=39y+J<9l8ģq ~{oD(@ PO#딧zVͥxf\FO(&=3 !8 gcg-;y.4D P(@ P 錬`H111ϧ"5_Q(̹bqs g-&g(@ P(@ P,„VY5yN}  ~( ={7޻c1> 5sOVL C 2\:SxUNc*l P(@ P.y;My[( Ê}O(~@/;ԏγs2b^O(@ P(@ 8)k{NJv ¢W8cw.71 s=YL IqqqnP (P䐙`-I P С@ 4LQx2d'7q7hDh7j>&axmRttt e<66־9 P DDDYoqFx!,9(@ D@#P˶D^NbhB"tͯcL}깧1,m~7{ɨm]=SIz0= P(@ P*1銕*dg!SpuaN&2a>n/BL؋pATeӁEYa5JxNh:o]w PzY| P4e:L6f_O>ޔNѣGq̙SVZCuZbm. ϫWY%bfu-vř(@h=^ #VG#K٫4o:wbho?݇ޏ _uep￑`"s*8kp{(=Q܊c£梜N|ek8)@ P@m}_:)^ejWeXC| #Sں W~ݷ(}렀]\%߶Ey7t|%(cn(Li:1r?B/h(d<{3&_ŅO`Ѹ(@ITVlK3A~}K,#(@ 8)P|E#^'\]d'G5PnPb_h?Y8G PA@EI*[ q_Nه=cE;_S@Xs#Xh:@*-p`&&;NdaHGe3[ wBQ@Kbmx!S"Lj3DP63ⷘV7Q㋬ų +ENSa(@"bxBqŸCl8FܻhtOƚc\s䆕0N723Ϯ)N~t?=ELÚEZ'ً# ;x0~],,(@ \]@ڤUar~.gӱR6+~^5 Ûgc+Obb0xr<գSmRvvv5(@ P(@ PS<8BoP .V&(y;My[(\wh2OE8\Gy;Vc=C wV_ {2(@ P(@ P$ dfոp?zNه=cB;_&!,9xMC G$CPyW'*$ǴUt};Ndr͛%ϼmȱ<$}'rmކ-`q;e(@ P(@wh1`o*̐g1j Kem#gXc䆕0N_̳kL%eF?:LÚ5k~KamL1s0~{rzvɅ1y@E?tR$(@ P(p}Z ŕq PUޭpgSu1 D.KnoCס=.TEAcCDZ".Xe Jtꮈ WIW!;:LF=0O}zx,(@ P<\X EVBo?j,ρU;uF Y<ω֘a("7 ~rSYCDZ+ijhETI-KR&5WCR*b(@ P(@ P\6ܶ$iDٶdDX@\3zn\t'`(u2Ԓ){p FhY#]cV(@ P(@Pw6V CnZET:Cw[{,22w!.^R8Q(@ P$DC1bXŸ\ϭR#B.5DSMўzR(@ P,l7vc@dƂl`E#N0P(@ PM3W. )#l(@ P(@ P" %%%U,B P(@ PTV(@ P(@ TE@J|ƥ(@ [z[vw+xff&ݭX,(@ P&Pmˠ35MSjM ""F#dYj(PjݗJ P(@ P>RBB۠{h,e0 #,.7mztDK-}}s(@ P(@vnތ+(kô)C$`']R(*+jN-ݢ,(@ P(@ PԳc`Rg rbY(@ zo:>χ;73Q]gkp'q *  S(@ P^`(@ PRrR: u9 R.□*Ax>tX*֚iٶy5fX5xo< ,'›^m#(@ P^ ݯ(@ݿ_g QiEW M|ǜdѧă| 'q|q5=V<G9dŦp_qm?l:k0")@ P@1`2a\@ ݯsrfH x\a ‘s6O%{0k/i6;ΝAu ;uL-TH1cƘYUÒ2'#D7ߠwi_9 ԥknG Zs<.l:MzoD<[S?3W*:[pn`|\1H쇞a_*uV-;tmM\[?KU3IGV"iA }DžBK;G Zs<.ln`Kn}O %[kPnPݬ9V޾g`?hA }Džݢ_~Q ݯ =z]>nvn9)F<:g JKL]5y$u]RD1Њ42,(@ P M~Cۣ(@JO*1TXZ;ʥ0/iDB((@ Phl^e(@ xә(@ P(@ Plw9_+.S굀1nRLIiX P@Eh9U3$66[r3 P@ DDD~&h4=JCjR@=v_ Wɴ`RA&|"t:{SZu?*Va\%KX.~Ӽ}]*y*z/,/n!Jөּ/ rJzev|e@?lmG}E[liw֕Ms:Kr\=+WʱvNOX^I {丵+W.NQ:kGS ?/K'G.XzL6z_{a,{[F9YyIwDˉZs ˣpݩ bFzA.2Rz9 aOra<_l*ϓ/٦ )dh&7xc ou1+єAQJ)J}c%O',^la4SR~P`w㳽&Rf}&(j3Vq_ċ3x|8|.5UN_PUL֎'<6^$Y[ 9_->O,_!L٭azkQgt*_/))UHBxy߾}.L&IUFkl~[l@T}WzJaWWx)^wnތ,mCЙ.k~޽۰h[ጊ]'C Fڂj!J ={|ݺY#C<]#1Bċz[,&`U$JRbϱlth *gJh;`&6=kTDuT~3O(dUm_\c3 ʚy0L冏u|<cZJ&c?=;ㅿ`?>kbQ \i++z@RspT.AreroE$G޶隟҉p P2}v:_,[lݪ!SώI5݋]g]c?<|?!D pb=AK-ׇ@?A°r-b+E5hJZ?럍1JGc) ,ƣ *?9^-;uyˁCB+~1C#!.E5[aDGԀCxCo0Ft vWfUatB޼*gNzá).1i( i!zvжq:%k6R:f``'0 -gcABtw>r:<>pcr ɸkko7wv1Tl|cB)/CÓzBk[C_'r+4̛ve~ KE^6u-n ƜLc[8Lܖ,/)АYfv߹_G`^ :9)+T~ 3DT|C\),iԫI':cdv<; s]У8rd`{f@'oٿKo=eZz|R9ˏ}ek$z7n^{7oHl z`;,W#qm|BzZ=byW W\h7 TvZtx[ T-x졭(zc)%B>?8L?Z] Wiߊ{Μ9 cv2N8Dc2DŽ7Q}ﺌG@m V&b!zF"U+oH\X6u4 ~vjZ]:=g+}&N-](k|' T}vA)?}+v>}ij:C mؽ 4W_=/gv ~>V}MJ.^I#[-:2NHANnC{ojt~`9ŸX0D#.‡)t s>O.4o'}g@q1?[gX-g̹}qr[qqT\bpܔb[[E2sd}SOZ0t(ݺCblSNbb`s?dy-UiZ|).u7zJW8EےQCV ¾b]o?gʴmE&S'UVaebw_*TATD?eGTV` }uPkokT MicX\sVw-m(5,;\2ll{R3qDy_<]jDة493㴜ǯW!+qk$6%-3#\T'G^;-De1/kK> پKW!R[)[90~Zzr bNc(,fYVcRZN/Q+/,Kyq]YV‹$=Xv4W B"G CmUf~έ_#L>Nv:י8$<;\SG\UKt%՚ҾXt:U))9tAzeS+̙q|a"JeorcJ.T%NtڜTL\g8d0nVv=^*ݷk8tca╙s&3q$j]:[,^/1l[сG|~̸=Z[\P(@ P` .@СCիW RhZ^4ahZ^Ǐy"L&СCݛmM53Ʊt*4-yƱt*4-j7(f0mw忊 {U6׸qV1>>>i5ல MSU4&U6UpJ%,ɵW5(@ P($=Xv4W B"C,FVK/zQϜ7u: G P(@ P(/ ܼvc>O^gWQxJtm(@ P(@ xcpqf Nk ee#f}*92@ P(@ P)))骕-:Ǹ\I P(@ PhQ V(@ P(P?\ 溩K)Q(@ PjY[nyMd!A/^+,+ERttxw$TL4u@ShJS >E4uSqJS >E4uSTv}i"(@ P(@ P H P7o!TΫ8g !{Tbm40V(@ P(p-i͸"biӦ A#x6_f>6* P(@ PHc`/#&y/v5P4=n1o%zR(@ PQSA!4rOu 2u%إu)(@ P(@ P. ijhET DgZ)7Ě.bp(@ P(9͛qEwM~6e^bټuHSޢGZGN#ÚR(@ PJ Hc`/#&y/v ػ'ZA%P(¹Rr(@ P(9RrR: u9 wqBvAtj# nnK_9@)(@ P(@ P@W 5a"*(<,<>#19 P(@ P %A7pNQ'Cm6NCb)䈎5' P(@ P' ;Mz+Ƅ!7- BUĮt'p<9noUYFs(@ P(@ x䟶ˎABHd?tkCZܽ{E˻mݛ @=Qu(@ P(@n`C[hW_>Xa fL%lq9C P(@ P$)Fl3SpZǙxxRAj\<\kDS(@ Pg y6T P(@ P' HWVXVjS||g_UmSv ?`8vMMW4+hZmJ7,)RtQ.w1H4uSqzj8Vⳮ\ ںukW&ǴM]ДpmONk222pY~AEr4\"Sךf/EGGtYzL( -Z@B*""1 !`4vG(@ @mRvvU(@ P(@ u6?K9*({^lU(@ P(@ Ծsf\iӦ A }%r_@\0)@ P(@ P ͎=ᅩuvF֠xC Hh HqS8,XE P(@ P(/NNJGN9 EqֈG~z `vq(@ P > #^ӎdn?),nY8 wv=>3݋"YFB=?|f"왵.\@jj*_wT.V OC.L'\$n}b)P]Օv+RҒbbbl(Liщ.@ty=Y-Ee.[n] U+QS1qW d(@J yl>bm ęCw"IH6 !wQ8kp{(V<%Ƴ8saH%vANV@~=I.(T!!)I fr 9{q6uAmR'<ж#.W1(T*Saa!N:={W/(@!P\\cǎ!,,*:NJ ;YxhY47d& W*r`ft|G]E A.[/*[/wY7 }w u_~9Rq-égHF^Qg:+T*6iƹs`]E (HNNv!{'h1LvK6M-c|\>މȗ۩уT\3֜@`p-kFw`{ }#G]q?yh7E`;?`܄)h~ף̓5ϡ*M ˗ pc[VQ)wT?KU3IA\~9,s~%flhK.+jllryB>+hB"=Co_wz̔ˉYUܙ (@(>S Hsy8)| :X߿T-/>40~ R>3V7""\S%Y }5,UFN|}dqyf~ zb)@ P(@ Pc$=Xv4\W@IDATW B"g@(Oy ="LE[ʣkŊS(@ P H7oUn}pSPLzff}Fes.,mۀ3(@ P(@bbblU-LiEPsY\-IW3p3(@ P(@*pN]򂷏TV9z(@ P(@ Psʫn7fl "RZ*ZړK.eBFZ5q]'y@tn\_Y¾EO7],,Cξ/0dK8$?v1Ll~>Ә#pu hRc{7C.2Ț[Q XR_naa!uח>p¥tk>yJ^> =‡BdZBg-r ^yhÆ9އ^GF~Ua@@akzz:*HM(@ X} T21:-y| O5wAgG?^.a&9Z]3 P ݷ gj]@X88}cb0H_43B?wV+jγeԙu[G=YT)1 X|}~)Bں1p|- fί80AYO[Dv#5Tմ|&&&~ `CGONNGv߂+Ǫvߪ~ v~QkݗPxx2{F?ro?;w7(7MqA I P:8yzSz#-l4Z߂{aۀHq µ-f"ARomg3pNiVtKV/ (PlS6}I.!01U *;#q<110V]˜,/[Gck^*ܡkwOí#[a%sbA  A q^u,_3tؔ^&Ν/+nyZrWoghmo[YĂdYbh g&Md] B;97G^Ѯ@t.Yn^Zіmq]25mEp?g#,%f-4Ŋ)J)~ݯVJwA4n=1yx /(y[K.ţrlJTTURF15OuVuk(ZLht9998wI i0)"VY."li)|\+-4MM[ٴ|e2*(`Hr[QmfghmxRb/:|5kXoxoƺUR\G4tox+Tcϼ@}!G.}NLF+x73=mkW (@ ԉ:aۃHh :cLS=şڮlr[;-H,(Pi|231!HJ>C",j偟 jK@r3p1Kn(PmS:r{5t6hұLפ̪H~;Lkݺu7M{Dߔ/V-JZ֚Ը L|ӷ^BbfoG=9^<\͒ ^:ro.! V3 F P-,,q(*ԩS:Еm (.֘TC..[bhB4"~Dg_mc0: P(@ P@e%k yVθҠb{cg8"^-e =E+ (PVu:(@ P:}󫎪)W Tn $:5}lI@ cCq. FZjC dg]ZrFS'-fKq3 P(@ LhSU[~W[-uv5 H* Y(Eҹ ptrB Z1G) PB]! 7RJ*]mUURFSٍzh+}ͬe`f t (Ps_Fn)_tTV(N; aS [ȵorr2|||j-fL L|\.75_9ڸ,]5wqF/-pŌ(@KyV~KxTK,U0UٵKҋM7n*P~ӃE P(@ P-`U9޳gO}K1B:_dr54-),2@-UgRQNUǺ֘ȃQJ#:Zqh}{6 h6\=c,ą(@ PlL`˱$$djо MQǠZ:fp⋫''Iē#Bпs'|fMQOYլlhP(@ PMzL r2(IF;%il{E9c\ :̙ ێQ(@ Piwj,EgS`X>gVBax \]c<(OWz?0=o,[aA ~H.)R g7($Y !3S m}_+Kg>CLQ T² TÍ(@ X}O<o/ C/97^ƘGi|XZdM5t8(>o&>y5`LjѸ? vYgn̲>JiDL .g( rp5G<1ṛԽѢp:ŀf8ύ G~#<⍿1L %-\)i匫* bwGKݵ* ?O+fu+:ۍ.+-W.BA:td=<ѹK)LZll-kqg9)@3 73(+v)'6] m7O36cC%Fs~zmũ]w o[|9>\w2 9Wstna]#wN+l;c?tJplW].]1^ۮ,^_/]".Zsk['Jo!|':@Kc4R;<ڲ-r+- Jzz:*I(@ ԻzvNVT1Sa p8Qy5@2,3imRlw$ipIkmP[q²n 'Ë2_JBaV:t=ŋ s[8`;Ot8_ h|P;#(@ ؛}{qK ԒHѿ-;zތTP.3x H?]{ܢllڢ",bo(}6=}w߿T9lAA?.糰[X8^6}I ĵ{ee81Kt3J+7v-,*`_ 7Q-1D\"T ;d3'qQ?yib4q.(@9 sOgm@ ?2{W S \ʍVt(׷Wz?0}˖eXwP<-S o7(h΀w!(@ P' EиiCAe'),⍡&Gs#_yd P{O< 矇ab[*"O\ 5wNȑcR>._G$,zX PJa8t+gb峱q,Q ϕQXv!ǘ>~;ƭ-=IkO o㎖Ju~tO ÷ B\C||Uah”T+: cƵ8֢0a>7 I]@%xv&/^C{z .@Z19p0 Gʎ];=V=⳶{Ki936G#ômh8\&">-=ħNF;45P&fQc 쁯`Æ ؾrxݎ(./vRn,ݷj0S'Y)03m)SpJ:D:%/zˢBs( }Q`uh܃m8=Ļ꤄yyyczK+f: ؊F(ثWC]W܋oϔLUxOHC?w BA:tCG M0s@k1"q?+FNCP-~nɡp 9~i W5~w żeP,e2Ùfibְx]r{MZoڊ3]ņXt^+vߔ-1%-Pvz֛4c\ 6}ǴKЫ/ˇv/2<w%ѹEqf t[i@_Zt-0`|[t[Q1K,۳f)ϣIÔޜdܖ\M"vdb꿼]2 $ܕ!d(-Ih˶.Ӯ@t.H6;->S7-?MKU}Gc #wo+<\g.~[tbփҳxg eS~_1x\Bȷh#ٶ}IL&'bo2 h >kD@je&>[/!13Gtũc;kՋlDI!nr4 N2S63|u60nݟ(:*scu`~UsLl-Q&aZu=[Y1^5idEtrKvZ VSUnc7Zdz"[1A}*: vP]<1վ26|{M7֭vo vY\%7SrZPJe%/?m (@kS;ruZyn'=Ы=uǾیdw/ƞyhƴ] KuKK T]}u=΍TaMgYȭ~i5 LAH+gdd(E["CtJGa-\'y6@ zO4p:#ޯ#y3\(@ $ 97W%uD |.69~W}pWF1ih>apycW#!pziy@0Y}.0M:}E$bPn:\;=f9ke4/ dž^pեҕ,܁i RnMAܕz: -݉7%nǒ-AeEAauv wQ@ZLRO~C%:% {"0suG[ kǘ/%R(`~Ok,OCW}a>%p=ߝqt{j%4H m⩀12pزYt:݂׊ş`ctkQY+Ub`q :D"l-磾:E17?\ݻx)w,Fs W(@+\tKc.qP]%P28z0N!5~|_%xaBiL`b5p2.\(@ X}6m{γ!\W1|=viDAJ^).hĵ ܁bc.^ͭ?F"Axdm/~s ^Lzb(PATI8V X+Ŭ.CxϬrʊ `_{̙j$ :Yw}{6 ?U2KCl.Z,~-iČç>Gw#7F+1멘<,(@pC:%.e;#a**pn@b (@ P~GW `fڈγ(T?G°L>G$3x1.h%goc\s1 Pue+tZ,/yopB~S:+ ݺ^kNhpe z6GEl+R6 Poq$3#i;cYx mȬﲢFY KF/ZLkeҢa Dg\\ȅ*D$c1mȧuȊ>t S_\ l0aL cLj.`gc3?p+cv!vo P4qA88ojJGg(ZtƸ-8*:НĨbud\_P6CfRE9bq0E#_tͽgxl'Ψ㫕.w"G@\Xmx!/fq+(@;߃Ea{{褎71m 4.Z-5 C W 5>`,ФM{18d(PRE1oWL .dH$7o^smPgq_ @wPqbzCGaw |[C8SbX.eCzoԦK PwqtED]cp17k8혢.n0O|XvO۳}{}N PzKJ=d BZ9*ّ҉՝cЦ,27 x|!4C+1FjhۉMSvy8|S^bD'hHC 0ў Rp(@u-Z="+F)M*lXk_~K@ PBCC 4\">W`*j6r"ra[gi?/+Mg1q B>Q4 ^2u {Ễ'Dž cQ) ]_qS75v膤G඼VbX}E';Y9 ݷgH@Rp51DxQD]LBNA=F/;.ÙUE^cv`"_3v|(@{pAxᖗS[b1WW~u(@ Բh*8:1؋,sI.̀.hy|K<㶩;ΕSk _ez~0ͰYk߄J^zٶ˰-vܢ̏6#vR}s9Uk'ϊ&4\Cxh,? aE+Hc/_"ew7i$.֕ F#pov?1#1Um׹A˻7(@ TC@rjWƬCMx׎+s(`1xtJ-rr?twOh`s07[^2R_BdI/(p(SIt|^c |ޕYBݯ (`VeFr:yv<7PSR誏E?!C?482\{NFF/#J["5@秂"U>ce|o> R(绀x"HbvOAPa}q+oKGohD:1]%W~ /4ЪU)Q(]G_WE:5W ФZ0NR{L~#&!+fA P ݷ b(@{;/c'uItn3`8)pcj9k4win?B@7.Wȃg5n=1yxD+/kSV]@C[ƽ(u'zz /B Pm ݷd4M {.x'#ކA^XU)1䩄i%iX<с.$KyyG7WCA܁/]BgNBsvF P ݷ d)@;u)sfU؃8~_(b qh"Zt>Fuީ4{(OGiy*}{ ?~ -v1ր"f~ց$\y}|*quM΂)(@ PVRQ,&(`W.=Q_m9Ar(Oވ hE%<ڰ]kם&D Pl]?,(@ 4> zmP5Eٸ L,N#9Pz'&?wqKu}.ž-3ܬOF Pu+>GԭU6ClK@r{=϶\i4ʴǰ5&հփq(,Yü%a ,KNt9 P6 6J#ߎq 7wr 5+аMe[QG0ۚ D~0 @Xs_d򺌮?fex, P5P1hG(X'MLq x1D .@Z19pP5*;E_ E?8cYFrrSxa5/Gڢn6, k{5#ahU9I&4mv,1}kQ]Wxխ'ml+{I* YU9οzV疽?v7nPghHe_O@^|JYyJQ}Joy"ZlKvk9$,~4/b21@^HNY@,v?ql8[>e >oGtj,³#smн/)N?G~~n'7/j9TvoN,qiz ,Z4⤳I:ڞMJkD~VQe{~.QyT'Sj,rrrpNbEȹgK\+-4MM[/9VӡUo]0 (B ""*{O`q4e>|pA B[ZQa l^~T=g_K|dͣW-ݷ޷Km\|kk#xPKQ=M@ 7웽 9[NqM+oVF!!7JZ~ mܡIヰzVO/A?7v󽚖[k111u|D=\rr2||| }Q2# PݷX\=<\\ȅL}%308vrȢW]l1 .(`Ufjݗ-6`- eRc eQD`)/TAE'~ %Qn;D P"kߌEU>qPc5$&CYڝnD(@ P(@;';ţdlH%dԈ~>oP:3iL3l 48÷<I.wF(@ P"–{#5x9:oz# _IBbTY,G6rٰ8yH᫥X0oJZEߎ5+J(,c$O Pl@ T"C,I@}S j8Q e?c н/ñ8d khIԬ,8".ޝmILA!l9DᔚΎ5𝀯q(ƒ >8#ckwL\J qԩJRp3(@ P#vbY ZPZCj@DbEUCP{Os4e=2 LO&/Қˮle&n%g 1*qqqK-Dχ3My[#xx5a\̕=P:ŗ0~{R(sYuK(@`ou)@C,o*AG*mCnƧg $yPbsCa֟մ YG.ÉT!]<\ 5/? ca[KOy`1^ZL %ۛ7%vuDvxe[TF@@!~;d0i[)I X}˩  H"p*sc^`l\Jwcαؓ/:φC<8l7teu'1[%/_v,IX7e'! {იp۽1έ}p_ƁgzX111EWMSlmFS3h`n(@ Կ@Iǹ(IQ_Z<ܦݥ=~X4Rg"CZ#7} ^1ze{TvaE%7,~x,rUbnZXk!W̲z12+ P F/S2q(@ $ G$nRC*m?;eNkEЩ{/,x}7҄XK(A3*t$ڕ P(`)ʘGq".yES\GqX{&I9+m)(Pwx~+`lt  ׸D ""8{Calh8<_2DǛoxm ذaviVwyA <(@ Pyp4j@ !YѨ=A{-$s P$GH_(K҇8-o{ⱸmܡAXxv=ڶ8{@+p"@;# 3!#v=4vjV1Q(@.YNڜxK+Z0B(Z䤧!)CLɅ['fu1t.ExFzZg<8 ǛbIJx;L*Tb(@NGi(=|3Wp"W{uD KG Pu*tqGI߹#KC~+~|nȆ(@ PCB5q>ƶQR~GW `fZq9M$:[۷oO.{aY P(@ Pbl)jIDATCu<֌ tyL|[eC)g D'1[ȑ9s;[XCnXc}ydc1 (?@ P(@ P"G:Wf R$,?Se.0qp+Q $f@bp6 .^Nh5R(@ P0@n9{z<8lX:$tѢO܏W@/&cCr> \\=J{\CskFOcP_+㇍pADZYؗ#fa̳}zl[Ѣ\d "{rFy=WH/Mq%7 P(@ P>p8rbH):$4O6j8Q w TCӺ />A3#r[)44 Kå+Y^}f]P6q.(@ P(`wߊȟNKk^gZ.ƥ%WP(ރx cKW@wd!\z}q ^]>wy[qf]ƕs*8:9BkHOYUP,,(@ P(@ Tӏ 8Pݯᗤ qZޤcq۰C3(ヰzmq~bAWD,&wGԧ'Gzh2ڭ(c%i4JJ*م)@ P(@ Pvzb=^@jR3:Ѹ!k*L{8asuGɘkߡe"/WWFKVSlF@uo3E-?D ~;u6s~wM\5 `"h$8ڊoj+Lk3BHLLLmo'''f.`#%} $!qiuNΫ4mMjݗkRr{'(P|1Nx ^בK$ĺÑC`y!VL_}?S͸mlxB Wp0n*+/bq_4 &3l[~omRzzzdCttE`i1dk񘣎-1֓|K(޿W^w.#H=F|[:0sR\q?+U(]܋CG MUaZtx)@* ݯW~V; 0^vlU`UI1B:½䂜 唿7Z'KhѬ$UEYK'bokVGRdk֔mYN=w6x'$f!ar<+{]\4b"6EGhiNjG[uq V~PB Af|V( [1_M[VNSOm?[楑"F hzb!̈/;c!joO]]]Po%{֨$t$zӡ( GfܳJMF̄Phl|^Qt\-vQ tUdkT]:zboosRtbTkh<;1 s漎EZw60(@{Pa+K29h Fa_b{:xEw웽 9rVnVqZCA P ݷ0KQVoߢF[qvvw4| rL $Rr٥brp "6%a;cmP+2V-70 /u Pu-Hٸ LJ&CkpHlJT`xj}#9H8-D%ő;w$7S(`l-vX6 P/ ]<1x*W|dQmui8jd<<,w 3Ot (@ P$vߖjP{%ky%C (]GFRW~>/b1e8x?R\ޯ;ϵ)@ P#v~yT P" ±\uit%ƽ3ZI )kq_Ozwb;!aI(@+`oSgIR0+Ғ(uٸ'mWW;^AZ =v@)@ Pv#vnR IKMEGu251Q(`lXx P& EDDy` P@] lX(@ X@mRppT͖3(@ [Ym~v?(@v_JOOYB P(@ P@= H1B:½Ɋdy&Y ^mnGn\T(@ P(PR]Ш[OL6ޢ]xy=(J匆|*G'ᅎWR(@ P(PʥK#MxKrlXĘ/?/^FsѩNb(@ P(@NGi(=|߅O#r tn뷤<:(@ P(@ P,G6,/ F[{v~ܴyC0vΒlO P(@ PGq 3ũf9FLx }p܅WW3(@ P(@ P@H 1}%$fABwC'Zg:֟=mWw(`F^m.grZcXB' d-}pJ-W!ւd<E d<+T<-z|vܢPr26 X}ˬJ1aÝ-\S9K/L~wEӟOt'U~(yJ_|yyӻxq97vժU򨣍5J1[:k .ҼV17[⑫1%ApWp@+* 8%&$$$ ::Om1&Q|lkhK 1}%$fW#=<+#qߏ_ݻYz#ÉX?Fnnp^>Ÿ6DWP}J.=@AH^Z, &@ęܖ,*5`׼L1U`vs x!`Y,<Oz{2EYVS-f )Z\>Tw 9l-Þ:(Ӱ~0^fjh}fS"C>Cl]tNMwv4 HQo4#}q?DHعsڰzZnڹsg0_ΛOꭡp)S9<^Rߥ+7TkjJ,A)ozPn>l@9eSBա=i}^\ U~~WVЙ5_OTMZר>-PK-"< ˲K=$i/hڡbQeI#6)̰5bSړ,ș>3>`7[0@-:$ QѰl1Z1pӋGyշJdyˌ.ܬIJmvZTK*,  eV]#[;>.K_W-1Ԫ̛PABU^';SVA-)VѴ_@^^Z`/_FT 67"Nl }f/ q<gI H_HRB gHл&Kś3gcoQxs޵l|t%f4[8Oux$n"$Z|l\0wE'wM/v/(Ș%زd-:*Ƕ uEhyl}+fa)pai4lv?:t&"2ZXvtSQbA<4ɗEG8, ` E0Wq}[i6]xg"d>+/mKƕ@%A |>/aU1INe9/1pwлpGZ$tM.-م)da[u< qhcry^#FߺO72pWfBͤ _$txo5Tx 0r?=CސK?̚goŽ}a>ݱfHBeM³_Ia]Ӳ`[_Ty|ڻ }>(NYNSC[SwU#[7TxrX읐=}},~2+{ʱ;Q+c^F>>|k!r^ߝئ7:w"mZuLgڊN3 @c"q>}q1}۷=ePw$y]NNy/+ܲm,h\}@2g\D\T>n! ԝ ? Z`Ti#pȲ1'Վ#,Ϭbޓh77P +G6F[Ȧ[>=X7ٻ7^ s/$#{Z6c6?7'm]J;?w\]%-N+{B^R B)^.'&~lf'(l&V(<6ovKB F~E3G$/ ƍ**W >7a㾼RX׌QeN% 5Oś5Ð6|,a]X!D g2SO dQ#dqc݌J#kG&JydA4ciJ Xl7Z\D_&w/0#kG&=V'NsR;vd,k[e!L$8e ǎKf18W8Ǡhqߊ +wNN.S {{9*\3ҋ3&c-5o_זscHHHHHHd}ms8U~}P6_AQa ܐ67)EEBSKƞN$@$@$@$@$@$@$X CI.cqi(!1).U^2x&      !{'٤J[ @9 x0gh߾R !  8~^X?e:IHH@gϞj4:j  FId wmP}񮬶n;14dڠ8 edJ Oa5VWW]v 4εbؾ}{hX}ڰ<62%ӆ'O2V8i5)/W["զw-DO#et)adA.ȴA0F(! r zOSNѣǨ70PQGd^#i3=Y~B隹xsMjzcף\Y_kԦjѢ=AJ"2ʶFe[Lm-HQt\e)h=NN -{dj)2uB˞,Ddn{VU[ .zކI 1B$@$@$@$@$@$@D@ k^c*B3.qbWAidHHHHHHH NCI.ه]IHHHHHH`:Qg%%4RB+ %.!EBs Z.ݘx O@;ct %ee*W?^Ψ=oSGZ      h4}J ډ־6gMځ6/LZPg-a::ӁDdN@k:4g@k@A$@$@$@$@$@$hfa3D@K@NԇάZ8|A$@$@$@$@$@$ШtLÃQ6c}6u6r=sYA$@$@$@$@$@$Wc:M;f\Ã\mA$@$@$@$@$@$@DβgƽЍm+IENDB`././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/stock.py0000644000000000000000000000467600000000000014033 0ustar00from datetime import date from openpyxl import Workbook from openpyxl.chart import ( BarChart, StockChart, Reference, Series, ) from openpyxl.chart.axis import DateAxis, ChartLines from openpyxl.chart.updown_bars import UpDownBars wb = Workbook() ws = wb.active rows = [ ['Date', 'Volume','Open', 'High', 'Low', 'Close'], ['2015-01-01', 20000, 26.2, 27.20, 23.49, 25.45, ], ['2015-01-02', 10000, 25.45, 25.03, 19.55, 23.05, ], ['2015-01-03', 15000, 23.05, 24.46, 20.03, 22.42, ], ['2015-01-04', 2000, 22.42, 23.97, 20.07, 21.90, ], ['2015-01-05', 12000, 21.9, 23.65, 19.50, 21.51, ], ] for row in rows: ws.append(row) # High-low-close c1 = StockChart() labels = Reference(ws, min_col=1, min_row=2, max_row=6) data = Reference(ws, min_col=4, max_col=6, min_row=1, max_row=6) c1.add_data(data, titles_from_data=True) c1.set_categories(labels) for s in c1.series: s.graphicalProperties.line.noFill = True # marker for close s.marker.symbol = "dot" s.marker.size = 5 c1.title = "High-low-close" c1.hiLowLines = ChartLines() # Excel is broken and needs a cache of values in order to display hiLoLines :-/ from openpyxl.chart.data_source import NumData, NumVal pts = [NumVal(idx=i) for i in range(len(data) - 1)] cache = NumData(pt=pts) c1.series[-1].val.numRef.numCache = cache ws.add_chart(c1, "A10") # Open-high-low-close c2 = StockChart() data = Reference(ws, min_col=3, max_col=6, min_row=1, max_row=6) c2.add_data(data, titles_from_data=True) c2.set_categories(labels) for s in c2.series: s.graphicalProperties.line.noFill = True c2.hiLowLines = ChartLines() c2.upDownBars = UpDownBars() c2.title = "Open-high-low-close" # add dummy cache c2.series[-1].val.numRef.numCache = cache ws.add_chart(c2, "G10") # Create bar chart for volume bar = BarChart() data = Reference(ws, min_col=2, min_row=1, max_row=6) bar.add_data(data, titles_from_data=True) bar.set_categories(labels) from copy import deepcopy # Volume-high-low-close b1 = deepcopy(bar) c3 = deepcopy(c1) c3.y_axis.majorGridlines = None c3.y_axis.title = "Price" b1.y_axis.axId = 20 b1.z_axis = c3.y_axis b1.y_axis.crosses = "max" b1 += c3 c3.title = "High low close volume" ws.add_chart(b1, "A27") ## Volume-open-high-low-close b2 = deepcopy(bar) c4 = deepcopy(c2) c4.y_axis.majorGridlines = None c4.y_axis.title = "Price" b2.y_axis.axId = 20 b2.z_axis = c4.y_axis b2.y_axis.crosses = "max" b2 += c4 ws.add_chart(b2, "G27") wb.save("stock.xlsx") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/stock.rst0000644000000000000000000000311200000000000014173 0ustar00Stock Charts ============ Data that is arranged in columns or rows in a specific order on a worksheet can be plotted in a stock chart. As its name implies, a stock chart is most often used to illustrate the fluctuation of stock prices. However, this chart may also be used for scientific data. For example, you could use a stock chart to indicate the fluctuation of daily or annual temperatures. You must organize your data in the correct order to create stock charts. The way stock chart data is organized in the worksheet is very important. For example, to create a simple high-low-close stock chart, you should arrange your data with High, Low, and Close entered as column headings, in that order. Although stock charts are a distinct type, the various types are just shortcuts for particular formatting options: * high-low-close is essentially a line chart with no lines and the marker set to XYZ. It also sets hiLoLines to True * open-high-low-close is the same as a high-low-close chart with the marker for each data point set to XZZ and upDownLines. Volume can be added by combining the stock chart with a bar chart for the volume. .. literalinclude:: stock.py .. warning:: Due to a bug in Excel high-low lines will only be shown if at least one of the data series has some dummy values. This can be done with the following hack:: from openpyxl.chart.data_source import NumData, NumVal pts = [NumVal(idx=i) for i in range(len(data) - 1)] cache = NumData(pt=pts) c1.series[-1].val.numRef.numCache = cache .. image:: stock.png :alt: "Sample stock charts" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/charts/surface.png0000644000000000000000000042776000000000000014477 0ustar00PNG  IHDRIsRGB@IDATx |LWMB&PVJm*QkKtіZڪRT]RT*ZoEI"AIνܹs'3I&J9dsysϽ3&HtHKKî]ѬM1@FdJ]& @)X"~i'ի𼘗t$%%)RJV l l]jbۖ ,8~8._NߎK/dWX/^DZУG/[;4G\1GW#?l !jF*='&`L 0&y!ʉ/%ӯ~O>Qlys`?xK$Z^ުW&ڦ\`L 0&`L 4 hm<Ϳ\AΝ`L 0&`L 0&`#PQH9\#ſLt+%|] W䓔d[z奔ɵ~裏S`,{a!ZRʤohL2׎=snwu]ҏUùDo_/K/)&*RjW^}-12_ہ\N}=S}EYxh$j_?;\l?Apdz>-jHNHOUbB-ny+cmڱcw|;jԜm6ϔA•|ӊbZWٟR;bw1ReRN_Prm89Kzz\ꤔjGۿ_6.lgToysm=]RfU0f zD!kRO׷+?ynxԨtixը"f\ }m䧻G;i?8/|ѧ8~(HlG8 3FWvʼnS[)G 93r2-TɵWN ijyYn(ӢОe2E(` X>l<9AvSdET{GGu$=BJ-WA9G:XzՠRcJ~( ?c1T(ڒڼ)Ցol݀:)eKaw۟o*ZrR.̻O7I[RIOWXLmI?a&btdg̘5U/0gQ}s j|5m1mz_-$륋!\ߘ>P-XȿrY¦Ŀv,=-S[R_׷:]lߪcZ=ϢϿ0]&?HzHzw翶ֵizAO?= h-{>g-T;fm^M/XԖm'};_OO3}L9(neYm_z-o_rIwiߗ~WRO׷:ik׷ں?8Jc%E֗_;}-IOIO1J|'PQ%l ZijJ,kiӘ&)yHiyEN̴tTq~Z;)$ )el++M(WTDPP:7WNW]ԡ6 mm+#QfyXƑѼr-: /x\wZR_&LzK`zYTƣHa DJKÔseɉt^STK*aY83l\=?i @~:X'Ie:F)/H"9;;9̴(I:dѤZj{G*@!=$A&(yytVmle^?@AmO5^uj/;QU GS =Wߟ~Y߿'{FҦ,wH1՞zUzIm=I}`JJ,lMeNcFYV^A,d.Zm^o/Zޔ|#zwHaϒcϓ ߻gaq#vR=E߶~qʒfA6Q$qKR?H|R&vdڐme=Ce2-1%n#7v@M$S[-b&/ӵL|n.B?j]xߣ]_U(iyb]=Q ʼn}A|}Gݞ+JR+om_3\5?4} fOB ʈR:n[CJ[G|Ssd[.]ۿ2>U`ۇkmK2eZ%7%HS%K>>(_R-Hې,VֿoYo2?'$ w=+YhqmtJ)[-Po|(EIv2~i%d7UOC-U~PT9KgIJÒ+LWY)]/uA}aoD&(W4K0B_ 0 9,S,`y֑Z}ʻҦ6I2呩vaRl\|,E(ɞDWѷ? ߀h첽;e4*:RGTݏS֖xɷ1u aJc2tQKc;ƭnת_V2e5?O.tԋ!_&6ƀ1+Qv.^R)|WwyKMT%-&3o:Fy*KiS?*ӏ}=#mqV?I~@#RlmziٮhxS=I]oi*岔2Q^c2T[ZZ`s}cѻ_⨸*~Hok)"Qړ䟧zCyW9J*1__<%MXx>)g-@y)e*Jc>mڣuFZ)1S^*uwpP/}4:!dFym3IXtZȎPT\⭖:>e/K&ԶS@K=CzU5I(:WIصS,i!!1[e?ϻ]ǯoiR_&wR[(>=_IxdC4nYힺm;O{)#~놫wuo[.u<<٣~Ije˼72*Rd:$ڼ 6C[˾i\$e2_T#[FeҾQ"_e&,C =ohU^|hZT1ƨkmjRGW*TFmIJmڐ:z}*'?qͬmjEˀ~fr3KwiZI*cQ֔&k}r:?#oO$r%@G#LܣjgWs[{GRe7*/uG-2(zt7;;.TW'q7>owמI>yONSv@6)fH޽RSxTI>UVls˜$:3+G6tzzʻWƥ4Qf7WůƉCztG躨#8b{emx__ojEgoHÓ {*n}+VV艧 ?}e}zEڗZT{2_e{} I\9 +RǍ) =S:|4*35_DIu}zV[41<޾2%_Vj8 Gz}}O?}WyS{Sy8mߓ=7IҗOI?TNK)^߫zXyh;#b}ܲГ={C[Ɠ^^^T={kbc]$V2nEfiۗړm8kW4l_.z}}^( 8%~6Y7FyO΀jӷ}ґuR4}՞\ħ{?X83 aǢř]&hSǧ}}QǫoOqJxGz8C-ww4SJ@HdLY#$D'Yl+!O64=bգ}0fghWVP-  *C]QqK1oQ' K;T&-S;)PɆ\ҨJ)x ۇ##}OժOof؟^FxuAP9TP岒q&5+T[oY/v$꿴Wri/)FΤ(m_EmbRF~,֯zeَIm,.9/SIjKӺqTAJO2剗z&u{`|k0%#+DqZʓrY&j.9/SIj+LzȆΝ,'6dΝmb;W~_S.ʹ<twdTRTU%Nڑ䟧zi&rY֑^RORF(w4YP295Av`l.B¡3AA}@zaܢL2??ԧ_edÛz6+)~= ' Rs9K"dT-SOmc Z 6O2 }_])N;G$S۪S}ٗ6/[~gcߗO>?u'IYX_g?'$eڼ~HJ▮5O7U[ކNUqiRIm)ORi~/ˤGRkQ^[Gy%S|竓f\%RQK]K)~?wQF(Ρ3=_%Jth֬ٵ3 `L 0& k[F|x^ʟbЮ%O=1yE1_cYJ,sL_|ELmۆE #D|Iꖾ4ߏVZ=_`b|o㔙-r2SEk8Մ:E)j'![Ab+L 0&`L 0&eR"Au2N˙C@h7xwD,;7ւ+oL-?!^o3ܬp 0̍x3%E;?c!yQžcJ!J̔HWYƮn̴8,eN8?|B7%1S" 0&|K!<8R-?O"珹&p5;_ءt5ߋ4m(4|KLFm}ݞh8L vƄ6hӣ j^bPe:j+ww#`]h+>1 ޱqUXŝ0cwg| c"Sļ % taH'D\YP&2״c'#9ʕ)5Ac߹KbB}g5§IX5\i!m;qZ6V|Y oigv>Z2S^dL 0&`'`xɷe6>ywcc (6j0Wd e`7Z`l;hs60{7{ϲ06ĖgRf7̴>TL'|nk77C ih5쇛=)Xڎ13-_6?z0Ӓ1L 0&P Njf,ӮseX dZV32#oZdVmtVy O֣0%Bq%`L ;B& [(H?۲qڳR|&6 Kmuڃe#3%%q=q/~I̴X,+uuuGܽ}pWacs|x;`Mp19Nods!X>r` hX(A.]йGt흀f]pMqZ<`uJ_c[x@`L +ރ{cBm jj!s |_谟 ס6z 4DӳjHUK%uҋͣNòvL5P͆C{ߪnە[r &}yvfjG}&as3Zݺd7v 0&Cq,M P]WEl*^(EtNWV+r߅pܿۊB`Oy{2Y!65xYO /efJ$ qD$_CHd jkv̴,Uk>1Wٗ9@uj93-UQmCfM+iЉ[jL7hL p`L 9 /U_7[/N/w 0&`L 0&p0=4S%M4׽x':a+}fL 0&`L :֭[OWɳ_>P,&, zׄ}Z|9KJVY9C|fUV%5Y6oyJk̔-r2SESf{qz}1 JII٢O \9S{l 0&`L 0&JNN *ǠIPv=k-b$~սPIr9V^3FwiiGY;,^ U1љoxw$N]ZN,t2 ^cK|ʣIbcJl!q /{ !ib҆՘ֽؒ`gYY)_zmw!qꂤ1o%d͙`L;,ŗ/c-HuXߌ]dcQ%-Y0^'(ޟEEܰ3?^P@ ;=1f lhq8cgqs4j 4B5[`y*t-Gp!aMAL ,,ӖB`H^Qw;2eSf"n#%F[7i|RS'i|S[X 6L 0&\P[7SDHwM Ow x XzaVkt?yFwsh3|5g!o;T:xRH|jpڬ? P$qS%GR\cD6Mb8KE,CCj[ӡv>F柘+.K^ګ2ömq3fC.<Ƕi[27mӡ/W>2/O|l%+i>ħ뮲F, p:ђ8mG `L )jkd*NfY$ }hWL]Τ>fպX֔!guXT5ZMyCSD·r=qƴ1~ś]B*ފz}9fꞝQ͙X dZQ EFǣrl46CqJGoW9` mi{VMGq><+5ׯ~_2pK5@L,1o_kQ~_R"fXk*+ʕ1qږbxiq~5Tp^@m3`L `8N)o:z_gZ d$Bs38?to"]- pˍīBedv653n{DܪpQKT`Q4Kw̱W иȖ m}'#PnT*/swL 0&p-pP'*c]X/aO=o@-ҊlYmvlOǘabr".5cz~N=EBIoZX05̿Cɗ$Xz3-bx /\`9D,xT\Z\4LZ4l=A7O9N=y=o>G`Lp}S@ݵ_`7h7E8qC ϝXu4ZUidi&0㛰ۑ#dBҌϠȐW:O˩jbwģ𮆨c7GLU$>ԣXE|Vm&0qDs%_EGtժ w3>1o>`LpP[…]=w2y:`M^*%d 7" 7cc0tK.xV r@8mÚ7\OEVpFuhH@\+'$)̉35$f+4C~Cߓ @6=q+q)/kG;Ar8-@0cK5dL 0@eB̳8Y\F|2zmD. 7F`\#, ˰ZxL4 1b@Nmq?Q E׌Ը̐ǩ!)mtU& NkwȢ`yL 0&`L 0&`@4wR{V "&`L 0&`.֭[Oj,3OI,s'ѪU+cg>^@9fL}O9N ")3=[8e'{A)))1[dL 0&`L 0&P CӉpQQ KL8 _ V<{$~յ$Kx&,zODmcWM%գiٌَD > m\I#ޝI&u1rd98 ~+?&b҂^BoF-0ijL^OeIisT/G_Sur aaڠ0;'zg OUc7`2%0q~E&( flppf7P'Ell{8 /iK`^7 uBHA#kѶ|#XyщW w#`]huBrv܍7GUk.rjeNkq^ iGXg2zmd,T:DC0@r{almLA|;pXLcP` x0#6T =ULRޟT6`@`BmF0B+h,t IYbB͓c"abWK/C[yt& Kgt2iYP1T5&G LUaăӤ TܩC8+6f1nM g^ð=&ޫTNb^ݒ,Z taH'D\Y@`1Ɲ012F'nŠ#'0`¡&m+:ӏ.̆ fs?-l 0&>W󐕔Gp8OhX &B 1 ĩ-A\'=bKju2 ^@ɴ&&I|M! G2Zyk7`#8(\@h?2dږMt 0̓;-Xd%6mۇt tԉILM7. ekG_)`3<*"-SR ޟX6`eȏ_3gھ2 8 v5vZwKz7)yuƏot?V=T?igQmFk3)\7wvhQVN 98skL+J(QV OL ˱mX~Oay;&-wXcyFh-<$8]9j˯K8NKqi&( 'ԸA>y2=ŭ{N (1`_E(eKIިK|[Ni"N:,E?Hn+.bbxsXGO2I Fqv n"r8kmK>kNkA +4ws\yTɳfF};ZqΈǩG `L  J,Ԭ Ft%p"!aĥq@sf?1{#K/BOT3y5{+608kH<^/Sv6<'T~&t@cyCq[gQ{* pz|*+&80#J}.svviieL 0&PLM8wS$ЊD"1_ܟfVx&1=?y714"u{iV7G[,w ՃD/Sd a5WN /\SAa8 |dM3qˤU8KS?"?2MO)r#a:(VƖq%. zCs8Nyj"v`Lh5T=7`U8jW4* |vs'cs0V[_4D֏MuA|f#QI@h=z|WqqU?N}iIù FDF,~zx-^{~j{׭ˮD$_CHd j;&׊ǖL?YmvL] N& +$.̲xQvj1-좈+`crd>3#?J!fjG 3J!fjGLqL b9_>8CJSmR.0gW8iRzETdAfT(SoL;%-UQ[[ g*Nmq?Q E|M *Xٔ4;OK*dL 0LeB8kYtx3Y4̳e&`L 0&(us:];tKsl 0&`L 0&@hݺw|ׯT|rdsP1S߯RfL}O9N ")3=[8e'{A)))1[dL 0&`L 0&P Cmw:ϝå{T4I_O@X[T׀%_OzRC zfίv0s!fe虣Ѫ(Jـ$DȻ0YYɂamN1iM؅7Fu1qLҽ1B$.k\hVV *u0UOs.%nB#;q/,]2™3-$v8N S*U?-l 0&8ۦ]=?x)/ލTۤUK dcQ%-Y0^'誝:N%qx|*;'O.M߼5jk:Ltv s梮ij7y2]fϿs۞3s_Ծ /Zކ &Pr~[{< 2eSf"dM0ί?3ngL{ gٍУ V?FXL[?8u*xZjh0`L a4pq=A)Y7ڣ\. XzaV. ׄ!v~}:[?XTŘX2Ol½Cc۶>k)zŅ5?YH݅"n.+q;NZPJXL 0&\&"+#8Ҍ3G8m8Yt(m ǀ zwh4'c01Y}1=?y.`61Iþow~uq6`EC߱L_ ƣsۚ@>f~qE󩇰< {7-V.OS?] &,3}̺ .&'"1QO6i ^*OƋ`L ܩ{/?Ք+&,8s6^❌s'cs0V[_(*D֏Mu5n rpTl$p3:뚏W+%HMayXNXF-F5heHA8Zn޷GmiJ$TUEGtպ wJ:GE ?aY;4K ԙǩR(i)@eL 0&L<;뢲5<_K;7mڄ'|% 2͎ _Z>G-j{KKEVpyDWuzu~jma8z&c5u5ز5fvg`HԬ(WrHIS´b|o`j2&g4T˲< ($ RUZi 9[AfTȥal6…~RX7*ܢcEx"kEZH fZUٔ0?- Yn`e uowˌGG`L 0&`L 00͝;KoXСC pk&`L 0&`W@֭_~2˗>&S0L ")3=[8e'{|obE&`L 0&`e=Ge *ԨR8RNzgZү +z ^f=V2cS5̮'cw$wl@Iλ0YkAx6TD,%k\hVV *INƄu1}Li;abwҳ~'7`7%8Nfӫ;cL 0C1gXW>ܑ>?mo}rTp ll{8 /iK`^7 uBHA>h:@0>o,\q q~/b},4>25|ˁ994;fhW>vƄ6hӣ j^b 8qʡcP` x0#6T&^w!4Ji4m&( '7DT ZY}P%/KLm)$|ZĮ^As0.ݏG1zt6~|.ѲL#䐓G`6vfȐ2k7t}3@+|DS{-̂,wbmp@NxrFQ:};wILi3`95{7(,80u00i X)~t)f6owݰ?'ӫyzswL 0&PV9"ΪlB$\.D`` x2m}Y b ENG{`tzqcR Ed5FN~|7:5QLc غ5j0!pd<k ,YM!>w =!4-<liQM0id|A[slͲpz#~k6ElƗGɴJӿqo]3&FpB]Rai;٘9y>~כgxB~P{(Zwr*|鯣8&\W'aiݾax@k;upgodprN%PZxbxT^m`z'~/S6hPZ(Pw2LW%ݛ߆%6:NgaŃr%W1E%aɚpt{ 5ebg`xF4!,<l8uϦ5?-22n`~O` 8s1 c)̕vl|sV[1fZ\k` .fwuA.]УGt{/͉h._c?SCaqQYޟ6a`eqWxҴ:6agq?ͩ=Xs ȍfzV86 8sh,n.rW~@ZWHa."+8u N*pܿۊu8 eV-{_I.-$|{a2`j9 N\2aIW'`ĉ1#?uԙ@X}6C0-ɪǗWL-{&dI|5w8lgq6'>7+\L}1s0ef\6oD@r@)"ޟ._`e:FLh1lvoƚU~mV" B/i86΂:aE+YH5B&q9@ dG[ⱔ؝ }iG_dy;.8åoܶ'̜Żɂݣ;c`1{lʷ#H؉[*omL&V qotR,z4 ц89L>p.HJ 3&@Y%oypLJYO՚_`f_uIO(/vj7 D!CcwZp3hk/֕qC6N'|-v_ }d>jI_lICXyf(:jY;i i[GZMbxQ$s4'#ÚcǠ2%ּߕx-a|G `qꀔ"OKq1:i10 3-.WL+0s/{[#_]w󆸜IпSHx8B̃Jmv 8&L/DVH[mHHS$\R`LpPg/>+†u_a۳.1"(B~Pۏl]EƀcX-<1y<*/ǶAcs0^=ēk&-z^ nP0N,g6gc-iVfhomHx/9NgU$Mޟ +3&pP V:? ]j.~:Њ@\Q\V>kNkl~^};N!5 &s/¿tQ="8X1q֚{Ah<~mTϰہNXɳfF}߻7_5XMe%X?=UCn`ħa<1M;'ŀ O=3b &`\&ԕKřz8z(u P93\BBx3vr7B *0d3.oC}?.mO\Vx-qY40c vt\^[~&t@ ~̣p3t| L* +Sֶ?DG}ğS&6 Kmuڃwnغ{|?{:u탇܆nĢm ۾ǩ'BEiq&`˄zcKe}hE7_Њ̳"Lujc+PR< >q#k(Ϲi&n ҰyOjüHrbz+lb,u/{aP+B\U/>rNIه1S.X( f'_]Ċק0W_ix|<:[&aW_efXx;`Mp19;:]@.]г[[m~ۣ~qVwRqt+F6̐@ ;붇i~><(i[?7a#GUnuFtU/#VPC V/^R}qd:en>(vi:gQ89i p;PԎ ZUX[Őmk vr7WQo q)}s6?Kⶂ:GEiXN< OBaifnB>oZ:ySC,/E& &+j \? r(xxiZRҼ*J˴Ԭ,--4Jii)(7 y]v\Tv?ry{g3ߙFJjިv.]- m0~xK&#.& پaF(\$îəHGF*Hi2489 Z*Uǂ1и"0" BHMELZܫOwn,lxqZ]b/ 7P 6@uYY)ڟ%rLU*%rD&>r O"Vj [o] srE,]P#RK歾غРLKپ@ǺSïNXOMg+_ Y•Iޛ%~ir ex? @ "bCϳD #     T/.dm&K -!жm[LCCCˤA\kg\OagB _")ڟ%r _")ڟ%r/DIHHHHHH X]CICi'WR黗_{lZax]yXy+O-c柋1CM+e$;y{|Ug0o= f7/ڂ)Oȹ zmT0wN)~ژc8fl@5Dx{ 3$kgwѻ1{sx}qwlܷ1-d_{};k}c-X9/7'TqZ ~Z|)HHa Xя3ptWةB ]׵}QV\*rk&<' "y6MFz]rC m T^{Ca J]xzFn } Ya< >z벑 \V`N'jLڧtrlni.wfү"^vʂ_ S1Ou{Hw7j]a!1ys &WkgV}z i͓1+euu.VzqjJYF~Zt)HH XQgttԊ3=P)8ޟPU(<@+NFʢEؽWFbm̄#ĬǠ8 C@7, CvƔ^'tCazak4{fO܄^:)t'H>,eFְq1|eZQI̬ R~Z#v`EƊQ+1umRz9No-HHT,\^yu3FBEN!x{3Thг _\#@u&W{v[`&Y%Y/ jϥ:m܂O!o(.sUCcuP$Vö=q:EaLC-w<(V%hL_li/oAښePGŭ@&j؎R+mFHHPYhu\v i7HNO*1_oma2}B@f!! B|Yz/Bh,*0ojj)MpngqZA2}V.<xG7Cc?7L?AH1$w}vǦU~™?fb? <\m</6  @ 㔋^}%.Ӵfyv1ϊ?mTh1W_y 6̮G}B5@a1X5`!VvEfQʣX.̰byoUPO:? +flnƣzcr@P;j JbuGc d+B=6q)6ab&  0!`UqO?!hy&l6yX/rf-O;Fup2Dȿ(9rU lB-='~QӠP#3ӏa{ѣ}BQ@8f׶Fi?ಒ=罃iQK?O~ Wb\> ݻo/fwW1(+dbԞ8sE5Xry?s @>[&Yi.nmA6DW*Axfl zW\et$xvEH8Tۘ{cKpjwB;OV75x.޳ qbJN!.̍-]q̼[vF{ p0| _uD_mq 3:T6Oʹe[}б~Ѵd-ICmBFY{y?-k”O$@$*h(-d#2WO{6$!.& پg8F.2>8W: W@ r')tۭvֽDrF Iиn|u6sW,3D~+69n?K\D'x&=p;|,R[L2qjILü)^ ' pLVjUeDQ7C`KE.bux!P^, G)a!'^,3T 6rrRv~ꁨd7iN"2a$@$@$p'P s6ayEHHHHHjevtHHcHHHHHH@۶m_}[\i">IWYPq G6m/؉%FFF23P!L/LO9N/LOrbJ$      'Pq:6JU!jV,|,Ck`@˱X# +1u8,] x'1hS4/OGk 'E[?9V-gEʡ=6f٘FMǡ{O2om 7m 6XzM"}Y~-ލ3r)l&hd†wȴqZ 2ILR( Pss+x5+S nώG_*նLy,NAD m=(m竆wFh观뫇şw^Lf/G583=8 *FxyA|(Tg< DI36U 7Llk XWz[ygqOx[d\ėFͥ_!D욕W@FIu{Hw7j]axU[ 1jv\J}Gg-Xyu2W%/ 2C7][FOQh4f[^ʴ1<<6k8&j5Y#EDO og,<Wן/cۂ&hO³o LKC2_k82B-,R ǥ p'5f2JTFrlx?-[N$@$p(ިRY0seEt͍t5R[*92Pyb3T@]BPцdb[\,b?5hu["q<9?f|.4&F,?Cc%̘8r) [𛜝.'Gف +!^=n*[dv?BֻtxQK8L3 q(tdjI85Oo-oF$@$P D_{=[U |ry)wm=&]`lejj=/cڍMcg T pj)MpngqUnnOW,ퟠMx+Jd˯ ]x) ovo~n~B@H?}qߧݱhe 2<VT$7IH@!Z4~v/|kf⤈Jm O'Zq;xVXcfΜO6 ]OxH>sPwL5.& s}.Fa ; ']է0p,; 4;x'{'mQshj8u,p:GL}1mMa\44oDm 0M:JZ܌t3O@߆JJ;aŌx۶m,rqZSS;  G'PHvUw^ߧbpM죣U U.k-S/Zԟv/먅Yϥ"؏{y7"+ |m4 fGƓ|zr8+~NGZ0Z!C{}FI'-_JkfMꓱ];M(VPO߀9FX?W^a%QqZXgvVI$@$@& (t?^uǢAjR 󛱽nG&sv\qsґKY"Mn]SuTs:y_.6>V=+ߚv-n(5kj>AA0k0wS!~s-OsXl͐yb:6ī&U/wdcaC&rѼڛ( 8 ӧ-vSbͻPMkYPEXNe۶m?~56q1i @mC3G&瑑h-:v+t* J4nhV>224yzUAv)Hfn?^BZaLoZSkTn>ӛghG f(2%SD;Jz]D"5NoRUe|VjqF2.ӮjTpu >JgB@\26oօ+&$Sz!G/*ѐW3q웙l&@62qjJ~~j?ΔD$@$0(rȦ]F_,WF)HHHHHHVP-^~ՆO% - жm[LCCCˤ9\kg\OagB _")ڟ%r _")ڟ%r/DIHHHHHH :S ]hؤ6|0ܑ 'מ9crG^WecOƬ@B[b8mxp(|g'UmA8G]@߁<ș)~ژcR@'[OK3aF~;3RT{k^^?|POOd1^.Cb|{~`З)ci~jH$@$lXz=~>_y yþ=Ğ0nHN™Z낵֎>ABo\ޏCm#JCPDBn >Fˇk5Bv_pr#O_xi,M՚IaXy zQě4;T³mOht('iv ̚7ٷf驝Y/L붞BZ~~}De0Dx?-I$@$  P\:^Dk¸"`+L Lǘ-Xyu2 ደ{'Đ-Β5>.>3?^3z}ZRԍMB*埕cOuN&Mzk8&jCoH艽AUM콞J4>{|"fuG"?PeOs|4l0tSNfdBߧ^荕Fi-Lہ}+yfFo񿣏wA1ge2x?-J$@$ PTPz\QgpiC÷ù&+ު)hг _3?^@7;pxsft!*>E^=e:8a*m 5:m܂O!)$]'ΙXNLAarL;&:csrğذb9)ۆ2x-h̬0l]}A[~MΣ?Ft@L9Nh8~ZF`)HH R]*)]>nhGs;Q<O@n3̤D@D($&Â#zM1W lSp>X!#?6H'gQ]Ͷ; m B P=JŐ:Kgʴf(<ʨ ϼ=ޑX~ucOz>v'xM_lx܅|yY!@ T$ pp*ൾ Q)|'X?[fm/?JIV^Zt:f&{n>|-YyOuA1qL|dt(* :(&qgĬu»`NwB/lqakhi]Zᘺ*Zi*:3SkT@R (PjX<]жlR DJUa*GL3@Ff&@:< ]  c4) V2kl$Wr ~¤{_t1K^JN`HI3g ٞ1YI>>UFL/1'5߮d@@¾WO˓HHϪk8c8.Tm]M< }uN&;oqam&ϡNG/gWdz[ǫ:_^ ) xÃO qwGnڥ{@qkMC5/ z7D $,vtsݲ3z3I.WYp50S[}б~Ѵd-IZƔڋ$ 8ӧͶӹ~]xR yp9d۶m jl+89#||.NnRBZ$ I0JYB###Ѧő[T\+s^%5} k6]Ou A"BHD1и"L$## U-f\RN2-E*ǩy? F n(Ԉn2J 254LU*҆Xnk&>r]iRUe|rqu]&~!^Pdlꋭ ʴLU'(PӕW@UH#jQxǫW'X Pn싿kGvcXSp/I_zܷO}3kQi4R('pTyd@IDAT53h_ Ɋ'|#3NGZ7,<`qA i}ʴB|0-{L.g/Y`*a>bbqUiƍLˏ>!x#G@@qo##Gʍ6@*M㘿Ұd  g (Y1UDoUpy#R5EC`KE.be<\(_A2}$4|a~uzjkU8Nmd,ۋ$ 8Eqts5,gkf#      /^+vh%      2!жmׅ`yT5IXRUe|:44T\ѦM vbdjL T#S2?K8%SDS2?K8%SIJDIHHHHHH ϡV: MR`m۱܌$\:+yN#      (e_E(sC+5P9e_%^z+ YHHHHHHH (3ލb̤eMk߳`|W@_ F$@$@$@$@$@$@EPf]4A}d"C<>l` w0B$@$@$@$@$@$<:/-ȆVU.i)7ղ gc 8MɬhN%       (Զj@1 C+ԚT$%%"EvKJEjߪ $&!^#UHNDFΑ @5ԩ`idȥ"fiB' 7bՇ~jm3s3C$@$@$@$@$@$@F@QG2/s[hD@l-{֜DŤ1D$@$@$@$@$@$@ND@Qb!N"*DƓ sPzDDDYvJqqqjAtv#@vCiDFvPt< NK.(;4o@~W2K$25ߕL )//Um6 5TT_7T4Zj9M_oUGɔLO/\ׯ;XZLL bccQfM'`'ڟ%r W?33/MZ&ѦM2M$@$@$PZժUTiZ)oJ*HHHKMՉwHHHHHH)\hЯ6CBnFb.ʵ,VuQ]zu92M$@$@$@$@$@$@7O@ћ3â]gi!xג?/. *YY"&0morJ       J@QwŘ"n|+˸/z7D%,8kn      iBZ #bZ%Ne2§rCjT)kU)HHHHHH3EKKF2UYvE%_Xж敀L 0^6mw>\ ~1qӨAe      $P 0gdvO Wl & +ԚT$i4HϮKJE劕P~v ++O!3S,]:<vHHHHHH"(ԩ`idȣ"fiB'`D-wڽ۰ ŵj ^IHHHHHPe^frqZMLjZ B=JZZ{'|x|W[ªB6("s |/iv~ q{En֦Cd![]^LC½G/*vJGW'&&:-ʈ_bڵxnjmCE׮]1d9rLfk|p#  '~2-/݀Q**H>y{=m06N_ }<=LӓqfhN'⻞fhGLB}N<C_}x'V%\ ˏ5hC-Q?$&!] ?cUп699,M$`5Թ$!**iS'SqAy< >TiJ2mPB|7xwcFvv6-Zx{{W^Xlw9:x>}:Zjڵkcܸq0 P~J%lKWDEoAo>%^KϜ9-Z[Sr &*nFeZDݠƉW: 帙㇦g ycHݾ7!%p_6Pw|Ǯ?ch⤒4)OO2%+katRBbRo_As|6h4Wu+(1[\h!~8<7@fރ1nV\P%۴|1=[*^V]?!M?$vsCBӺ+fF|F[3NϞc#G[Yngy]xL#! M Xf͚u'ЩT*K/ N(a2n+qB EZ7c ݳ>ĉYo%իWu}׷o_ܹsub34%͖:~gX?bWz:p%رcJ֭[pu Z'pa3O'^.qm?kvFUې!6l(#e2ֲ%t˙{.S!'J(tѺ׵-dD+],ҶBa!Co.0ZgA[/tMȲ.;"mڿIwe n&3dh|K]_І-[eeK߸x![E:a]Zoj$>cq'>rI#!>>P{71^C>:d{WyZ>10 ɼfկ_>oܸBWf0M7o,\omݕ]çMO?SL޽{!nZ*^|E%{= tuW_VC(PL#  ;@ V\ AamiA9]LM5 ӓ*1#c)Q1MrvUG]ƹ\Uғw5e!$⏲Vd79vkeN<tG;tHy3ROm/ =*<țʜ >:M?V*2w.Vdbqgw:b. ۟kDKO'+d]Ĺ݁9k/on{-WjڵNԯRŲ  +&g?.S- [L 99Yl/UÇ3f ,aSOյ`#stIII%ìp1'|!Ŕa >1b'Zx`l\D 6DeJe@`PWpy~}-xT.r{B:GCj폨VQrx 4ܟX 3i,̬?YV"鷻ηXk2\ao/0n p!%(P1UG _}T"@nֱRYx~{˾y$jDy]ь rJ@yJKKFrZ*½Pfc'˰TCNiӦJӶ'N@D(f͚ɓfjT_*W%HJZGQr,ッ-&  ;@1|حrTW_^R+eƮ-b}4Хa1+u "e:Y(ZWS24sgk)%<@ZTh&WȱTP,R*F1R&4 D]<& {Tz7f&P߿U;}3/Ώ{zH0XѦE'}b򌷑}?Y?EXoIL(&MNz R߿?:w4Ԩ!XvrZs ++ibY5Wb1 0HHn31H-B2DmN?Et߱G#<8BA4Ch_ H;{ EK:5iq=Dbeм=hРc!R) 3=*&lbkx6@@ޠha|~1{@ P/QEl Pl܇=36߄d uJS2zjeo9lv؁_QB-ZfSv0hРBi%)-w#  rI@(ӝ2}@6>l N}5 VNY钵G_-z=_-V@~z!a&>h7|t.ð)m_~nJTP.i k-;ρf7 lZL]{Mt'Ps}񯉎o+S.>@@L*h&"%S6)qIHU,LsQe^9_~T;cn-XuaL&'>i:t\z_CxͧV{#/]ґfR^͟?8+Atf\ث'bw~hh(ę(i iX"`y0mD|e c wЮd秺y! 8ChMzOG_Mq*Gb$rK@%?w(*"u\QCn"mۦ38p\իHIIܝ[d 뮻e7JUL ZGLL *UnD1 k&|~$@$@$@$@$@$@$pK mvK+de$@$P^ ӪU+ 6 'OD&M,3|=߁,M'#A}^%0%Ю];Ӡޟy_.or$cmzy³.[U.\1w_xuNnp:Cv~J>JL jijWoW7mmLe__u@wt+[eS P†~~~8!+ h\}:-={MOt"浫P /֩fҗ>&yo\jP*[6(IB mu{%_E=߹Tt֏;O#%8_ZH*hZjIjNݰoҟv_43q? j;'2^^h(^}i#F@ћ3â]g!x?6rc#wI ],ΙY!!E J.R-h@KW^hRgmR-RAEfSMx뱐W"TכO/Ͳr/O{iPC^u#}݇-[ߢn\/@zH5@K'< <޽!toBR{il4IW'Qz帴ڷo_h2{ £ڿY]5P{71DܒWWɋx'kq]<@u;wV|[Պ1y]##54Z6>t-Knc.CJՖkL{xޞRVb(o߾gΜ1cOOO*((rF8x zb0HK,tCd}+4(|a#?'gGZE Ǘ7[%<=-z`M|qz2f4asQ# ]I (k&LdTZw&NͺJp|qbO ɒtS tR.fܥ=96E#f=`u@P:<*8^n4{}+ruU[-w={b6gL4 .]8dHS (2AyxQ;>VPֳx+#谯US^9#(yibϺlh,&8r_iV,ѧnRI'Q+3ީ GU+ kGT Nk13}.4ܚ23m?ҬC0NhVRLe< LeA2˂m0;zJK|FU^#tab̔7&6ViòebĵX]1:+{[_ˬR3ŮjWOiQcMZIۙTg˽t̳T7I]Q1:Y+z+Cj/ʴٜT=ŧ͕'z[DźTb \ڴNr3Yl*fOftX‑jZQMfP#Z BU\MZ2Pe4$@$pG0F'sĦb;qRY>+]Sش9R5u~/hM]{4W\=DUۘ -|B!!,t3(ޣO*ǵHz} -)Aӷ^Ф"IAܬ5qI\*1ٗズ TJ–s4[)ϞW v֊D Z% (YBqNoJl'vSl3 Ϸw*Ȇα?T}*}i%f濸;*v r]Y0# ;AG\h;wfF͞ʶ*zX5EטXh˰z6_s?gX7BC'vݧffW!(ԩ`id  :~؟d$Iڳ&R @ fK Jtir@.PR5z'+ƃTMfgPS-Y?K*UܴβLqPVqEF$@eBDE2Tf~h!yE)Ҏ@cCn*֕-%2k_H*o|uI!2-'(#`W"[T{b6>qE*Kb.] -/F%ڒK8Si~HhiݥKcSeTbWiC+V,#\K'Qi*1 (,hn.fUL ݦ39#dX4T/bcdT]^Ϲ.YϙP꬘s*YpQ()b}.5 ZC(RE.S6"O(ԙ.C]L6ZԻqYYMlgfBTj[J:~ECLТBB7>3pWLGI};n " hƆh*߱L\sԼ?u%/$ r#4Z.ʜ(#\T\hz'ЯAKrxcuB,8-@KZ.9wIWZ*RNSE@л+*U VHQ5l/dfə;[Ώp=9wdNmߚy]@un[-jo8Vo@atZ;%} .4Նiq`Zk~L= 5ODp}<=mCq0kH~q ۷.c 2DӔܞG@ts{gI8PzL;pQk.)ȕMO~͋/6Dk֬1o,1=v?&̕dPK鴈%G5h"B[vf-͵ʈhjlCVvכ4{I'Vv\b;#& _LWLJN?H~oCx{u ):o :Obd2E4ク<5,}KI0w\[R p0MX$s",,Ҡˌ@4'O4gMej7"mI0X[N0L빾pZh˔ZjId~kzOY=q씀C퀵 _7 8 jX,Kv( vM4& l;v,Wr>Zh7)0*0T[#NKK-#EnHO Tc 7R䒷@?PzjcE@1LfҌ;rWϹ:fdNTG3+7:­X-^z}e$mM8zI{|tAuɄ|Mz^\ěkűA#:`Z-pfXXHLu i¼TsRJ@J $ p08Cbw \%JST=+Uuz9qft `K~#/c>3 7v0k2N3ۅ߃N"uR1,x\ ]Q'U _6 ,57?`>ܵ2=_H@]MG'*pcc6`"Y%w-9,W011m'T(~b_:Zh#Pd)(XNO0 C״0_322 5K0YY9~iK+㒐W;6Rhiq>^"Ű8vNf)})h$)$j'3zY'8G~M;;mQwf>򼁩^6q[ Lsa߁jPJQ,DP$3/8Kl<|A4##jzbk kᤙN2eM=.A'v))L-vTދ\r6~W܋ʓ{}R^a'd/x- W^"Pe4x82t|t>R8wpSU}uK(` 5Q@uk-S5xA2K~/RmUG$֝-OҕDlqi|dmR7!9&iQ{M{#M`:w kKBRRZi~tLs-4V7+^Gʛu5 +AE8J.t'w+mʱp6glJ '-ʋ!5W?<_5AMn)p"k#V4Q]׈(yQpҏ1sY Yd]a^lL{hv$&{X c%?Kbˏ5Q8xuOl+lHKkt7뫦NAqx 2ʐ^tH}:nۧ2?e:_cziNMP$մX"&M4i >V#M~p { {ؖowEg`M"^'{L,k2&P(,IJ  (Hqj<1![-6\3:g_O>c=C7B׉ݡutr4@K&5@5μ3\|y):X8GT:pm;Zվ1m(gu`(*4hN֥BC/JCHˑ^_475~A46 X y9 o^x!Zf!|SQ/Ĭ_ّwbR/7"pۈg2sy;N@ͿCbXe} &0|KK~^=?^ 0 TGSn %vkZSdpi %)~͵2T TS2O9|]]@"3v9IخN~V88~3vG4a'מ̿ɤٜفw}Lk(k)L'e{^O )^E)OJ H Ĺ܀Wn{sHSN 6ޕk;&(Q%־AdkLJ@vZWâ# ?hCM6"Gi Ei(T+cP3YX46F'eF}U IZZT4x}XM"z ŽrȫemDz,qnYf l}^KH# ]yr[  ͗)q`My%ܲBֱf).7|&H> b(rzS?/{9SpĴTFFIɨ\AklԤ=|PM<7ʱ*/ڼ}qX[C.Z jIQX17&duGG;RG9[ko鱴@7], #XTI u{q w)1@MhU0+xZ2уլ1ڧkjc/&"ՂQ/PC3b9iܰC6Q|#{(@P8vIHNf!\gfjD#ۅ=E\(oe0kkkpYkH[IhMm!Z}zy --Ca0i5{XwwyH$6L _piQ^%HzF: 'd SNŦM0Y,㦛n‰'pWRR1.2sR"v{ ITQ@P0pOhCr݃ĺvViξQcݾ ?ZƂtO Z?`ΧE_U N,,14"duJn8vLĐJīT|rAfc.LByy2 Tz^sZt}_-pkWsP =p6{gsAzx($$G$OG]iE1JVtĹONNaiԒar;ˌt3ʺԂaZ\uv| ct#ү~+A)S?1ك7`e$Rq%aG5{`lFɨ6*kw߀0L1E%S4mWV#x6h7b qBf@IDAT6'--Pvex.?4bsn M l.>1e93{[^lV_f`Ͼa,ߖ-[7Ĉ¬Xd^wqZ}nuwFALT.!;COɋObf"HPw5գkȫӊV4[c`ᇶ*Y)L[J) ƚ^7'i\˗6nkg~^/b<\_Q/yjkAD"<믿;_}UW_!##wuf̘> ^{r?PUV;G%I %ܒzS[%rdjN;|@d^UN|z+̙2?l?#NoA@-H(BSbXܴ.{kP~r7y!s ֦^qヰks _Xɱ O =J/#m}(S=2jއ9d`#psuEZ!ƴ=Tl[Sl/{5xL/o.ǙǞ/Ӈ_MW${)^iڭ燇l0eO{R}yGW W҉o\@,=?UǛq 3MI#ws`)La!k>@~ZGKm]&T_l'3q4fhS@uKj#%N%s!KM0P١&'X (G^ӊZv2?Kέ |eQ(3 |DVEoKS؃f"~l`QY8hU kW^,}#G]| ?|Pw}/r  ҥK /Id֭uPQQn|eŊ+`W},+R:IHf{҇h|!蹵̸]GL3MX}Gjn>7OopC}'(i(pp2\|Q1l0~.E+ЄD3tl}T\<еv @+1p'?: mqgbWߐŀ< ⷹe-X8j CveEڰ _.'=Y!9/]_,ϵU@y=n coconܵ_dڛZv Vڗ,v/X'~c_sh71.}jMZh7 c]ž$QKJyh|T6D\f`:vRa2}~4L[ݡZdҋv~wi \{wcٕ)эc̟?C Q6@/@rjiSwf̜9SSӱ~caڵ8󐗗͛7/Q<'ѻ4iM#2 /AkDM ;^)pm,`Yr5ckеd}s%V ǟbU^1>q$?=mm}ep,L\p̻[ZosTrּ6#k1Z&^ւ۶<4czFpjk#V4'uF!a4XoP}r&ӄzJ`4LS-BAu?R~i35 TSoT+wx_~S?N6LޱT+-i0@?Dj"L~^oFkk҃}Tsuu5,T/b`G{UL=iIFƟLoBߡ[n?Ÿ|vܹu I Dixٮ.giDrR~h ]hl"&X{K[픝3nĆFfʢF )fϏ,Hl`oe sqiiF(ݝ؈O.֛c?ts~qP~1T㩏XHSJQޅe?DGe#QW^7ƳӄTlg`ph 5E30 =#!$Pى )X",'Pc,BKu%(JD9vy$s|u8YQM<|4""PH~?)9ΞPZ,iLEOjvlxpXlY\⹲k.%g+$ʜ(w_yJ諯}5?).slx7هI$% Z鼒I2=p-4=t4_&l|;!V ):9;pFi7X0CF-+T I㚿tq#jQ~î5M:(ξ7  4htaYވ錞~ΐ1|xwu76m`i&4/x%,MǪ/4w;GR61!dNį_ eu:>X5wmՁhEigJj0:q;Y*#Ϊ"Sx#wFvۨx8dEm,GuZZzLjqYnme12ʔSi] L4E}Y53\Ɉ:33Az\?EAbsorSڻ .DUUj}./rE3xS@'|ܬٷ-$%Za5[ M*j}{Ccydq~1%fZNsu3Ơ(k!4 |䒄y]?K茯ZڝG2|i% kp^?ڌGf(AF͙C52NǧC˜%8nf%6N񾎳f^ibcNXhOv /h?ߏs 8a{^(V+NOM@*L"=x{c6ڏ)׍=қj']z'%LhLAVNYIԔ,ޝ?TEF:{\j2])5c)DQڌ/T0:X0T:Q[[.L9}g Jd;vLЭO4Ήr|}J}#SwWmFf q1c@5>5"%M]u Hw6d1m49:T6P^c> gc &h8V1x1cδUA G Ŝg( tXEqLkuZ'1&w PE%_pS2N~ ZiIwnHR Hv%-֜ylu(,)s!S}l<<OFzO:VU|GپP)?V^XM:%Lhk2՚FS[+wf-H󘙊sF =ݯ'Mׇy@u[W:P"jxq(uNlhRx@5+ /G@!3Y:P]e@)Yha4/ T |f4'%.i?~E%(07ׇcsӧvb9rD6ח2֯HkMXI6i_~{C,wĨRQVd$I>u֛X~͔GZflg]y7PmVZKSc"Q]OG9|E|WjL6~dMiDARG ,uPCV*ƨQ~E`Mh椐|xki0M%I 0 ¥@Bp [l&to@—'0nz{s ]0n(99M XbDDZkJE k|H[]Ǿ{R[MWN' o&?8IJ60FkVMRX:EX՗w4ZT5;G 2مtс T;X@ĞTX +N(P5i 0."P>89lH=p ^#%O%@2Ԓ5@Xnd9} HD|݁4"~U3XX?5V2ϛx 򤶚ߚ vu5(gz4{'VdF^co*JU^pjQS-9@{Z:?߷4TתuLkri6Z\^`dHA5G#H̞|^-ZL}Xavo@j%yJ_sK&GVZQHG Ǎ#Aѳ/Ui9x@5\Zh<`6 p*ؒ[xO~zPˑ|nPVaU)  - 7wt$P7 V%2̿-n!X+ 26(;]Z1Tʏ{nm7 M Lsahj:'k:T3)Ayв}Zs7Ngs8>a{mG@;Wi9 8R H@NhmhmnGzrQjT'tMS[OxՊMYo5v}iZQ`oE 76'%V}Dsp~c;6tJD)oCJ@J@J$Pk'(0R4Жo{2 o ?i,LBā5q"`MAPM#\P_ba Ơ-,BΊ`+F5.Mebw˨DPET7壳|$KU#f? V%X$Xxw_9crTp eyZ3?oW@5+}k*,+⹦dTꮪRG`n\Gӑ&Q|iܥe@Z\+spM҉XS3ؽ8|e/aH-uUlQ2{1o1ƙƺvZjv#m#f:]]FNb@H9.^WLձ.$q4G`ݞ"0F&Pc_DYkiӴ`%=VmG1uQ{fLs$% % %ZărZ%U֩Xj]|pu@5__ja H||NA57 Xћ'Вi>@u9}H _,i_fLQB #))Fu7J{XXӅ4.b)8|ȵG@we@ J\LǕO?Ku#c^>};4UivN`9C|jQ,:kO -aLbooS7y=XG7ݰmjGw3-Ω3P-IJ@J@J d D8EՎXD^y/Qu)@"vG5Ӟ㍜݊ xFZjs@ߒڈ: ؈Fdd#'1 wl3qjj3XS KM=i5lAK;_+ M!PMr;k}HV t.4j%ꖬdf1= u̿?"0`X^Q҄r/Oډ&7"}93;AiVWNrjcHKM%&.RlhRQ*xN:5"&gő4.7ws&O}q΃'5|lBj~i[ъBpϏaϦ ]4&@T륩2C /M5h(%P1< TC;`j~Hِc#gl>g OsgDLSk T7n;ݟ~LsfRK%ѷtػW>}:>x\}ƌq)_ʹz gƬYPVV/Vx̝;W\q6oެ*//Ǽy0}t,_~β"%`v:уEX&M>qi:Goi(oԕZà98&5ɈIfLW)pRjHjO]DYmoTGʉ0oXs;67_9N0-3GZx(R~$׸> \{I~H?!-t˰2ݧvMͨ/!\VSfd奢ú_:4-5i2::ڕ ɇk9WOk~>RTx&b9HivcyS;jG{;Sɴ#x"pPO9Xr8Y@m$ мk_uZѐՁiR{K诀I lgO?4~W۷cŊX`m߾} alٲK. /:O[֭CEEn| o?e?ƞ={m/~n偔 4 795|iM`@ *Vϙ3hʭ}5įl);P^8 Ea(` <^ ;g5RKyt3tMb Lsf\q&k8۰ _.'=mmmH@qgbWߐ vNmY{ u3oÐ]`r?~x se> YFXO~E&s@Î[c„ xnlt!رEEEXv-;<-O6ϟ?d91sL,XXXOiNOO:tN-Z6mb/S2@'%`FL;N"c5k)7E&X`<0Ńl*.-pMOs 0u8Skw2(yw읉K\u&^ւ۶<4X:&1a뱥6, 6ym:Fnot1ÊbQӹ-xdn\CbT CVL}"`A5E *ÇF8hhH?Biks?`/=Pa8o~*a?4_>ӄh陾MmYh+L\"`Bzx"uD6Zn#q`oPS1u/ZޫI}()=VNf3us}.[z,{:P- ~Lzx dff2'r +Ri"}W3:\s5OK.zB;sDd;;;XxIpIHCo vLG)ooJf|d-jSݑy8}暃h&d>8<hI-Mhoz}n)n[]il.mT~vzVlB yӆN9p0q׳_E{1|wu%ZN|vD_~}z{yo^xy>\(EV0ksqM5?Y;ʁt` Frn :P{Np8`T9ir|=,P֜>Dv \'Y \sM>Rke!mԧLsRK%,ܵ x]g|cZ<̗> BIIbc…i 矻XiӔvra>|8R| hk"j]$`wkp;ox2d~3 O[͎µ%4=4:Z5_O+^do5(SRSΝ ݆fYi3a(۰2 V_Fє2g 2~1\N\Y_ibCS 7~;? z {toݜ$Pd@1 cÙV4=xT;iu3P}\=S]PM`:Mcڌ>lnBrfVHLb}iq,}\I8Q(04,i)jd/ +i-5FWHNF/Ui馛^ۑQ%Kرcjz'k.y睮Slٲe뮻رc(|s1)%@/3F !.L~F"l<}Vܤޟ&zɝszIkZ皁kn4pOyW-`YNdT]zyE/K.>f-u*XK 4~ٿdf~іxsiVxrˮَ9>s.%i:'5XREau4,@5עeF*bLR020ݗG2kdڷТ7?QUPC3b9i=`:  ,گpw7kg2|$#Ӣ$Ou!€:j 2М +| A5$| ݓ)Gu Zo0^"兹[SiKZd͇F*S3$-uO<3 &,}P4i)Xkv nhX\G魫H`N4'K T+Zj&ۓzq(j:% aB3tfNeyƒQ>p{[FYGqX4[JQij+I&skNV3aO@kvg\T/> T;Ƽ]] Y,TK؎;;:A&\$-um}cp%c)@݆zvk")W \<fڲ*>K`,)frˀo|4bi+s0HK-IJ T (jȮzԣvfc86C7}&_5I5C]O 0ͩYz_qs{|XKEbjH3@$=EXJW:-g: XAe9X6]TIZ2-u=?Խ=%`\/@2* (hzx2&1H|~tZkJE/Z"}o(aZ꽆iM++i^f30so?y |7͉1^Fm36vZ$3&Pev&jjWv\:. g].)XLkBZKSM`br#P9oltigJDZj"~(K)))@$Ӥ,T7:"cOQ){)ˇIm5}GjIƵ}L3L5v݆cKqEl"gUA)X i΃@u}y*)7g0SsVrrtmykJ5w0%# S_u[`M`KY eQ$s /Dyy2!/B % %v^_2U\Pn4tDTRM  DpK~zJԿ%FբAnDu]# Km'0jk?>I& Y`%'vZljo=X0]4fZ" )7Q(ޓz_r*,8jO`!Z͛7XnٴiϞ=ƽE{@K`뾷";M&d[0vL;^{27Q,#}Ӳ.,\ o'?|I9sq2t:{s!Ul (>ԍWt3X-X _|w{/ wMHƱi.#}YjO꾄t)Nzri,8"ԑZQޤy3] t\;+]5s /ui<ǰ$a)ɰd{sWE_z#xeQoOfg aÆ>DӦMÔ)S r$ھ}E`]RRB@;; X<<*|K֓pX%@D=Zy /;`m\C۟\~:_Y|a3>!@u7L( XJ)+Fo kKiJ`}"hiA RkCzFiN T:1o}{~]t)nvL:{E{˚ pP2e ')X)JTvv*sEȾSmZ_"׻T\j7 ^,ZLR5sDf`ZC>5%5z`f<%P=X,P-1j"V`~&Ձ@u0Fi>OMDY$~\^}<սݰaye(ihj¤I쯮m&S~GR "fzCT2d>iŗ4o',Ȯ TGK@NUd)s;';=BirZ,;}-`H*NC4⚿tqqְm_mۘT=wmaéc.tzŨ}ŋ ͚5k LSraujRbEp+(pf`$SF)Mm\Vq>i7,N'{ꩧ`e,`,'O/~}@t/u8_^$!~?W~M7)ǔB'NW\v^uY,W_}/'PIg?3\{.j*|;Q?ʹ߽<%zBMЉ}MT`Zl0-S܀(8~;.Z)ۧc2G@>ZD%K7I^b(:}LOk&%:ء>Ǒ"EH[M@@F:x:KG@t)#֑68Rx6bF'N$e e%}W &hPnC~E#=4!%NY`X Ǯ~VB4qѭ&LP!B,E)(7a61sL$8ϵk׺5رC1:g1R!H`@DLB!p<lhygX/s..l7)>Sj1"/ܥIZRu,taiDv:}A1({}w3MimoO\sl#ԟa3@S̥Ci3i#=EX4b4xS|W;z٫#RԥwaYQ>"TiYu6lM+qױj7zjT T'Yy2v =5 _0:n9QZ -CV V)\:)ʯF"+98M|$pUTuB9$wb9=_SS+Ri[pWnk1Ӳ"3sMwj~XYJ !6—Ge"LKVX9֤]fiuW@5KISM _nן@EOL/B@Z\7MԛkqXiQ׵RѽNѺ ;vL  l}4gNGJrJ&+Fi/|TJJE^x34%\RFJvMLf0Ț}'XȴxFhU'P$Xkؖ|S OySz}]rsӐ,DJtܠB6yPqFE] p] @ƈ(ZG3qpMk8.LKIK@ Dbs7ۼo-f{m;aLd$(_g]-fS&L猣_=Mh1tڙ7‘Cx1fVm̧il gY0{}e10ei.Auj"*暎4 VPmNmw ;1"%9I\Sxg:jjOkiORR$@ZjK[F~5*_u4kqO.BФ/d/(b DVv7κ7d($)=%`FB7{lTLĸ?C'uLU-$L-ͼI@5}:+:Xy:Yk.l="NJ\܇?SlX;Y)Ft?kӫTwj~e/ŐZki [;X9TL>U& % % %Cjhyzvȵץ%% Dw!.X–# 0MI;Kx-d]? .ʕY}evԜH?< h7`` GR&3@_sy9A͸ۚbFG{ՙCT͛4 h0@APMQ[k3ugs]\P~w|r./$Ēks,)sC%9Pnڋ!, ([q9֎WK,7v?#UIv$ \^&G+ARrLݍՊE^" ziiLL} `?nY4%n-L =dZaw 0ڟn`Lٻ@It R}$@ɶeRZT@01fLE{l:Mil.FXhzI]=*_K/}Vt$6=ޑ}SVcݰuvSi 6SWC2G5X2?Z}AܴFށG1i-E#P4Ց O9ě݂_!DZjSm@ukk߼| 2JhPJ@J ( ;95=fZ1R'[W) ۘ"Ǖ4剦cdM{7RO:)X$4rFQ0_(/i=2Lsa'Z֊0G%k-'*18_dcx=5mc@MfRkyJ,euOM7d`%~%۷׆"j 2$+(RZjcnz-IsM&`y HSq1Tk贠(qYT;Έ~2R=FyD͚5kbS|(:/u(( x} ܬ;TM`w8`Fb@91#Ok}-Z}>0͇rPmakNs O`gȉZw4K _jq+Ym< \ӳU+]y{c2>V;=”xهQZ}V($ j#B|՝uټ9JX1rn[~#[ko_ yGlM*O0 ¢R*9f4i= CR``ZY" %5(EjksT{ӑҢ<̷89 D 9lVВY⨮BE'ަOǼ#Prs'R;%4&% %rJ&C zt镡 y<XLgejA̸ƚDZ )mX<rJSбh˗/jt)O=fϞYf, ~}& RѢHŠf4%EV&p]5'PUZe8aGpo.u;YwX d#l+pgbW{7? 7U~3A4mCӞ[ƫ h>bLg1 k$7$+;Eý&ujU꼸@8=k"*ךh |CaN_qQ*ջ-f P :O3_fC4`)>nG>5i9;qՊ<:J3ˎLwVR$[8m5 QvhѢE .))QGիq&|ϟ?؛1sLp 9Ȋ@Hk*|5&x98&Xh3Ugz0#mtف*hڬ;4AZ];%c0+܉8 E+*sFLYq`99}3q~aX?11",w=9>~:nJGV.o~)?Z4;'PMv֡iF^rtqEA 8نhDTklwCj2fNLD:BdMZi"0* T:7G2HS8q&O_ x袋|sssAYM_| d*. xIӽڲE(Pv, U,*^*\wޫWqPTЫ"*" HE@YZ 6дM3N:I6m'mt( M˰dSz̚Cb%ĴFVzZK]Vj-ŴjaMJ\ihr8p>"e`sU%DaݑVHbX_dqurݟ$uZnhkĴ]OTJ%ʦ嘊(.cQqCC1ENs=8z̙pXN b>V۶m1||r4 %S,F(~]yJ3 VC/~,2wy *9Gľ,5Yk2Y3!wam>!2?NA^P|"'$2C [u5ZAXZ-l&ݟuUBU)GΗUtɀ/!ET漴3ֶJE㷣duV=+):cLpiHcslڇS95ʫ.ާ ͲV݊E(8l$ db*Ɠ8mbغYOŴ^KkĴVړm(//*’qnV\)~˓QmHTD",1aQ=PCTV`j 할ĉsUZ\^c?.ݥz饗pcĈs $ Ν;#//"mҷv}Qw8(W_}I&s۷o_kyL|X ) )r.9@ W?FdwɊ}:a52- z+ViF ȓdWIxQGXw8[%bŒ6<5U< R8x~zb-@o1gac;^\1@,]߭Sg,+;xtY%* jXZXYuh}`}kՂSQ]@GCOkD$CBרV4.V8=M2Q,b7#6n_ o,G<3bdʫ`'%רښwY&tnow^zjS`9kV5Zku%%rzMTr- M7+TX`9pD7l*CdlKL MV#6%Cs;5-j'<t>JJJMcTXB S.ɱhzeee'%А,,ݑ~2;B=ГJ+HZho@5!BE8wdhBy2eQIoTUת|!%(Ӽi_Vpخڟ4 h 4[miiQ].bU-bZWZ.vU-ݥ/4崢|O'CPUBL{yyhx8`q`!׌nξYZ7՝Fɞit+jO^{^Gەg]ݺ{&ggÆ Ѻ蔿bƌڀˢe}Ƣv/̗5pD_l9S 蛔fa,.D䗔!$\,ݿ;Z;o ֡BX K[^}DppV*ֿ-;%Ă5 /q9<+X5g+B[T OQXX wMX#K(,,q뭷bĉbHZ)"83&B@]ȷ*2!mnJZex'/mE$5jn4{ H޸NY౼ oiV%PvX%zEob,n$3R1~}e1~2R&K_ǥw9+H#@o/t̩>Via/ ZXKRTIm^i$;b(=ZUL:$Dd(c#n)+JaKQMb뮓-ʛl^Ν;&&&ˮnFKV#s&d-4tF ]XA'εz %bU߭W?:օ-FBXS#L*zMlLy%&bŒ6<53w>[T_<:y$usJzhppuNh-¯ѝ+7]Lȵ[ ioh@0 8E[eV iExߎVÛl" F'%XҊBKW_}{} burr2;j#0&O@nxAXS?Vk2.R\j! V3O+trRXPjGXic{bȣD|VnOEh̩}<*.1;&ddVaB6h$Ӡo J@8 uIK5UX6Alv}YHpojW!O}L:L8$  LqJng+VCyd5>fL@K,qڝ9!o%|;Dw$Hi尙bx0jnRrT0'UMikA ."bXn?$40\3P\, C]Xjk6am247UTVJDFzl=LߧZ_N:g~"QMÿ= $#{FLò1OZ:n(&!&iCtbvρ3Nۡר6 v=\9-%L&z^z+"'qK}w 0 a}Ŭ=I־7j@rX-Ԓp`FݫIIH2TŜhZ~L{R)LOϸ}e܌Z1cl_k06d.&"Xb1Wr]7)쬊_k W-)__=NYĠ݌%r݊E(8l$Db?Bb}bpcOj( |MΰC=TEZZq5BZ`nW:1F!O@dSVp ros#}~0sL<(Ú/))A||#0_$0[z$~x&vkC)51-֓z/HG~-L(:%W}vnj9{蠣O! ZCHCg¡O> ¯4>S.Lƪ4%眅>݁jQH &ergAؾ7x )wU*L-JoV羇<}?ۨn~1Ff֐ײ. AEb&Q6؍nNBCE8]p9yKlr%Nl-zX+:ѴBs-Du1;wUө71;wDΝcXnݰELRͭ>Ai3331h $''*q TO E\VM%CTLfǰHSb4#4:MYKQ1eo(((h]JHTEĢ_RT|[LkZ`pw<+:m_/S+t} ai Ŵ'=4 Ĵrj1ć@gD`ʘ޲ʝUׅOM^+CǕn,3& eS3(_:zj+t 㮏"3ˁ x`>o˦b,n$3S;`W^|c0;1z7ejׯQMb:՗D5 hZ*$9x~Du*E7w “;QMbzcg5Vkch(` z+krV ͔~þ6+?]6֒&U-/<:ŋ%̃H= [rFa|tp⃇'uDjVԵA%Q͔Vu`iWlv%"^Dbih͋^rwcYVi+31M= ^ 0VSQ"xx_r 8k$aMKkzA[ln89wøipvWR-',QueX)=f!1bZp:n??%^YPsH88̘B\M:P6Ks).QwF \Tn.gbDLkTGu!݉hu_%g1`#@Te%qȲ_X\Wz}=z2~ w#moC[70n{J15 {vçO,i:V,O/B̀a#_܍ijEsNQlV9igqJGHS(ކJף]`X=1l=RJ1;PZъ>F$C aЅՓn=2`LWqMQv51pXNQ(CsP&uXc]&B2MtPP |Eʮ9g~K`Z\/Y8󁚀^}R1z!DYp@$ψ߭tGB::\ߍ]"ڕJɈظzDup?3&H\+5kF>~@YrjnjZ-Iڈ4 1pO80$`'!5uzY Kh摋`1\`FrkrpOabڵ ׮DIXר-Drthjy੨nvY~蚗ϙ`Zp'w-n&뵲/@և? V,J́4r, fOS.206)T$I:ݻ۫q+g̑ګ+ja5 [E]'ǡ%Erhb6ěwjO43hnh[͖D;rz&@ (]+Q8SF WCX FֵȢ./u8 SOF[S:FusLB43ZDn EӒ^ko_(WHyOC["u2S*= ku<^U┞z.IChqMl(vNN_q Jp:2m""jK$;А zc_.Uxv/G*BT7&?aL x";z0fHW,Xnn;Kƕ/u54[0wyeАm j/σF~5S~ b#^~A?߁ngӮ8.ڕ.7ؽx#Rg(}1 B @i\Ŵ f`L 4ڬmʐQ;x9]OX 6Y0j8M +$;nʈ}ONM`G?Nn > RmÖQѮ XLi*% ^k czM7C}øj4%prmJ0OO+Q Ç'O͛7v&>KW56 +klV_]jHaq8(ê?ѱc'yZCzݛٹr97r-۸Ot-Uwi!Ģs:b1AqV\+V`L 0T@\]3-(jtݮ^wA* !,3 yX;b8Аn۶?h`>CSNwuaiiV/]{!P59]؂ud{s}En?uy <<\nS,PLom-#_ 0>a=Ko|o0W`ۻxc+g2 (o^iu7?uf\̩g}ǝhZ711ꫯ8?'dL @#f̛*z&bŒ6<59u YPlZ%rc<,!!qhlÂ? ǂmLK V[!|{f|Z9aԨQJS,t#`AOt? 0&!B`,>)yRSHg;,rs m&=ԛÙ(P]C&`L 0&`AFS.2L,'b5L 0&`L 0&> h<k|. 0&`L 0&A~Fd ,?#ϟB'߿/5:NbzԩxG0hРQ_ݿ;y`Ȑ!x'AKh{׮]xqL8w}eXjl6>(waҥs=rdqHH\w܁{キQufn  bN,^{5tFW-܂7ek%F={6N<)SpJb6ǎy^}唦']PP ك^zaѢE0+ 6ZCvCqZOjIk@+M!wi71ZX1덋_܎TEر. o\];z\y 6`cZH-0/"2}ɹG'Sܨe0rҭCzI|1k,~{^4o]][{RRREѱt[+m:~2g7mܔְފcG1;qv|f5S{׾ŏFo!~{o(++F-FIؗ. Qԡ|뮓ڵk' t)'=i$ȑ#r5bITI&L/$Ԁ$#S']RyyeiƌnRGz^oL'޾}$_c3'u O?-_KBPY=[]'|jY_Uv\{޽{[fK/qJ-^H/NMMՌSE=zT[@?gٯCOH=j#ks1NإGg2O/X҃;M.pZoxu-kPZ{h{P*uO..ϐRA=b3RK{rW$ X$娚8ܳ\fWw8|PoE _0f')e,jrrԝy&+/}(iQu9(<)egE͢BiegH%I#rnt*;kTN?ri㵢6H&Qާϗ0!fwEmb^lmz-Ql.LOVolpYYYpڴi!1tP߿ߩO3i<[+$%%R)i ,d捩1JZZ. %[j_xךIؓ-0WÇRS^Oe6dM/w@q-'u+/5\D5yOo ?aaasA?.H}Ǟ=~xB֙%J*C osuXQbƍ5 ?nC;\|8t JjQgt*hZy-bٲeb5Widž ⣏>E^S`31.$ޕ@/|NNh>uO}=(MИ9s,^ 7P mQ}eKE3mؒcm%?l}p"dАPr:F+C^O~wd+%jUn7x<$ V/H(o۶MJnnl Sj gSo*[ K<4M͠@H`k ]=¼UF\ܾ:&a;GMjD} _%EbOr5?`;Fi*a|qh-7SPpڦ޺J~ ڪr3'6QL>}K,Wko"3p*ק.޺mvƨ]bgy>fw!4 f ٨Ov{ y«p\x}M֭ed:}4NkׂYoo&oϷz+ /Xn '^MnR}uS#)zM6m$:o j$(АoϛǓ~ GpŔDY+{ヲV+篭nΗ]v2uRMvލK.C4< z /$ikɓ;8 =D3 M8pBm*RM'/#"|ܛ:7Jf*Үԝ{#F_✈*m^W#KƒS'¹V.2q֪~_v'2_Wj}E8(Vg?m[&;{ 1'lOp`J/M.ĵ]N'% b_'XG.%KCEEƴ\Nqq1/_,}RMhցU;:5dj޸&daJ Q7uIM4[y[}rsM]ż1m<v4"Bxצ@.iiiw%Pi1 d$ZGWfz|n&1B76V}X(;rcnCьиX< 6g<y&޺sns6YJΎSC)K2HlVXs/sjc'X ,g͛x4>o z%a%9شE4"݂{G7u@Ԯ]r ^k`L 0&`L !!4!#RWl!u4#ZP0"8 >zOGp_" 0&`L 0& QZel6zR&`xk?:}%^]ycD>bL 0&`L 0&d.is"A*0%"ѽ8azoz.`L 0&`L #weX)=f!1:MxHNt W"^n7 0&`L 0&4"`n4st+f@ⰑӶƶWf4 -قO0mXBFp1L 0&`L 0&Gw}qg(9_OKbj4O>'i 0&`L 0&@0Hɓ:FyGe*DZ3mq K01 <8u98 0&`L 0&@0 S֗! a l'+L 0&`L 0&씬J(2L 0&`L 0&н^}2e&`L 0&`~EsyH4Ll%b+iV SN{ʕ+1d wL5Tc8fL'}2S h_"?T{ڗ)3՞%z95hb. 0&`L 0&@P q,Le6:oR"":^Q\b6uv`cL 0&`L 0'`0`[Db,n$3B0ӻt4{ED)`L 0&`L 0 !`EţGRxTy[yaK(.Ӟ\E0 "[|_[A?RߕAB`L 0&`LJ22h.u%QG#)}KW"2L*ubˁ 0&`L 0&@00@*GuS|)eBb[(Sihx~:$5q'L{`L 0&`LAYst+f@Ⱁ*DbW)qA22L 0&`L 0&zu! \\=F͊rG >`L 0&`L 0& R$NAwY&;0!+Dt`L 0&`L  `EmE8QT{`L 0&`L  8|a߹L 0&`L 0&M@ojtA2{9 0&`L 0&8s+[hiV SN{ʕ+1d wL5Tc8fL'}2S h_"?T{ڗ)3՞%z95hb. 0&`L 0&@0P̅8s 2 7)w_6N }ƨ!`L 0&`L 0#`0`[Gb,n$3bvu`/"6RJt@ٸw0&`L 0&Fz[T_<:yu*.¬4nÖb:y7>^:[H`L 0&`AG@ Ah 4f ٨O%th%QGBPUq`L 0&`L 0&QjLikA %^)| o#qaK{`L 0&`L@+isBSW`kpD30I L 0&`L 0&, 6-c<c GA6k~(FqqpM;1 |>d!-2`L 0&`L 0*]f,ٔ#݊E(8l$DFF)& _e$t*J`L 0&`L 0 #`>]߭s'~qIuxufB|CWĥF#50&`L 0&.)yX2kz^[ d_W\X"*>dzqF`L 0&`L 0&< 0"emsqXZ+,:VaAˁ 0&`L 0&@pP{*Pnm۷{R8@^^l6!.1S05(3m.3S05(QeX?Q1PQ3eоD~Ng}oqU:kec;v n{T{̔jO@`XmA\Zvv6rrrm-O*2S h_"?2aԩڶ+Wbذa^) eL 0&Xm۶2dHc|.***СCw§L 0&o(((h^r `L 0&`L y0rNTf>3&%"RɣH? 5ꋪt|`L 0&`L X XjQo>{EpmJ?(b#fEQqW `L 0&`L -/X: SaVDaK!,|A'S_C[(~90qg`L 0&`L 8Cӕ&dd\J-dFR<1~]!eľ]%reњ`L 0&`L 0 $TRU)m >Ô2[ht:q:l2QkwJH!p d]fL 0&`L 0 Ա=s"Al|x!^ZEIr0&`L 0&>`2,ٔad͇lJQxe(<ķ>oyb 01`L 0&`L 0"`n4݊E(8l$KBR\6:tv.bl옌q`L 0&`L 0$`z]߭s@H3Tj ?F#a8V~P 0&`L 0&AJ$̚^ּ#2-XKK`٠GNHL 0&`L 0&\d\[(zLfAbXo0370)yEBvqi`vN`L TZ,4DcaCAIVH%h7G=\ '^^0w}<MugFI9jw#>qL 4Ν;s :Ԉ&}6_z`U]ë7aV5[rX5WΙC:L1a_[n?-wolJ`WS[a*q8f2 Ag}k']#?g!Aǖt4?ypj]ڔ6q>&o:uWrJ˅2%`__!o¬(-|,q$eFT[vUb&ngkC x?*** IR|r_Pٷ!y[XQLX97eELom[WƯwaŎL!T6$)ݎ`?7Ē?Xf_֞IsSb^O ae1$9P x{PPP̸_L@{kba3VR%VAӱ ߛlN_n֚2Y5PFL 0&pL[1Gi/u QP۲yr#+W#^^bj2a]`|4Ɲڀ # O`ϏQ|}wuǏxwے'!shЩW@¤D#OB/n۹7\g\mᏌl!wά??ۆCOvgE8!SKw\(NRPXq+8a6^=PI_|Oo埾^A3(珯so/'s+.筘}42-ؽj!q&Yr)(w,jغmƸ&@\쮫s^{sPg vHf"͜i3~tݯK2HmxGxy1iN5^o_@8^۠vNkitJ*cظqo퐤#ks K74A.EZ~fv*QbYay#Pp["_KIݮ.edY,P4f^86wE2~5:.et43ɒ$C<_ҏyp6w2T22{6:8~wۘ( ?̞vWh.vnb\l#[lb[P/o)֢~o7H+>fqgGǩ4ONt]t>I~Q\yN2G3Ȣag ![FZ4l?ftF|9/n#E !Xs!_˗8>!¶b݋{)dg ^2.~ i&.@\e+DGb8`L ܈%^#;[c߭=otl?LeOՖ-f\)_bg=QFG'ț3|)Mё\%+,oWxyr;5 'G>?{_UudABH0 `+ XEԺ[V\W[?"ZZVōhUpnvBB=d7wd̄,~yw~ߐ,  Pk}(Ik0/{um:+&d|uOcZAZ9~Wyygmۆmohy] /zs-Pנ"'d`OaO mh+\cBި1q{07tSvrV@{C~kЪw10Oz>+@|sFľ> fxclA,Hz9_!6%#68kϴtslZv^>[[/n8MootrA@h!mNGC{"Lםr5w;A)~r}ԡZ]|I;%x~l&=y=O G"O-~2hst#ґ],ޭ/G[/޻&?5ܥLInDjfD~GH7dX{/.i мowXH |k/ó>!6U>F*SmE ȟ]X|GK5[j*kOX];Vl+PK+ߥҷzfw1 73ȇV1 u+OF z߶zx\5_陯HDEE!svkh@NA@@%Xt ׾-x}x+.VD}ޤmO8O"| 6ӇwjD}f o\}>5:9=Nȱ~L3&u3WHg^5xW7ᢋirOYL,RAksX :e!7('@3A@o2j4 G7EaܹH.1!#\#Vr20ےV{#止'0-? )}0z:noƀ!kT#|r9ÌėҔ8 ߏo=4Rolδ!{--A$[hve|ÐjjsUw4LNT4U RTA@8sX*QNsq4x 3Lf;6'-n}k'*'*&MMW :lJaN@`o6aT|FYu .<#10WWgKЃPV2wln&m/8qIǸ^ nꗋfnq9^@D@h-@wNڊ8̂RAز*MF*pZ.IE~&HKC?x \w3\A6NNɌx{ED[dfVZUTS]+c#7-ڌ_3I721&t7pK bǾ?^? FQ<;6XnEM@Y  gm `~`}Dͳ䎄ZOIn"ͭaά/"#/ [/֮5̕ 8;h}8z8K[}u[Sb5~|K'kvKU݃cDF㻹[?+ߊM Sm>lٍCy% [r&ƢSաoé2m+ɧHMIJoW^߮+]sgܧ\7V8fcI2T-T.AA2'2h!38t6X>sL,XgzWyr !嗆,]  Dh=_mAV}?>ஊ4}.%6'b󒬽?ؗjOv}i-W4KViwt1V|=8W GF笈d^|wi,03{ X}<˗/=ܣ_ȷ "E5y3m8 r @'S:K$vQi#b!!]{^yN.w9]ܗ-+ȥP(3;%ȉ Є8rb̙MWͻ+7n aԨQ{ f@]ei&:wi2vRQo$$S;?pcU^G:y=u=4#ق/iHv}"vkίGZk)a=MUZrtD;<̱=":wن^.ڸa{,:r* 4"bτz`h1C/xVRr~"Th8f$KA@Z[p?I@ ;;]t (! pYfË/\* #FB jkk5oCA@hk7S :f    d|+3q<4,HSq 4'NM^dzp[NA@A@A@VRlVSФ*T&rٓљH:ฉ@;\н^BL+   D0y+m4?c49D)(qds]]E n    @98@OĞNip{u(K    |k/óCLHs#jNiWGT4WTzA@A@A@V^l՘x+17ΝŦV ^A@A@A@FUDFpT>nՉ[\$SA@A@Au!`6c<$lے!HӔL8]Z 6E 'm>>Z/_   @kDleaoΓÍ=bpĂ̵xMvlψkKzDA@A@A@hmkccQVVj8K.gjX܂7޸,rΓ+A@A@A@A!@&%8tQH(Y]ah-G*ǥ    m+A]cd    xC|ro  "زeKיTvv6tr&6A@׼o5k_ŋ"A@FC`ĈVKoVS' Ќ׼okưHA@A@A@3C]IQOSo "wT$kKy" eUIF^dbt[ZA@A@A@,DKm;XmEtl+sql-O{k&UU;c1.   IP'aWpSh*gcair*PǶ`Y)H$u£d`ն,r&-m    g"5|& P}چuV"Ptr鲺DԽ4.   i4j܈S(UZOn?$N6\    JË |z%ƹsd:>xw/*+-@t\г]     }6ΓÍ=bem~9+t" VXQA@A@AU"`q4@IDAT9GYY,|j8K.g6v fȭ9b<A@A@A@Zd]Ceuyd-ƱB[A*   'ڶY56gE)~6n܈7$-@B ==MOA@?2ciAhȼ}2/_n ;K.EJJ OA@Z#[li˘ѥKn-Beo-OZ)g pYfeL/ܖ.4++ 6lQ4B+AL!0bĈ3tkVō1$~c,m k7 Me%Z&@ @y?hA@ ͇"?zHD$wEH-4Jq43 6&=FF^i'U^2zTA" ~}2rA@hY.Ŷ`9ѱUݳ'3{kЮPٿƘ- 351:SK @# ~c.-  NP'aWpShҐc49Dc ^} urptja }0KA@>27g$=A PPנ"'hSC"}چDJrq$~H߳ߔԫ!I]A@Ay! ~z^[A@E@ݿ ~1!}΍H96ǿ LO`F;+*ejA6S^%k%  @E@led 0 CƼ'#^1ƹsXg 3O߆ x%  P*i!A(UA@faIWA@P[˫`D!I=HT>2 J5TEm0n$-o_@V~SśӒA@A" ~}22A@Mؿ##z۶hc)"jc'ʻ@D`Yx\ -/괘xA@527'A `̦*_NߚΓÍ=bpū>6j[9`*M9 5y%7*IUx'/A@hȼYZ;|b&#ΒYM<5L,)C%4ۢ]l N8I%yCh孜A@揀A@2.24) @;hْQeFݴZ q~S K._Z  ldoWF'7m`==e+,5'^ 9  -[3  }~ S/^$t7lm6r-ltҥEӠd @ȼ(b׼o5kVp=Qk>Jۡ6ې@E`ĈMsͬgfmf2AL!yߜw U+`"Mmh/G̈́]]n4护+0ɋ5B݀)YA!`;7VPIS_g}/Cl2!}΍HޥjX]~EPD/7%%p'S^f1f.3L>ßؒNbSN=KN&(EX/sw}ǵϙ꛴r֫?\*3oŦI6t3.e|[){>59qOO^E«^Cw p/ضqoyFr.A*L3##"das]!fb>Lf]? Jo87.aLC\j||?y1'lXq?D(#2ZDYM-̑j|˦yB7z5 £ϰq\${ww"z]!->0Y8L!nf7zѦ=ttGDL: f6hv:T1PC-NL9]?@X42,xQuhq=9f&Lũza^ۮ,W01URV<+ĴПҏŬwe6ZsjY+`+s(//Gtr<>SA !9:2T-@M02tMV\2ԥm:ViWYܗ)Q[Z._<1!DJ[,~6}]I};(N4Bm-%. \;'m_GfA)LILl\Ȋ*"ĵl1jg@AD:>,v#hGi$RisdL11Ju)Z I_: Vʱt}h)V>l:"t^̼s&1/U&jc+0۱l6u4h6? =ܿy(7my`Ɖ9$˙ ?2U0%%6픨e"Sk&g_\tꜵӬv -Q+ې}׬ʢls 4^@W]?ƧwT7~޽+wa^3 3+15&/9ṴPQ| D*b !Юp16&CO#uBqI;*;j>0h47!خOH3ꪰ~G8+'߇{tIfoTpT"2PiuZ—2b?P_%3̚Ah dژm9z0=y=Ǵ~KZT˅2WK/ rKCϙ%PeaB:3(dWH?S 6u&X G21ap\xuU:$+پg.&lf 03(U?E\=s=>yi5gZO>Ua:VQy^>5Ww &T̺O? [nu&y^фXR ^Z[u4e[79l&?븘>$IwdL] bdo46UbTe#Qfk3qUD9ozD|gC7llݹj{[ e[qx_6z 5Ҋ\3)W|0E|mu%.m[id{ q,+$x? k3f(Ȼp岉 1\]y(䩹h ժ:x駘6mBVLn?~;i۪g8iB ! LU@2Ga3ޛ:aNBy;m lnRnҳ_P6FDR CB9RuI L@݂qYQ{zZ/hs`,NuD-:sLTW`v͹?VUٱ ",sE^~ʞeppXS=~Z]ɵQ빫v^mUn?BWeY9_jZd6-" <jyajB7ebl*t NST 1f{q 56E.h@DZ˝GsFN""tft}eTN.B.F*o߾a:EfffK.!?e Bs>v$n"b=Aqfk\}I)u}vgb2X{u-:$!?SSF26K4⇼ :YCusWWY<.&'o^>\m*};&˨T7c)$p/Wjn,{J7M— vYx8~]Ufu❟>'2c %8HwVD"Ɯ?kP2- f"?zHߴorWJ{C.BVnf-F%wBrE97ԾXV"~/-΋C PX`]qD}dvj`"7SyZ.g<`_NUW\=TCa5 }ဏLp N-ҟXn^*yCkᜟ gqi+؊ [?TŠRlVc[ (sqZtڬ xNpgHMZW0y½X7_1 0mnWqzɯС2 .;RĹTV/[߻WQ*M7ylP{ˏǵj)]uMtqB494t dWtoORVr[;G]Kݎ^8'F}8q:V7i LU/A@hȼxgr7j^0&P1NJ;]TX1[6PfR:zM>k̃#+U{!!WX%Vk"aFV96\ qҧNܽ'N|i5~G 䞶 ӄȗ Ђ B_MmIT TK48\spAYuTD J+(N)kGEK1rX- Cj xcC/܆;. %?? ȗa M{ADĉZPi|JspTX:iUsP51(roAJhsbݠn|\SǑqr+0Zi R;~Q1 w~Ldߎ|]qEu?Bɹ y_=35+ȨyUS&e*4՟fz/5AǡXq>kCA$M-cA8jM|}OT|iw\6(YpFJAv͌ϣqog/we<=WiڅXۡTdm>]{jh־He4sf*YȦI1rd%>X:jE.}x>' }ӑXg팑!4<=:4b1`Nuew^L81dW)Mw(t5npH G6%ckdz ci5+Qfb*Qj6[MjCV[v4c.SM]Wb3aV;՝qB/=FbrEk@W#>'"7dH#ts<}*3j&XɄ;bf0bĩg߮HJx+mv (˛"m)|mzom5U s<93Dgք97"RLX|*~2}522w3/j: NDŠLddfè3W[=nrzzvWC)7Znl>La$*ב 7'usOěě˖-i|k2HuOW"ҪI#ur *EU3AV%vdxM⁸0tiQu2-sgÄ;M??˶b˺"tH\7cm7'xsrG9aƁSxc2j ]{ \Dv0~X]dF}:Fƹsx] kKeYoFT<8U J|v M͸+iJҔH{G,l p' Jf(56XftCSmۥ6W85DYPHvIN57gj44H_$҉6m17!3YmoоS&j1s6g"Y/oE[M;\^63&9Xd}Gai];'j[e9JwƸ}I#rRaݺ=jd>i6GQJ yqi]{=4e/*eg)$plg`h~gB0I3GlyIض%GRl"E$T}031_}=c50ec_fbd죺6z|0Y /nct ޅ 'PxsOCCY72@!ӖZڧGb&şxJ+ݡU[I(_dEen[|9QF#Fb͵\42HQE7jN76 M[Gwjsz̩ڵM"m@M# tXW:OH]Diw^AFrl,JkURsWdux,K;!Ս_Qk̍Zs#ްc2U?I*/e ~ !Џ쏡u9؆!Hƻ;qS:Ʌ{̦*_Nr'߇{tUk'N膢SڅIэNY7V hZ!bqdrqLҸ2'|ހ i?ԴVtM) 2G1EZdVIkN߸#"ԏ*KGyurMYMωM+}[*qE oX~E8DU#kNϚ8wR ՟m;qgjV\p0{v(N̵1i&QmgB`ſ/CIJD|D12Olfą"-i6#ÕA|m6ڈd:xb2=;J,c.HG xUiq[/#!d*-*YQ 9n,nd2ch煝/ޅyˆ__[ΦpG11URV<+Ĵvh(^Z7Yfˮ;Ȝ0> ux-n_)/0! o`۷T%t*F ;l ҕ@kh/cly2Wd>c"{;vE1CèWi7ۛ\fz>b^;U `ːJﺕgp+6AS+:65?no/E/dVWoE9SoЊk _Xsk6:Lri92vw!͵d?|rDvB]WdOUYp4v(9KX?  Oc?d! 4Lcݐա҉T3*E. sPj7 :)7%$Qؾ=\7 Y 6yM)vo 0.+D`0Wr]~;6&WGOMfcЃC5bE3,IҴï@Voyr&xF1fѱ=z;2T_c'?\s]3@6t`S=D`԰=VLÿyʩN(.6 'u(NK0Op>zvd5V3VDI*7=&J28)9|n$ e 0apX3Hg"ɼuݠJ{PTKA_JmsFPsocJ{/${U @͂ߐ)G߶ϥ]okzy^puj;2\&Ϭ%_1XWTIdOH &B7PRhNJs-ʼnɗrlfF(3t`}9Ft3\-3/&W쿫<dl$NJtZru;Mm84tܛڟ1>$[LiQV$Yl~U[ƺܮ"J_%QO/(Go_+,_A@}8/_@Ko Hp,5tF7U} 'i(Lcl-\c9_H?7[lm1eƸjZڱ!PfNS'fWX}^E xP"t&L#oM(AL|5 "'PFf*ETWhը/ƹUQ[8o~WnF.]kJmgr ywόv"ZgJπIhx*k T[`}>0q䗵Z3awrxsX(r{}m5#d%I1~*[&;|9_}.Ƿ>ZiGoP{+y_3+K$z?WK+ Ϋ gI$BQi!93}7==a(mo|dϱm*7᪸tg< nF|7=9߰3>,ܵ &&m,.+FGL+V{vtw#/!*#K #CCyC BӼ_Ufͧжs-\ h.Bnȩ[GG_E#ub4Rkcy©`ŒM()tؐ ?[}/gh-' 6l@(xlGAN9%:@4 Vhk:H;]G"|?>`m8w8D&ܾ H&Wx3bc}}1s" /Sֺa3Eŧ_ң[r1v_dIE_R bW-5qxʇ<.,IpF9ef~ʆߠDOt횂U[)@IR|""yt\RUAAT*+SZ Q!\?$o!7QG.^t.ձbCƶS%#f 7+E.u(jJeonG.Gg-} 4>tUsI_ßgY/0>v᷈t8xJ[sLw9qNb(]gMjW9ML1Ql?dwi֊L}"}["A g-=ȥEvԝŦsV)O?Ŵi쭅+d۟Z+nd_PjzcC25L#;6:6 &ZA4%5 !Z@:T8&oO#u\*I `nH;28_v B-=rxt̙B@y^L<ﳯtuM r#gdZrMMW^+_ӆQ]ͽ]M ?\W13kHR,M9 H5G$W"ݤ wܧ +Ä֝)q|$Lrm-/y٭ǂ^n$ Oݳ"ү[=hV >|Bg1BٲےB=OZ -yeLJ>N>5W[)ͱBu%ƟgOFg#тe隢b;Z̿7oX*] &OW߳`k1"XpQ?bOPYW +\Ww[R@J"UydU;?F2i,2?BJ2jsoW"5-u8ȴc>zzGfWH-wɏ^ZMJ! 3jϪ^ۡ3DT}SL.[hČ2vm͗n ~׮$Z]['uݻ_pBYC^(D/\Yh FL&&r"I<~z*o~r^!~G"Lr-hcm6nYr2={I`Bc6b߫[*ؾ@ϼ]ڮ0dKƶ C-KCuu&7&V T-|cny$d +xtOX;*_^nx6qW(q&lxZZKo%UKn\(Ԟ٫ȿce޻8&2V*UT Z|6)}jQ%\ ՆQ9< @98@OĞ*iTZ*6+=}V#!?t 2DL`j,qqqG,F_uÿI"ԺQ0)21d2js̐8٥;qhخh\Tޗ23oLk&a LFEոdZRiZHY&FCb8hNQEDsh+1Y_ aR-v7l_Az MkLh90Vv6v # I0Ք{DznzC3Aru4an-Ȥx!oy揜d&M*bĤHFvFA|Z3nwY~Ҟ'iep66ڦiBe5ݳW{u~{_?WzϼA+ B7Jq1Ci1϶eufްVmvOHbi8V\qߑڂ͸ JtLe?E&~;H-GA j/ól6!}΍H9bD{u gje.iB̝p̋5C_aɑn5Y`3W{$& o΢t&&Ӭu 7 ;2[u_;&ulh}]5 -DwC!d;.2fi0yrG]h_ȫ ZjCGUmD'huC}D0OQ~FU51WHQhd@t?Q[G\"ImlHFG|_M#YLb]'Sn{zeFu\MSe\]Iq2bkQkGәl)s#֧?f<<r7Y}XtR5ۊ\놐kebL߇HizfR}4K׫OsQmo4mkлk? kPxyg}Ҹ #Xќ$I&Ec㷩|hiש׬6D[m|*r.4BWcޠi(<. Ewa E|Tu2<:*ކgn:1)HɸA%vx;f\5J{r*}( Bϳ9U("*sl+,PJQDD"DGcI=( Xj#ؙݵvɴg eȴ>.CYޗl!Ns:&G7#qSR9Ύse ykOi7YjjwHI .ZDvɪ>ҿ ڗۃ7KwTP&L?%_TEVa=ՑLݜxYl$ɮIC)/._.{Sk#;`|Ijnns5S%&lL,b tY_633bõ8_liY%E6յ:^| 6zDC9پ`Nd Ճ ek]\Ͽil h,c&l]aXkK5Nwu`3%{gpbs'&ٮD[)_@ (ڢ"9i+82 J#]ة^);ucElp+qV|YhQZ}f#-7@oӐb0܉Sd:Ԛk=4GџIk>Z)`\I;%=b(ru8Rɴ7so6:wd%x[L'd l^J""[8%++Ѵ:b4RQ;֌ui=uL 8)RݼA"`3fr+w0HR*-КENdy>#X3YVDHt!+p'I4'&D @#HCqtBb']5TN°l/ 3SAƓ+߮˨U:r [cΉt)j,＀+@IDAT9f:~B _t6{*-<{$ߨ8ƨ/2kw~5[KXV+j̦|ߑ~ݑd=m[t3XǦab'+~F``;rS1e(F>yM=Fu4wɟ:)Q/t̵>ɴenW s `(QkRvko'̽Mݙ{GF3GܗTd6v@ͽ;8Los1/Dx=-^x~'wm0D!. nXQep&vqus|D"|n$̼xé;1yLW*Ed`\H2sņ]4i(o.ZNfMc͋KvESC)c;Ͽ'߇G'$tL߹/`MNeeeuTdYrqP{:g3s^ VKIn53p[2&֢"G2+4Jp̗d8nm_ִ4W<̳,&3?FGXis"-+0Ĥ[%E5k9|_Ii3(rbnH[d]Ce HS":X( eayy%=XZ/Vm uilv탻k&IT""ӺuV6] |`Z^m37W%10AwBEt^Vcn!Vm )*piZ) Vo P%z!R2|R55*hV3VI4 9 -PJ+ftW4jx1\bH2X<9/&օD,]l 3 c_m$;&sRuiY%V5I8vMD1mpCifrOvJɳ&xSY?;m@'/ծ9P;1VĚZ%<ޟE% "ͽm2jlK"kiɸjGE܁Ea+ͲX:}}U{zS߅`7Sߴ~w(nw(:wMiyli.k5zp#LiMfNdѬ_gD{)"^L`toWC.%̽H&ѱ2$GeZxesic+B梶ӆTSi7|W羚k"r5j9~$0EԼτsö:Vi[a+vmQIaRwު*ϲMlVuRTGEU*Eɝ"J<W54a^[y#ϞMyz0n{es T('-DW3e%&J[ 6ص-E9'۸HO Dzy*?kֆO;/X]xq_/S4OS+_gGV:wV~9^;mķ5'6Vp(f!uyH&&%ӪҘqmLּ=&۾d8VoLI,3QmGh\+QӪ>xR%jwm/puPZ䱶-il7)/:5-[4!4gggK.M?:y iY$ݷMwjHߴ6c c02#U ̹j=V0P$QDW򬑼q&Ūz= m@j;9@9Z N9mN}p 0x]՗,GadQV+[nI62$[7 ] KK_4/<:.]vH3W:>ԔQP faN\hXcO{?wQeO=3<-ZkTKzsآ5{^Hȼe2F%`XI!tSjf7ZڼﱄZj;H-)"UD*MzK9# &(֛wiWa%~xT+9r$u+0ٸ-{(\U.{=:wO.²rҾym&)0:Wuط8f!gމ^>Ue(D5"Jwb<關|&(<3rsp: R#G {TDJ"{ t\iEQIcCU2 5VGi)Ӏsm2%Ƚж+U:~+{E\n*ڈvbLʘ>nri 4Q_vdBjjmaIcMy]㙏CM6o΄wXXs5z=Ң tóY1"|(6( V?K ]$>_܏MUHKb5CWT lۍ琞 YiCp:꼍Zi]aoMT=.׽="&NEEr'مD̵8ݕ QSt夌<[kX(^ OfD/=#6+ԖliuČH$ip2stL dJ2'PdڐJBWЂE 7dLS^"uŽ=XKhQ yb75[=Ng7~x *'̗{C`ma|1k9خe#8]j_YB p$Lx=) +wŧN7~_[VX}kCi8c/eIb ԧ>IH%WHTl)݉r!v'ҺRMyEE?+nVVNX rtJ$$1if KV!!6)*'>JXjc;3߅=qc}m(RUF{\"tUa`4*ii8?A HZiu"16 Xӝ.Şy({U/O@ __XtH]?$` zzѰI;3k[|!Ti 6kL- 5M z{K#/Y-c&uN o6Iu WJ}fg~ hx(LMSnc!B\&֫77h7tcŘO'nCY̱#{!nbMi;cCWip6 r_X kP9dL "h4#𜲦-ZH_:eBBMkZAe)Nj0M8_Ҏ155J(>ATxHW+!zpܽd(VMTJ6ي}㴒4emv6r &h~*-&k\Cx[r+A{srRfF6]9y?jc_9q֓~[=*yyH# ] R}7{4ufD{tb0#oB;stfD(,=>xr}yߎVD60o>HĪ{KJ3qBjA;ԠyxX-<7Wh쎇+jhHE0Ώn\7ñ0Giͩ C1jM-@{rSMI%$+}*<.q{ĪZ,-opFvHo{ z fRP$'~?^M yns#yxn"D\$Q# i`[x10_=kkA-=^]ӟ{9yilGi$cڻ|@4,ٞ2<$2* A4k=.[.f 3?F򏕏kΞ}{agY=]; ym^xSAřNj GF0W!NH_襴F|)b^ t4m?CI&>7< Yxwa_|5Ԡ&^|GލY0xkp3L۶mSM&SJ/4.eͶՉiC-LKr$9^L?2O{Rӧ,=#ZG8ԪfkNb+/ Ws^មg0q?:a4w2~9}-XuRgWtL$f~->ݸjijSFs.H-Aϡ՛h6S &<_5nELAer;r[oSK\7Zm[k I0KL2H1잂 \)et#Oj'#DJYeLM3 yZ!MVyh Z t3<ȱmRٚs7 hz8qE0Y$[:'csXy/?$ @7d7*lZc, Z~XZK LE'b¨v[_˖h_MoG|Rj!Ŭ;P1EM.rUxg"<.&8_ }G^lt݄9 ނi/cc1zlmF ԩN&ϛzi7ؽQbP+Q/+vB8GO؇*~ZQ .v#:hH`ڕZ_qYM}DyߧGPbLTN: z/ <(n~M8#h1xbD 4;!{z?Yr$TFĮZ!*A@΀[o|;?ޞק:g~ ŶAD,; X^J%V`k9H;_JjE8i&L,ͱ* ^fQfM3yAJsJ ϲ X=VُP P4ЦxHK{";ڷaX.]lNMOWF5؟])?9^J^6Hg^3o[ A~ey_222,D$kP||'V~ RpofcT+yWsP7iצJ=[6:a"|25Ji;^\:l {F<߄p'9)4}_ދmKUG-..ղWۃ ߅M$ 4*d*#BMjoɴD7*eu_j|qqшo'Uy[>ш(#rn+ie(/SN;fxV3h j-?ӥ?<[KѪ̺Y7W$HvRRC'Bcx3nOfܗҬJ.庎5W=FHrS޾$rJĵsf99&_6vG,%KYt&I?'TXwW6ώzl%>O:fMdBvG?X_PޑftLo AQg*YI[m[Me">ڗ fT{M?]yZ¾IQFb>ҫWKyxщBAqջN"TG(\9~x:2M B\j I,0*Ծُ`iU'`IE!kjLSƢZ[ՀTK^OɴjrS=Z!\4=KLҞcZA{[eZa=nˣ2RK)4hUi%uMib;u~sr#$퉏6㫟c,iZ?.N!DDk wz=>ּzOvn<:B RNhe>J:)V'_uXHa\bWvD)R]uB/$ώ;PTGA`[;c gj֞3kzZpG[n=ǪUh j3 :u dIS@AvTݤvU( 0c,:́eXX!xR8:n#8;gÙ/`M)m۩mB2DO[Q^3GI:J2B{&s5[ռA2]#bzi_սeOrNV'y jrMtAk7a-B;XV.1${ݾ¨QqF% ~g!e@g2oI[R*rNv1ZBJlAz I3򬥶P1X4k \ M2=UX5Z5[D5\/r+-)%WȴG$lkپ(y$?(쓟  ? T&<ۻ,lˑ+jL^_gǻa0LZ{TW*$mǓb<2Ël*!(=oy!'APAVtd/{2ieE -˪d/)p zփL+I:s2muR*|R7Eu&"^wqU)ݢ65BYgRhg t:_CBWdS7KK(~}'"ynيF9Z:K&}ȗsz!_nc%v ynqEJbRP`uc3!@μ\JVIl(FWϱ$>F=9$LՈ6\K/AYYLTB gqt& ztdzի6jۙay1jC5R/B[=*QxAo]o[>)V`Szr=T2'$>o#BB k?F?&& >K]'$'WŶ"JDMN|j=K_\9Al>.^nxOd3>3jKw͸lyQJkz/^)d|W]^ȏZh~{ x58S3Gi)UT¿P1a//<ܱߡtlFk: omwEB͠!zmxs/z'M2\3)NLHy_zfCm5!X9Zh8@e;մrm{;0sQUeygiG2McD6 I/~Qʱ& ] B][KGp#ގL/2m#w2Mc]JF̖:+HҬ=J#t #NoT-lFHQfN`!6{""LKlKx#,srS")ZV࿎5qʨ6Abk߽).v9qhOXjS-|NH ^$iB)?O{R9dwqOi{Q=,b jDہiQ[ yv Zd1rgسʒn1›vΒf_pKȂHvvyT}5'p9:W>}N)&k b bHӋ7m-9+ DPT~4IFCa.vˁV> ~Pxp?nOB|6Ĝj"q4ivϽklgy9i `$xK\mrO.3e&\AwGҶhc30yQwoaK=p7&uoCMuKhRYp[J-Q{qf.䞞(.#S2 ,e)vݣ"u9,<`v8_m旸x_v{~ =}m5g;;|01},´n}RQ4~zPAqH;:D[;MK5q$J\O?v\*{A} &v 4a i5 6Z}4!2e o7$]@dY~K?(m=d6M,O'ռף]:x@Ƃ jpj$ސi VMe^:**6 yqsmMD;2J仾Lxܩ{72MhzVSyٔw$0,T$ˮÛ"G)5!IMC-޶m]bb"(ǻ ⳬ1&F,W/ ,#qX;q=p"|27s^F!nާjr9RK5i'Mk y# <)#b/ɶtEev-CBlUԮ~:\Hc?$9$Xe)UR}af^j}O}oM˓ m,O蝇} n}rEa}Nxj)гo:T4`DJ^. V(ղZtN{J]ijGMX{d;H͈T5W P% znԽIVcsP{KRsS$|͆IӞU5N뮫 .Ě2MӺAx_e?y/Ҧ8i;_ }G^ltmڊr㙱])^_; nq݌@EyHt ?5DUUjX!H鹦ջװ {T 1狕=vVqE}Lu4#*ZIWX>G%$NFnF{(b* cu/?=PXVT5Ko@UJ;uajX\ +6$iX̪OQSR3q*7ܶW𓸷;LK {vW>=ygܠ;1 @KS=c1ѱUՉ'xq;-^^(KnMmk T9YmuYL-p&##ZLlH FII>O> Ҝp_Ex0wIa?-ᩔgdXMURCx%֋X_u;˘ݕ3}?d敢ߡU7bd7ҫo?_\m N{B 9-N=yWZG~g&hN2)y$Rb.R-؈9KUsyNcgRpy$%N=7U,rzɋУWu(v\tQZy嵐Ԓb)%HZLAAtbN>ѽLțC+IoX]wW^]s/i8싎'e?sx):_y}t6m 2tz{G &̛;ŋl96>0fL Ա LQ ~WpU^<8v4ABM*^O&+#2Wd"M;%h_:kjxɍX5ASǭ-&8LpH2ms`{"&R\p&ō1$YCRQS뺖g/^/5z'(=LZ ŋL/b$A40*Ծeעp}"+td55vGC, }Sʽx41\USJ[ps_1?!נ|#ͼ!~*GrlGiO>:ݫuUeդOp's D)7"9*񢺾>nB$J1 $*rxvR,'-dyW"67sZ|mYQ ZtJUZ;>r61BovPS&888/u *X|(_F:'c+9}~{vЮN%ل/ma(R7qbU` =_>ፅe"t&4)Q;ir&2+ IJLNk(T v8Yʭ*Eyzdžsjug- hX,B 6LlmݝU龐\Wq&e|%JCLJfϞ-`Xt*˜CdnŸN1_xuOr=8/wz7߆rƧ<q5yu?K+W!u{vlf;^U~󾫗}"J;'7q_>×XqߓᘏƦ:XMq*g<2V"jofߎ9&Sp4w ޔwQbL45IĘJ*mT鈛v<׳/TXWjg"ZzV=yPrP jQ"%\5=Vc'B"Rfj{ĻL|>n x%+~zsƬk`~ uF5 LJi' M&M͗_NnN62;n"ӔN[jXq8iǾi4cQȧ5u$U[CtD%|P ݍ+Szxo֡pDFu.f:=sGڣ o[~PX|ڧ2v ty{w @\-I|ĮۄxܹV|>C+1>^3 S&ރNܧtwRI2&E 7Bm 6TVzLS;4Mb&jI/}qtRYyV%b'%JID 3kl|ggMEj{ۦ/y޷}+f0` ʏVa#713t¤{ƢpGk<0 i}er?;ޙO J(Vvjނi/b0ی\AS5W&z⭮ŋd[iGcs7(njdVc ְ'w pibQv6Ar.wNRG8Kyٔ;[`JҚIfZ@hKB8Xj~ $s8k5r}7L&{`ם˗`xsUbccOԹH;qU "8﫥TRMP;1d/&~kokx})H"b[H}_iN:_t}Cwha\{3椫%?dZO4R;]~8yjf)/jQh=h9(_"גXS,;vԩSoqD ߊ:p&)uQQIF [K_խ`_~خPu0a;eb\C?f)leTkP}zH;qU "8ɥ%yK^i g_;S%^3s($eGz?SqԨF!GPSS\7濁 rq))H6yݳd4"$6#سR&69ubMX3:CbM(:zARaíukXKdi[˘TTRI45c|N7E2MV{LSjm:dRjAh.rPz|:< zՖ:XiOT4znmF0wil  U'ְ)Q5aQ:v&3MShE |}"5y\LOu9uӭ^24~j;q}> .j֡jd<>rhJM] 辩1m§sN' uUqg8u n1ʼ5XXK,q ac{~E4_b0n#8;gÙ/`M) 1»>\2ЬGMLսMqFEqDxgRjMP1iУ=wmu<]oذ999HOO˴׬ ~MA0WTavmTuM|+?I;'vevȋTq!yCgOvm&I7y Z`"$2(Cl؇;^pȡOƝ}5xs}̻PVV0cJHA,N.&u[8e"V)(? 4͛ܚ/VBv<ٶ?}+xx}7l[ 9suJiR;d`;J޲-Ӟg9;K:z 5@gK*r VXjPVT6u^EF`z=\U]h@yQ%S&Mzc )NOUYυX%s> V<<*.~\b %ڪ}3ʷ Y@`.EVq$#{‚{=%-b_r!^/pO <1Z{N&^LML*2!`{K,{L#'p6%izWrօ&nD ӍvooN"1_%uAIQz| ME +κʶeBl[~5QB@c#⮏˼o^5kT,jW;A`!!W'T:4=M!!Fe$F3Ξ"j(P$Kb|V#E~ӱc"T].:$r/e : :_oxֵw'!BΞp;@zc͵W_jiwMLK~Kg_z:L3kq4g(#*>|ِlo{[dg{Ӭ iNgۂܥ}WϿ\kM@I<<$YM{O:!nYhJ6ܑtˆH8mDɓ|' Եp!8!Rc/.ӴP[+ sWsӷ)bYC .KqWkOGDD Zlݒȳ8 FA\HRc{Oۓ>?ъN*I/ٛ~K j߼gc3Q~``>7N3TB-ep3In"#i~K[ͩ qI%6q=BE8S?+' q \+ab9/JIDATtZ9AKgblYcP] T'^մSs]@'Vlm0fv1Қ ȏOQCBt8I%4vgDc'ݱͅd{"5C:-$q>TOhlyEdu~osQ3-zSi롵5]Oi&Y?qcOcx F YP-%J3O?d+f\krMuo?TJ=3yvrLiK#JD) V|$Knm0{;%9íc*qgϽ/M m0a|ܑ-&rl|a,)ę H8/DE xH/O|' 4EAzy .3rrTUWgz>d3yn jj)TIRc_$Β8S]ZY.Uy=|IUT 93n6BDq}77n_a[`y|W}̌#rޯn=.tSIM{GrMIzMQ-%g\Ґ vw9hH,LgzmWWg_#>$<[)$u *X|(ֈ[z#=^+cAġ许}rX%HBkCVͺSZmNq8_ pɗ\\]F!M-?kݗvw(˳;F|L;gi_>v'5D;?A*9 vO'9o8;uNoΝ;ѷo_\m{Wbd[bEhLL}詳aP׏hgR}DM,5e"52=үܥ-[#[S"ߡRV1yV.MT0ؓu1*2߾KY@#2z Ͻ:8sbC]_.1ѭ&c.u`pMx\ ܑWJ,/>cbjPZ$LI6׺&Ԇ(&_Uȍoɽ #1c`1YuQ4IZJ-ծ Sjr,ϗ'"'Jٳ=z4@H?xg}â=ZG^\@sD 7R*I%Է"aMlSRd*{-l2in䙼l6:*!碿 'AMIzLA䢃xG \L6MAcRǦ@*Zr?o{gM羹$؞Q/$$<"¾MaՒӭ€)(>+?Z?ƨw|Z Bߑ[-0b|7D;eP0L G'wi-2X%馽E,'R'6!֘RUd2U%ȷ=gഀS"j1nGQVII-⛲zq@:sRtzʕHMMuj/lD;ބgs ~ n;m_S"BX[4vץ  HGyR&ȽAgos3'*[M )6YsK,{Azi9#<-$myi$odfػK$1cI9Wc5A>x)dPy-ib1,Z`\?9W bO6 Wփ㾫wDNQ)F/;ףp|,$mR6kWOjɡB#yw|Սiy5^HtԪMiup%GtLÉLG*~NouiegNyfm;4Q!d?eb:x o=zAe'ADAyW4LZ 'OP{ae8jy݄yMUCmq~87Efo Y% Zha i0z$^>d;ao8ή~&UI(޿Fm =#$Tj 7O.`*n5閄۱)t5' i2ܐNVrYHz E4 JRjLJbLq_D%ܷy3Ǎ ǍťUK[h-DHm,Gg@l21Zi2wG6زC2 W#QH0*\VV_@("̸ o`i#DgȑJ4:iW@iE:-z$ɴ9 f%ۃ {ꅇq6 I"ρEbY}<>_lOQH-L3yĕ:[7ȵu%dKYLiwRkܸq/Ւ.X=0r VkeEjSxǬwQ`IcA:>|xZj 'O^d'Rns\pGi WU3Om;3dܤ cAA ᤔN{|ss<$rO}d{+i**޾) ȴcr昋 );{Ng(6ϾͥDי$_t}/l<;ƶ<]Bm4:)F`S4&%^JvftJM< ${$&v%*iii֩o(揀|yWT-y5cX`a%3C@>"r$<};(߼.5 3I6ihP@  DM,¢REk'ƀQg_`i^M@[MW*V ĭu2G@Meo=i kb ip`恀ɖ#y_"`! n-ĆaXCt5C]a@MliVP&j+<RhPV'v*3Rh}T9U]Տ֜ 'U܌@SE&UB܋G 㱲6R?o*^oF 9y?&w <fn+րQYxpր/b9D#uV5YŎCM>̚{7f_?^#E"δL u]]͗Fy#@?y]~=LrIohPd`y#ɣcB7!N2#W!"&-R !l{ '̚IS ]z ӦC٨PR+p"$ ނi\D;zlNZW؂WWWcɒ%8JdPPMm䱇õq!߿wτx$R #w!-{ޥ,so(á}*p%Ƥ a(E`Ɩ?>0wj/5>u8vtKr7a.:bFSФf\4ۖ9W#G*H'`R"/Rlڒock_UU &Gt8N3 ~냡 G!*: y՘O-fİ׶ɶal*!] eel0o䱇õ6lO}վ(b'ߖK"0#0Լo,((p6gF`F`F`"|^r K&B?r gF`F`F`F!ЀP߲}E~D!w+?>t؅J05# S.WţXY2]mjhԺ9g RSҵgW?kNl}3L} lCa—p˞b=ˑgb᥶1"RaoU'ݵ{xrm؈С|GGQ>޼]b)>;s+}F yz=K1f|K¾[I'g>5 hkб%kݘ5~ Lbl?^#ݰde]e\N6ߘv:rsy'bW6UboBOnoW;A2@pp><~p[nkPbϰ ̻f+ QYs% ;,1#;[{f쉛:@>-K/ކE~0W J :L>;:KagpUMBM]Z@^QlX6{A,R*:NVQsXLh=9WPr谠q9+E;_p}퍈( .׸;eK9Eb߮):cؾ:A30J5q'p;W}A}@`B><_\s"J6Z:Ge`YĊ<%9q^ՃTRNc^vj'gR97tƝ֣q+CWuf!=?gXP;R{s}S@wKvU~vUU]VoCV_@q4 /bi~BJ{x׏ oDSayGw=缉Ӗ=R$lo=O\c+᳓ 0'%PA.0aQyy8y_|sE "&-R !l{ '%pI[. mS ǷϮ: g+ dH3 V/ IVZ,?s|rz\ GQ8D+tb BϹqi[1x ED.MX9 cUZ4WW ԣVouظ.tn 0$5 iqzDI:n#ZaqXӯb#-c,bިg~B ecwz+ql oq0 8r [i`ol6>xcs=c[bo_3_ .ʽ[\` wsO@s<=ONs#\dZjVWWa]RdʵdddXiaV˺?fZ>姝st6oZ?ڇ5ܢ/:VK)*BoK{B>yyWuP;-3 Qh38"$؇sˌ#@'-P=|x8tYA8%kA0#4K5 %`<(F`F`F`F 88%yUDB:eUIAhϖׁ&\7#0#0#0@@>e)oAm(<𻫐b)OoĈEh/:X#0#0#0n ![LS)HP0wj/;up3 Hvb ,*+@ϑ{`F`F`F%#`?| A5 c,8kB\] S-Nf˄Zb{F`F`F`},1ŅRY폇[uP#K#0#0#0#Ђp f="~['0qnA`F`F`FCl.<F`F`F`F@An2!aF`Z vj1c @бc@73#0>#y8}t;e\s#0@H>|xHoNb4!XF`j%V\WW3zi1eLG@kjjЮ];}+mᵵok֬[8OœjcLSпFO4SZj[HOITFb0xi-+CmL qo(g }ae\!zWS(3cL^e:|W9kuaÆ&5dn 0n!:c5dn 0n!:C %ѣBAV@;~%GBW9lDGG1v`LœjcLSпF-F~STST1PU4u<%6Sοzo?: xz?W&5e/50#0#0#TP rJ3h8uCT% ]ԙ"=={j|S`F`F`FBB] ? FA (iǕ4nleڀt+eF`F`F`%W`K Iy_bsJs>r7V5qF`F`F`!Q)mt=UNѴTE:wj%& `F`F`F"`LORl jl_; sb坺s2] Pq7F`F`F`F#`?|@5R" NlXw=^+j LF`F`F`=fx
Standard Colours
Index
0-4 00000000 00FFFFFF 00FF0000 0000FF00 000000FF
5-9 00FFFF00 00FF00FF 0000FFFF 00000000 00FFFFFF
10-14 00FF0000 0000FF00 000000FF 00FFFF00 00FF00FF
15-19 0000FFFF 00800000 00008000 00000080 00808000
20-24 00800080 00008080 00C0C0C0 00808080 009999FF
25-29 00993366 00FFFFCC 00CCFFFF 00660066 00FF8080
30-34 000066CC 00CCCCFF 00000080 00FF00FF 00FFFF00
35-39 0000FFFF 00800080 00800000 00008080 000000FF
40-44 0000CCFF 00CCFFFF 00CCFFCC 00FFFF99 0099CCFF
45-49 00FF99CC 00CC99FF 00FFCC99 003366FF 0033CCCC
50-54 0099CC00 00FFCC00 00FF9900 00FF6600 00666699
55-60 00969696 00003366 00339966 00003300 00333300
60-63 00993300 00993366 00333399 00333333
././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/comments.rst0000644000000000000000000000462200000000000013420 0ustar00Comments ======== .. warning:: Openpyxl currently supports the reading and writing of comment text only. Formatting information is lost. Comment dimensions are lost upon reading, but can be written. Comments are not currently supported if `read_only=True` is used. Adding a comment to a cell -------------------------- Comments have a text attribute and an author attribute, which must both be set .. :: doctest >>> from openpyxl import Workbook >>> from openpyxl.comments import Comment >>> wb = Workbook() >>> ws = wb.active >>> comment = ws["A1"].comment >>> comment = Comment('This is the comment text', 'Comment Author') >>> comment.text 'This is the comment text' >>> comment.author 'Comment Author' If you assign the same comment to multiple cells then openpyxl will automatically create copies .. :: doctest >>> from openpyxl import Workbook >>> from openpyxl.comments import Comment >>> wb=Workbook() >>> ws=wb.active >>> comment = Comment("Text", "Author") >>> ws["A1"].comment = comment >>> ws["B2"].comment = comment >>> ws["A1"].comment is comment True >>> ws["B2"].comment is comment False Loading and saving comments ---------------------------- Comments present in a workbook when loaded are stored in the comment attribute of their respective cells automatically. Formatting information such as font size, bold and italics are lost, as are the original dimensions and position of the comment's container box. Comments remaining in a workbook when it is saved are automatically saved to the workbook file. Comment dimensions can be specified for write-only. Comment dimension are in pixels. .. :: doctest >>> from openpyxl import Workbook >>> from openpyxl.comments import Comment >>> from openpyxl.utils import units >>> >>> wb=Workbook() >>> ws=wb.active >>> >>> comment = Comment("Text", "Author") >>> comment.width = 300 >>> comment.height = 50 >>> >>> ws["A1"].comment = comment >>> >>> wb.save('commented_book.xlsx') If needed, ``openpyxl.utils.units`` contains helper functions for converting from other measurements such as mm or points to pixels: .. :: doctest >>> from openpyxl import Workbook >>> from openpyxl.comments import Comment >>> from openpyxl.utils import units >>> >>> wb=Workbook() >>> ws=wb.active >>> >>> comment = Comment("Text", "Author") >>> comment.width = units.points_to_pixels(300) >>> comment.height = units.points_to_pixels(50) >>> >>> ws["A1"].comment = comment ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/conf.py0000644000000000000000000002320100000000000012332 0ustar00# -*- coding: utf-8 -*- # # openpyxl documentation build configuration file, created by # sphinx-quickstart on Fri Sep 10 09:50:03 2010. # # This file is execfile()d with the current directory set to its containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys, os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.insert(0, os.path.abspath('.')) up = os.path.dirname HERE = os.path.split(__file__)[0] sys.path.insert(0, os.path.abspath(os.path.join(up(HERE), '.'))) import openpyxl def AliasProxyGet(self, instance, cls): return getattr(cls, self.alias) from openpyxl.styles.numbers import NumberFormatDescriptor def NumberFormatGet(self, instance, cls): return self from openpyxl.styles.styleable import StyleDescriptor def StyleDescriptorGet(self, instance, cls): return self.key if os.environ.get("APIDOC") == "True": from openpyxl.descriptors import Alias Alias.__get__ = AliasProxyGet NumberFormatDescriptor.__get__ = NumberFormatGet # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = ['sphinx.ext.autodoc', 'sphinx.ext.ifconfig', 'sphinx.ext.viewcode', 'sphinx.ext.doctest', 'sphinx.ext.coverage'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = u'openpyxl' from datetime import date copyright = u'2010 - {0}, {1}'.format(date.today().year, openpyxl.__author__) # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The full version, including alpha/beta/rc tags. release = openpyxl.__version__ # The short X.Y version. version = ".".join(release.split(".")[:-1]) # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = [] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. on_rtd = os.environ.get('READTHEDOCS', None) == 'True' if on_rtd: html_theme = 'default' else: html_theme = 'nature' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. html_logo = 'logo.png' # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_domain_indices = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'openpyxldoc' # -- Options for LaTeX output -------------------------------------------------- # The paper size ('letter' or 'a4'). #latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). #latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('index', 'openpyxl.tex', u'openpyxl Documentation', openpyxl.__author__, 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # If true, show page references after internal links. #latex_show_pagerefs = False # If true, show URL addresses after external links. #latex_show_urls = False # Additional stuff for the LaTeX preamble. #latex_preamble = '' # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True # -- Options for manual page output -------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'openpyxl', u'openpyxl Documentation', [openpyxl.__author__], 1) ] # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = {'http://docs.python.org/': None} doctest_global_setup = """ import os, shutil if not os.path.exists("tmp"): os.mkdir("tmp") shutil.copy("logo.png", "tmp") os.chdir("tmp") """ doctest_global_cleanup = """ import shutil import os os.chdir("..") shutil.rmtree("tmp") """ # Invoke Sphinx apidoc to generate api rst files import shutil def run_apidoc(_): try: from sphinx.ext.apidoc import main except ImportError: from sphinx.apidoc import main cur_dir = os.path.abspath(os.path.dirname(__file__)) output_path = os.path.join(cur_dir, 'api') shutil.rmtree(output_path, ignore_errors=True) modules = os.path.dirname(openpyxl.__file__) exclusions = [ '../openpyxl/cell/tests', '../openpyxl/chart/tests', '../openpyxl/chartsheet/tests', '../openpyxl/comments/tests', '../openpyxl/compat', '../openpyxl/descriptors/tests', '../openpyxl/descriptors/slots.py', '../openpyxl/develop/', '../openpyxl/drawing/tests', '../openpyxl/formula/', '../openpyxl/formatting/tests/', '../openpyxl/worksheet/tests', '../openpyxl/writer/tests/', '../openpyxl/xml/tests', '../openpyxl/conftest.py', '../openpyxl/packaging/tests', '../openpyxl/pivot/tests', '../openpyxl/reader/tests', '../openpyxl/styles/tests', '../openpyxl/tests', '../openpyxl/utils/tests', '../openpyxl/utils/formulas.py', '../openpyxl/workbook/tests', '../openpyxl/workbook/external_link/tests', '../openpyxl/writer/tests', '../openpyxl/xml/tests', ] main(['-f', '-T', '-e', '-M', '-o', output_path, modules] + exclusions) def setup(app): app.connect('builder-inited', run_apidoc) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/datetime.rst0000644000000000000000000001020200000000000013356 0ustar00Dates and Times =============== Dates and times can be stored in two distinct ways in XLSX files: as an ISO 8601 formatted string or as a single number. `openpyxl` supports both representations and translates between them and Python's datetime module representations when reading from and writing to files. In either representation, the maximum date and time precision in XLSX files is millisecond precision. XLSX files are not suitable for storing historic dates (before 1900), due to bugs in Excel that cannot be fixed without causing backward compatibility problems. To discourage users from trying anyway, Excel deliberately refuses to recognize and display such dates. Consequently, it is not advised to use `openpyxl` for such purposes either, especially when exchanging files with others. Timezones --------- The date and time representations in Excel do not support timezones, therefore `openpyxl` can only deal with naive datetime/time objects. Any timezone information attached to Python datetimes must be stripped off by the user before datetimes can be stored in XLSX files. Using the ISO 8601 format ------------------------- To make `openpyxl` store dates and times in the ISO 8601 format on writing your file, set the workbook's ``iso_dates`` flag to ``True``: >>> import openpyxl >>> wb = openpyxl.Workbook() >>> wb.iso_dates = True The benefit of using this format is that the meaning of the stored information is not subject to interpretation, as it is with the single number format [#f1]_. The Office Open XML standard does not specify a supported subset of the ISO 8601 duration format for representing time interval durations. `openpyxl` therefore always uses the single number format for timedelta values when writing them to file. The 1900 and 1904 date systems ------------------------------ The 'date system' of an XLSX file determines how dates and times in the single number representation are interpreted. XLSX files always use one of two possible date systems: * In the 1900 date system (the default), the reference date (with number 1) is 1900-01-01. * In the 1904 date system, the reference date (with number 0) is 1904-01-01. Complications arise not only from the different start numbers of the reference dates, but also from the fact that the 1900 date system has a built-in (but wrong) assumption that the year 1900 had been a leap year. Excel deliberately refuses to recognize and display dates before the reference date correctly, in order to discourage people from storing historical data. More information on this issue is available from Microsoft: * https://docs.microsoft.com/en-us/office/troubleshoot/excel/1900-and-1904-date-system * https://docs.microsoft.com/en-us/office/troubleshoot/excel/wrongly-assumes-1900-is-leap-year In workbooks using the 1900 date system, `openpyxl` behaves the same as Excel when translating between the worksheets' date/time numbers and Python datetimes in January and February 1900. The only exception is 29 February 1900, which cannot be represented as a Python datetime object since it is not a valid date. You can get the date system of a workbook like this: >>> import openpyxl >>> wb = openpyxl.Workbook() >>> if wb.epoch == openpyxl.utils.datetime.CALENDAR_WINDOWS_1900: ... print("This workbook is using the 1900 date system.") ... This workbook is using the 1900 date system. and set it like this: >>> wb.epoch = openpyxl.utils.datetime.CALENDAR_MAC_1904 Handling timedelta values ------------------------- Excel users can use number formats resembling ``[h]:mm:ss`` or ``[mm]:ss`` to display time interval durations, which `openpyxl` considers to be equivalent to timedeltas in Python. `openpyxl` recognizes these number formats when reading XLSX files and returns datetime.timedelta values for the corresponding cells. When writing timedelta values from worksheet cells to file, `openpyxl` uses the ``[h]:mm:ss`` number format for these cells. .. rubric:: Footnotes .. [#f1] For example, the serial 1 in an Excel worksheet can be interpreted as 00:00, as 24:00, as 1900-01-01, as 1440 (minutes), etc., depending solely on the formatting applied. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/defined_names.rst0000644000000000000000000000343100000000000014351 0ustar00Defined Names ============= The specification has the following to say about defined names: "Defined names are descriptive text that is used to represents a cell, range of cells, formula, or constant value." This means they are very loosely defined. They might contain a constant, a formula, a single cell reference, a range of cells or multiple ranges of cells across different worksheets. Or all of the above. They are defined globally for a workbook and accessed from the `defined_names` attribute. Sample use for ranges --------------------- Accessing a range called "my_range":: my_range = wb.defined_names['my_range'] # if this contains a range of cells then the destinations attribute is not None dests = my_range.destinations # returns a generator of (worksheet title, cell range) tuples cells = [] for title, coord in dests: ws = wb[title] cells.append(ws[coord]) Creating new named ranges ------------------------- .. testcode:: import openpyxl wb = openpyxl.Workbook() new_range = openpyxl.workbook.defined_name.DefinedName('newrange', attr_text='Sheet!$A$1:$A$5') wb.defined_names.append(new_range) # create a local named range (only valid for a specific sheet) sheetid = wb.sheetnames.index('Sheet') private_range = openpyxl.workbook.defined_name.DefinedName('privaterange', attr_text='Sheet!$A$6', localSheetId=sheetid) wb.defined_names.append(private_range) # this local range can't be retrieved from the global defined names assert('privaterange' not in wb.defined_names) # the scope has to be supplied to retrieve local ranges: print(wb.defined_names.localnames(sheetid)) print(wb.defined_names.get('privaterange', sheetid).attr_text) .. testoutput:: ['privaterange'] Sheet!$A$6 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/development.rst0000644000000000000000000001654400000000000014123 0ustar00Development =========== If you find the openpyxl project intriguing and want to contribute a new awesome feature, fix a nasty bug or improve the documentation this section will guide you in setting up your development environment. We will look into the coding standards and version control system workflows used, as well as cloning the openpyxl code to your local machine, setting up a virtual Python environment, running tests and building the documentation. Getting the source ------------------ The source code of openpyxl is hosted on `Heptapod `_ as a Mercurial project which you can download using e.g. the GUI client `SourceTree `_ by Atlassian. If you prefer working with the command line you can use the following: .. parsed-literal:: $ hg clone \https://foss.heptapod.net/openpyxl/openpyxl $ hg up |version| Please note that the default branch should never be used for development work. For bug fixes and minor patches you should base your work on the branch of the current release, e.g |version|. New features should generally be based on the development branch of the **next** minor version. If in doubt get in touch with the openpyxl development team. It is worthwhile to add an upstream remote reference to the original repository to update your fork with the latest changes, by adding to the :code:`./hg/hgrc` file the following:: [paths] default = ... openpyxl-master = https://foss.heptapod.net/openpyxl/openpyxl You can then grab any new changes using:: $ hg pull openpyxl-master After that you should create a virtual environment using :code:`virtualenv` and install the project requirements and the project itself:: $ cd openpyxl $ virtualenv openpyxl-env Activate the environment using:: $ source bin/activate # or ./openpyxl-env/Scripts/activate on Windows Install the dev and prod dependencies and the package itself using:: (openpyxl-env) $ pip install -U -r requirements.txt (openpyxl-env) $ pip install -e . Running tests ------------- Note that contributions to the project without tests will **not** be accepted. We use :code:`pytest` as the test runner with :code:`pytest-cov` for coverage information and :code:`pytest-flakes` for static code analysis. To run all the tests you need to either execute:: (openpxyl-env) $ pytest -xrf openpyxl # the flags will stop testing at the first error Or use :code:`tox` to run the tests on different Python versions and configurations:: $ tox openpyxl Coverage ++++++++ The goal is 100 % coverage for unit tests - data types and utility functions. Coverage information can be obtained using:: py.test --cov openpyxl Organisation ++++++++++++ Tests should be preferably at package / module level e.g :code:`openpyxl/cell`. This makes testing and getting statistics for code under development easier:: py.test --cov openpyxl/cell openpyxl/cell Checking XML ++++++++++++ Use the :code:`openpyxl.tests.helper.compare_xml` function to compare generated and expected fragments of XML. Schema validation +++++++++++++++++ When working on code to generate XML it is possible to validate that the generated XML conforms to the published specification. Note, this won't necessarily guarantee that everything is fine but is preferable to reverse engineering! Microsoft Tools +++++++++++++++ Along with the SDK, Microsoft also has a `"Productivity Tool" `_ for working with Office OpenXML. This allows you to quickly inspect or compare whole Excel files. Unfortunately, validation errors contain many false positives. The tool also contain links to the specification and implementers' notes. File Support and Specifications ------------------------------- The primary aim of openpyxl is to support reading and writing Microsoft Excel 2010 files. These are zipped OOXML files that are specified by `ECMA 376 `_ and `ISO 29500 `_. Where possible we try to support files generated by other libraries or programs, but can't guarantee it, because often these do not strictly adhere to the above format. Support of Python Versions -------------------------- Python 3.6 and upwards are supported Coding style ------------ We orient ourselves at PEP-8 for the coding style, except when implementing attributes for roundtripping. Despite that you are encouraged to use Python data conventions (boolean, None, etc.). Note exceptions from this convestion in docstrings. Contributing ------------ Contributions in the form of pull requests are always welcome. Don't forget to add yourself to the list of authors! Branch naming convention ------------------------ We use a "major.minor.patch" numbering system, ie. |release|. Development branches are named after "major.minor" releases. In general, API change will only happen major releases but there will be exceptions. Always communicate API changes to the mailing list before making them. If you are changing an API try and an implement a fallback (with deprecation warning) for the old behaviour. The "default branch" is used for releases and always has changes from a development branch merged in. It should never be the target for a pull request. Pull Requests ------------- Pull requests should be submitted to the current, unreleased development branch. Eg. if the current release is |release|, pull requests should be made to the |version| branch. Exceptions are bug fixes to released versions which should be made to the relevant release branch and merged upstream into development. Please use :code:`tox` to test code for different submissions **before** making a pull request. This is especially important for picking up problems across Python versions. Documentation +++++++++++++ Remember to update the documentation when adding or changing features. Check that documentation is syntactically correct.:: tox -e doc Benchmarking ------------ Benchmarking and profiling are ongoing tasks. Contributions to these are very welcome as we know there is a lot to do. Memory Use ++++++++++ There is a tox profile for long-running memory benchmarks using the `memory_utils` package.:: tox -e memory Pympler +++++++ As openpyxl does not include any internal memory benchmarking tools, the python *pympler* package was used during the testing of styles to profile the memory usage in :code:`openpyxl.reader.excel.read_style_table()`:: # in openpyxl/reader/style.py from pympler import muppy, summary def read_style_table(xml_source): ... if cell_xfs is not None: # ~ line 47 initialState = summary.summarize(muppy.get_objects()) # Capture the initial state for index, cell_xfs_node in enumerate(cell_xfs_nodes): ... table[index] = new_style finalState = summary.summarize(muppy.get_objects()) # Capture the final state diff = summary.get_diff(initialState, finalState) # Compare summary.print_(diff) :code:`pympler.summary.print_()` prints to the console a report of object memory usage, allowing the comparison of different methods and examination of memory usage. A useful future development would be to construct a benchmarking package to measure the performance of different components. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/editing_worksheets.rst0000644000000000000000000000354200000000000015474 0ustar00Inserting and deleting rows and columns, moving ranges of cells =============================================================== Inserting rows and columns -------------------------- You can insert rows or columns using the relevant worksheet methods: * :func:`openpyxl.worksheet.worksheet.Worksheet.insert_rows` * :func:`openpyxl.worksheet.worksheet.Worksheet.insert_cols` * :func:`openpyxl.worksheet.worksheet.Worksheet.delete_rows` * :func:`openpyxl.worksheet.worksheet.Worksheet.delete_cols` The default is one row or column. For example to insert a row at 7 (before the existing row 7):: >>> ws.insert_rows(7) Deleting rows and columns -------------------------- To delete the columns ``F:H``:: >>> ws.delete_cols(6, 3) .. note:: Openpyxl does not manage dependencies, such as formulae, tables, charts, etc., when rows or columns are inserted or deleted. This is considered to be out of scope for a library that focuses on managing the file format. As a result, client code **must** implement the functionality required in any particular use case. Moving ranges of cells ---------------------- You can also move ranges of cells within a worksheet:: >>> ws.move_range("D4:F10", rows=-1, cols=2) This will move the cells in the range ``D4:F10`` up one row, and right two columns. The cells will overwrite any existing cells. If cells contain formulae you can let openpyxl translate these for you, but as this is not always what you want it is disabled by default. Also only the formulae in the cells themselves will be translated. References to the cells from other cells or defined names will not be updated; you can use the :doc:`formula` translator to do this:: >>> ws.move_range("G4:H10", rows=1, cols=1, translate=True) This will move the relative references in formulae in the range by one row and one column. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/example.py0000644000000000000000000000051700000000000013045 0ustar00from openpyxl import Workbook wb = Workbook() # grab the active worksheet ws = wb.active # Data can be assigned directly to cells ws['A1'] = 42 # Rows can also be appended ws.append([1, 2, 3]) # Python types will automatically be converted import datetime ws['A2'] = datetime.datetime.now() # Save the file wb.save("sample.xlsx") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/filters.png0000644000000000000000000006254600000000000013230 0ustar00PNG  IHDRKSsRGB@IDATx]|^rit Z -*EZMHAQlԿ (((HD)@(IH !]ovo/]rz9})ofμ<ÇUI(2@:u(#ϱ?+&XC"@nQ3Pjπ-}D92aWϔ%O 7\ B  2=1l0J%1* ͮwiWX1ˢ<ѣ5Ea/Xvpqٕnڞ@?B۳T8 [1+sX;^'abQҜJبb>A9WGBXP'.„.,[n~<>EB^ࠕHنVT)-\[7.pCW*\b ˓{L@V>O gwGX + ) ^\w x>ypjsg#tHZ,9+똂4B|Y/Rcvp9~NȮx̏#Ao`!BZʢk}s1牣_ˮVVV\'fWFJ;}I_.g/^$IsdPB/]ǞK%++[F:%A:0HtRn#<cq ~,.??C*Jx0 fg*&tBPy[7V맰Eaz G0`ۉ׃qeH Qguˣ54>7TFL42ȗ^ u]!e4\;//!II\Oƈ[`NmxBZX{'6b( uaZ:D=s姥nzJ,sK%tJuBe]]]yxyyqXadߵB=$B" -忍N͏[HÇ槛^CZ_ii% ᭡8z#U|n᪛/8CH#w/eWF,-#ឹuy ,6pm^̝/>=jlΆ=1!s~!Pm, nCeq |<#igqrY:)kaem/Jʾ18ψ=TFL,zuwuoLVHOjy%Y΂ƒ„³[g~$ nved ?:/Oi~ vAm"5t SXy b9՟h˖C3a9f k{{{T`6u%V ៅiw: pQn(t++ 6m.?!]w_*\>| {81v8'԰ i &@7Wh硤!>\1Z(V˛&;}uE.U`)kv7%抦Hx%m.aL; q+Kxi]YGdS)$R7EEϪUvedEO=*i CժU=| 7+ y+{0b:|켿B?ohuHDLGxʯ3z؞Bݻ!HW_q˧,MvvF< n|nf^jM姴VߘUqUeظ/~U=YOgkjyz ϩqH(#G3jwJ e&FpUgI%wrQ믽,rdk*(TPVoN*@p #' g~|.|+<9i.xuȑ dJAg 'q}iԟծ#%X7۟mwX񬳯`+dz<sfpԳ*]VSsL .&{FBw[!6Z)و˄#,)eȻN [eb|ɛg.Dnœ#1*jt<%m ϏIhlt? y2O_tõ/nnz!/M%6r&Yn|%-Z嗑&\~3BB •Hp W-ԩ)8yjT8x`24߄E}vL2-6q_jA?7{x( UV+VeJm6]??A}e?KJ"Re eu_';[4#M)y4cD-s?SF}d"Du!S/ dd}= 2鎾;aht_{vDp\+q,.I2O{("l6thSNO<{33NFq+/[rO*ۊY& 9u :ڿf}ʕQTO6MV`()!Nm{Gݍh;4+ tRxBTToΥ6&'CPo89F^L,WQk'`Ti<> ɴ \t ׾G X+n1+YEzWu}p9sgϞp\Ȥ3'%`"0Ń!p0u3H˛2|դ2H/#=(ic@ҭ3mmԷP5M_JU'Yxk ?V6 l'Ґkt@F䭬T^_Qm]hbWMgӒJ,i)aF<;f,X.?3ۢ}H w: WG@KClf+1=3v с8720ںriKdd 5pdY ڱ @ZK1lHnLqq4 /] M<-zTPQ\ˤoE:>HD>tl2 3R_*fUJDC=WvvY9DҔCBZ1u "Ye$?NIىP4a=Ǎ޵xw|}n@3PK{Tr釵fOTq,R)%\gH$XsA-VUA DTDlMPLO |n]?U7>MJN+ `KmUtZ1IJ󶄟|p'&~>$ƣGң¦]mzBApH!$TÊ&Mt" :k02,[74u̕6C/6hڍU1Sk y:YV:_frWv͍LHHx$v ޶yUS1˦?ANf6LI1eg**h5R͡ cz͚5a 7 YbE6Ǵ"gK%0 {cnndK'C4DZ1 N=B6mW}q07Zg=#@o1.e=I]nY6-"2pj;c' xrOa] ɤ|r~i#ƣ}El[#E +2E3ߨ6iȩ o z a0U<[GÁXl` #uX&e,t:z<"qӫt >?\O?)ߙVX~ M3%4_Hr~CkgxKkIvvҬtX΀}5l>:*ګN `?o+ا~T|L\=M ɤFLb w?~"g\Kخ/T;F"27vǎ+J^,6Np/XD p_𞾈Jٱ}a8lhB['l?AR+i /=F@L=*y $?‰Y0d =HiSFܐF28( HF26ALza䔏xf8ɉgzkA46dTkL#z .-TPJx2-(qaFǎ}$(Ḷ >rκP;?{ s'uFF^cρy8_)\az9=>X@E{GR$ړ dƓ*n|c%Z`ñ)YL/SA,K@JW:˒@hJl$tSIE z2 fʺ;!O=xW;*̈aɴ4Jd͚5FOe&-]XL)JKuֳlʼn}qF5L`_"DdE~UQ%+RLEW 7N@IH\9DP"]▀ 74{eqw1}@Q8p6V~H @1JLcXe";M(x%~ĻCh9U%F߮f؂6O*tOjT˯c J. $zPNc<=v-fmtǔWvAXT}Zo8jOoi 5F*y4nN%iCK]SY& =:! \;ãP$f|$Azt4CPigz{1tRUM3'-Oc6P !U+*`f8y 2 I۬rh1 ׾Vef~S-r4FHXHsbl(N0exnk̫]m*k4}t+#lN#\ً{C,A+IDFЃ$lYJ"i):%ˣJx ]A9hU_.4 1^[ >hv׀+H?S'{1$: +^Z0&L)Ys1U\zrTQ@S+5xQNju/-fn@Rbꆾ̻ Ǝ6fɸ6I+%WE?jEGo:}9@A:O JfPq`_+*ͽW2K,uNǧҒiþdU" R$PW5T\a*[ D .)Z5iH%+Q%+OƭT %@ظ;c}vOb٪Cd`_|I>K;%=~2U )ՕVȢ;$]Q1=Ѥ3mEA Q_Gns+[׃/5Kh!p;ǿ!$hm3a$L4x5#~yުhiTzNGX|#S 9< /LjƒYqG>BO"Zz&L1po\=)i$v''y,S)quر?w=6ͱU)֨|O5!i9ܴ*l[ڼ+ݸ(.L_)hN|39_煕@ͮp,^TXB6Uj^{&uLC?bR?-zLE672Tbn))M+n&mO;22Do3Yr(3RA61X8%A+|A%`_Qf1%J4>xjl8o[y,S1gq\|P2 [ʱob#z̄rf xq6\N>m_ e^ \[0W慡[ZfU{vkJ/_' ڃVxN2ɶ,S%%ZSQb֨{d6gʋ%dYsO{L 7%%dͥٶ%7*H$ۚ3nr;l,Yaa_*k'թx1SNvpTQLˉ|þxT&+WM5GKZ5$ W2XWu˻J֨I+dJ̯>f_< O 3|KK%(e5-lĕ2^^k%FeH[ if*A֨\rAJ_R'TKS*3%\I@N6͍'5+F07X Wcb5[ҲH%+*ٶ,n=T.1L["L%`>v"NR>Tga56JĄ% Hzل"sZ,ڗv[=; M;tw~8>r4B@!4k_Bu%7Hs"~.̥CwG7!s("q3?;wݒߙ;xJаk!L5r]Ѹ.ld8NDJ}QK&+K䉝##IU d8lM'pY0d{w/ԫզ` mrrFpms4wߞl$Skc8/KE]p %LaOpt}/ ;n+t#~f?EsBOqTBo0_N ¸m!|:W+s;b8;^7VtI}%nWX.?,}ǨʰN1(El\=_N 53Y oپ4dG{TgmzɄ±;d#,cpqf&ύG_@ /Wem;ͯda68/)ncG~;[ CMDGIO ԍlDi#+ ٴ;tJ AZKr?:3^y%[Y2'Q1^ q#jtwéw13՘?,ҥKc>ޥ 9#_yHnlZf4JW^^{42VN Ft#nFpq~NnU}hŒ%yaWvCDT'+pۄ V`^Cҍ}%5d+gD-dȽQCкZjLo j-ÏӬ&޿HjC"/F{_;Md݋7UTC2.`Y/ XH3L|(3 g'Cqn!dЗ?`n9]*AaX RY42$tFc^d҈Ym!5 qM| zWM18.%͠Ț lc"7Ym^1ش>8O5רy>5,|>Icb8?FI`_d6s1r0oCu,YwLA+]e/xm%N=RT[ C+}I\ $!^*[O*F tSCCVd0z)p b7ڢ?hlߒ\#?4Y|jN=0#Oʹ"0 )>Yo i,zwd.PoO{zo >h?>!p+lde+X"<ؗnnm6iPQ(e 2d+%,N;U0VMƅ iEgyUD!ZKĈ{fE=lėcJ x8,">2bBRRAvYMC - z[ʗ'D"Vh)SU1ˤ>-SUӋ( "k*<  5GQO,W)LdY%`q )Jڒq#uTbē&n", eļt`DbcgZ@& ǐn. [l=gOނN hUpfvK#S&"D[wEG_ +C`e<,IH^9qc&8q* DG8rC/˖BO"L]V,MsO \ Z*Ĭ>6)&0JʸoTQc.6C!IYN%/%n-ݰ'&~NCW" Yq/49OƪyÞhk#ƒף ~B8; lj<1N*ǻ50޽F~=Ob;<ۘGymexE=:Pֿ+ ~XZ&B}( ?P~52HYMm 5T [0١5߰4 klj>*w-+7]PnW\R~6ѡ#F,G0$\TEҳD寕F W+PTf_VI9.z腥c}H w: VT5( Cd,FflޣNȑN'Y9| =.!C[2 E\m⧫yNɑwK|û^IS2zcЛlSYlD4@uDZI?,KT!Z#SK/h륎iAx;I<"Ma_#rSR{&.&p0.i=VgiLhWɑ4fTByR LpӕQfgu/|{4Ĕ i녥j#iYn jX눿H]EIM(P-fU,sbS^P{N1a;X%esaHjh$$g&iiizkV NGs9ui$6D`iY\I\}>wxB!Z#3$R4W&~Ė x/Z=_,$<+(þ]ڂm[n4{L$W{^fzh(k1ߦnʱhyW?],p>.i:ʞ-B̰R7b}ljE_C̚=>,# eNjv6Gu|%}Ndy[싦yNWJH'k_M:a$}%&fJcʡQrL]A7 /D UClXʖ( SZ#+o1cDbnq,EP/Y"RJm ݞp1geF/dԈ1t?9ݯSt g4MN52#dZQeJldKSpK<#7vS->GSڮū(3te^h*^.Wj+z"݌l_s!ҥK ԩShժUi4ڸؗ־Hݮ!RzԵJ+(C ؗPElYHso_x'zՅ}Dri$dkDS*m1`A/9cQllU?Dk__jXɅ/r6)Z/|~5}þ4k;P;A F U] H`_91ֈaڱhLa_Z҅8bB˖@E}[5؛1Jl\H UةTFP}*M%QKIʕMr>SqMP_=2a{6ŠAMQFTk_eT21 .CMhjLN"Ts_:fYLd zNp>Id l9QR6,k2 WYWT3V[ũoyt+!s$|-U_o.¾JX 7XNc3 ؈w,ي־136G ̢X&cfD*qn+AVv.j=2qn,Df\TsydJ/7`r|9CUvֺH(C/>̤|o6:~JMO6K-]eSQ vxEa5b>}}+e!n*2dŔ2䏫Dk}*,­m M]z&/< 7 @I%E^(t 8u"} ^F;?1E.i8$UBI Xх,+E ޜ #}>7OD/ ap夆h%1.c<ؗ x3㖅4o.,BNVp^H<|ڏuά}1\v>dk3K`.p A_ ƶFUXZ~ #!?|Q.FP!5.s'$U~i/U9F,?g(0luUJ笑j[N+q.&&IK'p5#f+((?t*#k+(a)6±EdFmd=L-,vH>GhNڌJ6NTPmGlpaLuc)$d#X_/ {¯t6sH@<Հ)8Gw3O:?&/g?-K$5ݎ9}Xt8pKA =$k_jXnnvGP)pZ1A-g|{$ MH&aprK `$V@ *Ҭ[iΫdZ /RrF(b!΀"PWwzEt} Iұ mfû2+.@o#3q0&JPuWtuUD ;ih۷ xw ןF֯ b]h*-Q!P4lŻ, C4KCxD87tsLR)m h:ѵE_\ӱ6nw70ʕ \a6| ?; H#r!`;hYۊkKᄝ(Gw渜L/_HYdx @1+Y*B۪4j|t#Q4 kÍF3 +:Zj){x ZDjN\6^a7HoK0$\TMփ `Gs'w "{-QXt$Wƭ%Ocn{YL4!GϦrLVA4C l#RppO]dh-PW.C+ҎE"ciOyq![|ļ8)ʿ ?&uP!^*,e@) l\o2fY  M.vd{*ZCm#򵱳zp|]ʰWUr";Q&N a-І f hx,,8}#Vs?T>zab3-~|7PԆQzX\le2<9jCulT:үOj~ŶqY ~ϭ)" ] j:œ0f(PᦂƴRXcخy`o~'&K򴝊-^:dk:୍籼-- ]V>_G-1_݁/r[`Տ᪊0m3Hs!p›? -1~agoj >i[%[tU Tk_¾TNS)2;Uc>Ɠ~L}i7u 6pʏ*~D+0vQF- 󅖇GyG$JGFjM@jxf,JOl=-MWnܴVY(0nd^Ct<5Ng,a0r|ŏµPtt_ J WR6,kbSK) H3@Ŗ S]T}CaJoLSe\2XTF})u)W< ԉ`__|WuFŌ Wf(zW?r4h]ɴ+PN:*%NTpjzg =S`_󖿏)GjRҡX|;dhyNQ%! *ptjka}{Hu;T֨ީ-nc&ǶU+j;$^o s9wF ^>?nŮ+dDV=܍!;2ٵGoܯ a'a_!9"SZѸ.luDX^ uൗP|FSo53莺ҧ 61c&v^xG' .ɝjm?¹x\_ĩnA|ѧYMihح?N\:õ?2Xq:BpM,bK`_9LkO9BT2YKXS4 fXHF&%E8o*k`2 /rw؀_lPnĒ4JƮnNѾ2U6'°j :V?T=R0_ND4j%IDATH|r?} }[]F_ԥ{^ X+wzU*գhhʴ&[űhXm%i.;mhj٣=voI˙PtY6 Hr>9ھK!a砧noiev\d^#p]<ЋcA/FԳ,}Lҗ 0ﶨSI;fny_BgV}x5# Y {sVNC0?p֊ SjwEz1%P!a_T?5Qqd h-{SOs+|u>h,H-;fNCMf$!Sń&nfX>@dA(M{`asa+2: pt\Z8Gc=3(Y ZBλl<]RkKHa_Oƿ K:7ݨ7o뺵JDuh[aht$r&ݑѡa]8p5fOUܺK~BNY{HK<}N!6)KHq|YZsg!\x+mIV @ʘL}_He'K}1)fWF׆fOyDEɒN3x_t3э}O *"MgD|mk 7GA\OM@cux=1u=}#@*t~s'ԫr\NCùd>@0X9|]|c]L"m`k`tz 5ʼ⥌$`/&A0q/&TFc^8;?՛AHE DA~ uZdmkko @h18;Zon*>Oo+&,cN™,9)Ȑfa &X~]igrf൛L"`Fz-Ö|֯!H"Vב?(EkVP,s XIOTi 26%#+\xJfu)Z 1jw-py?EE$d6"aFUv8}- 2 }LÿV#_2nFp.r[WCNF@ ,ix2eþ+fcK>{bvc8MSȩ!6 9ùUs'i ^C̚MHn_0=: ۛzk.G϶`ЌorՁ0  bWfi/b.+K3 4I;TʖKG< $Bʴ|2_%%P% ZȭUv6d%P2}l[ 7^2a_%ߦ"GQŖQ`_ uAAJ8[4s0g ̘1 VlāI|BBtyb|Me#hD/,A{2F˔xgIf6'k_s]ط5A~oj OiHƐA0 @}1̖A}#ǘXY`P~p'}g["9> U!/ `ȾNcwޗ-xW  eFҭ5<էjG nNqW''Kʛ a !&GR A ƭЫWɠbj!rꇧOm3'݂C=_zD:)75lhGt԰/|b־Y/җ}9PWVoWJ-I&RppO] -~UHF(eFҕGF?zN~H&"ӵ~s Ix"Lbf'#;Jx~C'I5/ X2>V u!7 m.vt:zU3KFha_,RtF~FonZKbҎ\?=Nv.QMI܌YQc ߝt~S!}I9XWVen*M"{"2<9.c{kYg=k+/`#4R=; 7pl]f\6labp<Ε7eu:"\i8ᓅ!b "Ja_a 1߄aSVDchNPxky,ggtd)冑O V7x,>Ux}?nýs/tz۵Is,ɐѐz+ ScsOc6x5G X2Azj"<`tQa_-~p<  e o*Tւ.hrm\gn~*oR^Hؗr< /4 [*ԉ"Ȋ>4t %w$V{lC0_ǩpkSVmd\@ X0+#q'57Y#($@힑<fKbeW"cc uJF$ կKѤ'>˂msc^S/Y$- 4%={$Zoñn'ud MWxC2J%OUP5l2}^N{IV I0 >D jPP撪Ed͚5qd:tP\D*Zn=J3f덭$g/BE'*¾JME-1¾NACgc"}}!omQIjuW X4Khi-KW0 zLT+ fVTa2#T< X:싵 mZ~5PX;Ar(ւN3l+!$U.e %Cj53ETz-eKHI٩1>x ՛!K2qY0 ]̜aAߙsg}?X{6RRڊU5>a Sm""Ѿ lԭ S3kޏg*)^lN|VE}f)̴p>tn5F cAMٵ@89+3{1_<ҸVܲ~:$+!!/O`.Xv/Ѐe8 bHr,et%8n9%@VV1n%W9HhQF iQL >'q0`%xrn 0W7t[1t3Z_9n#mI_xʐ1V?[X3 i8)ǕX|x6M[w|Jzy4Z?S1Nzo=—;-5L0BjuW9 Ð.,C ԓU:+%KX 6nd_K )*:/!*90lk+%+},~͵S(D4\0L5 uqy;v@8tbځTv/Ni `.ك!.C\%464ia7^<̚Iy'qEe7/Jm튲d&ڗWQ *I҅1sz&[1ެt8i8K?v-'OǎeLt RwDln`.RlCx0r Rbo?E!b4[ttlc ,jtu-;:KD£ơ|Wy6;rH1lh*r2ERjZ_Դ/[ʼeƸ@fR(5yWأ]ݠ11z׸Se Z6[&ѱ_wG"6/HYmp=QEcJk!Q9pUJ7(RCӾlxɩk5|8@kZW55څg!:F@оPQ@e'c̺ }35 1uCO(̳.%\5zS J@#<}%Qꅠ8t9]Ɋ l")`];?/m\9JRA]mKT2<j~h}qtxq.Y\ _hoo}݉OA{}]@>pzڗ$㫳rc;NZоҿ`xHәO [.azadtqY8‡CUαbZ a 7-24NO2Xܺe*xzO(JCpbѻ1 Z%z E`z<;SгUe/&Jo<4Q[T1 RGB:ǺA'AYB'}<1Bv}')hOi_L1$S<΋҉1L$ /$3kroIp}r4m-]; 2*zcBZbNj% GWLƒFgDFCqr=Z^g׆ 86/QgV] _ e#nGF?#辭{hsgoXBf._62Z9rڢwQuk ;NM"Wv$vncKQ4xwֱbNN-/VbWmJEl!W,·Ӿm.ZB{Eb ȑ9-3/76#˘Ci7`[{V$#@V:K+rE 5DPОG/ 5`3Us 8+v-/@_{3"{ z?GF'<ú'L02͛7x.&9WX\9Ըe{Bl;UDۋ9J=苚/7b Ǣlicd!p2ZLOqCnDiz~JܾxՙHq&1Q@!`W1W/،ZnndOPN8=Y2VRHHTu< V^lNoThAҺ =z'rw5{BV ~1xDy_nf#G?m쉒rid]P[!Ke˖ ,MIIq5HLLٳ >gRܢ /"vD.r!~I"+%zSL 66V}%Eƍ܍MMM/W\Sr, q]%cK_e4>S.`M)9Dĉ˗/JmU & Xq\CUp(4Jd=cK=;βdEe=-bZ er&a )Uќ9s~j޼yK4Ag۶mAU^^^%9d-54yO"hfiede ǦR1YxRGֲWRB $E#A)YhRڊa#SZ1TE9)WKu"hXꚬZ/?nPVJVLVzSL[Znijr,<4-uinb/h9lycd=J%ɉ,\bKKYIUz٬Y3&z(O^TF1bZZN5ˍcL>f+iY@z|w !Νˤ#˼GibqnRX>|Dzee<>oN2JV_I -.x/DCA@VNI JyϵKy` mIENDB`././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/filters.py0000644000000000000000000000110300000000000013052 0ustar00from openpyxl import Workbook wb = Workbook() ws = wb.active data = [ ["Fruit", "Quantity"], ["Kiwi", 3], ["Grape", 15], ["Apple", 3], ["Peach", 3], ["Pomegranate", 3], ["Pear", 3], ["Tangerine", 3], ["Blueberry", 3], ["Mango", 3], ["Watermelon", 3], ["Blackberry", 3], ["Orange", 3], ["Raspberry", 3], ["Banana", 3] ] for r in data: ws.append(r) ws.auto_filter.ref = "A1:B15" ws.auto_filter.add_filter_column(0, ["Kiwi", "Apple", "Mango"]) ws.auto_filter.add_sort_condition("B2:B15") wb.save("filtered.xlsx") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/filters.rst0000644000000000000000000000113700000000000013241 0ustar00Using filters and sorts ======================= It's possible to add a filter to a worksheet. .. note:: Filters and sorts can only be configured by openpyxl but will need to be applied in applications like Excel. This is because they actually rearranges or format cells or rows in the range. To add a filter you define a range and then add columns and sort conditions: .. literalinclude:: filters.py This will add the relevant instructions to the file but will **neither actually filter nor sort**. .. image:: filters.png :alt: "Filter and sort prepared but not executed for a range of cells" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/formatting.rst0000644000000000000000000002047700000000000013753 0ustar00Conditional Formatting ====================== Excel supports three different types of conditional formatting: builtins, standard and custom. Builtins combine specific rules with predefined styles. Standard conditional formats combine specific rules with custom formatting. In additional it is possible to define custom formulae for applying custom formats using differential styles. .. note:: The syntax for the different rules varies so much that it is not possible for openpyxl to know whether a rule makes sense or not. The basic syntax for creating a formatting rule is: .. doctest >>> from openpyxl.formatting import Rule >>> from openpyxl.styles import Font, PatternFill, Border >>> from openpyxl.styles.differential import DifferentialStyle >>> dxf = DifferentialStyle(font=Font(bold=True), fill=PatternFill(start_color='EE1111', end_color='EE1111')) >>> rule = Rule(type='cellIs', dxf=dxf, formula=["10"]) Because the signatures for some rules can be quite verbose there are also some convenience factories for creating them. Builtin formats --------------- The builtins conditional formats are: * ColorScale * IconSet * DataBar Builtin formats contain a sequence of formatting settings which combine a type with an integer for comparison. Possible types are: `'num', 'percent', 'max', 'min', 'formula', 'percentile'`. ColorScale ++++++++++ You can have color scales with 2 or 3 colors. 2 color scales produce a gradient from one color to another; 3 color scales use an additional color for 2 gradients. The full syntax for creating a ColorScale rule is: .. doctest >>> from openpyxl.formatting.rule import ColorScale, FormatObject >>> from openpyxl.styles import Color >>> first = FormatObject(type='min') >>> last = FormatObject(type='max') >>> # colors match the format objects: >>> colors = [Color('AA0000'), Color('00AA00')] >>> cs2 = ColorScale(cfvo=[first, last], color=colors) >>> # a three color scale would extend the sequences >>> mid = FormatObject(type='num', val=40) >>> colors.insert(1, Color('00AA00')) >>> cs3 = ColorScale(cfvo=[first, mid, last], color=colors) >>> # create a rule with the color scale >>> from openpyxl.formatting.rule import Rule >>> rule = Rule(type='colorScale', colorScale=cs3) There is a convenience function for creating ColorScale rules .. doctest >>> from openpyxl.formatting.rule import ColorScaleRule >>> rule = ColorScaleRule(start_type='percentile', start_value=10, start_color='FFAA0000', ... mid_type='percentile', mid_value=50, mid_color='FF0000AA', ... end_type='percentile', end_value=90, end_color='FF00AA00') IconSet +++++++ Choose from the following set of icons: `'3Arrows', '3ArrowsGray', '3Flags', '3TrafficLights1', '3TrafficLights2', '3Signs', '3Symbols', '3Symbols2', '4Arrows', '4ArrowsGray', '4RedToBlack', '4Rating', '4TrafficLights', '5Arrows', '5ArrowsGray', '5Rating', '5Quarters'` The full syntax for creating an IconSet rule is: .. doctest >>> from openpyxl.formatting.rule import IconSet, FormatObject >>> first = FormatObject(type='percent', val=0) >>> second = FormatObject(type='percent', val=33) >>> third = FormatObject(type='percent', val=67) >>> iconset = IconSet(iconSet='3TrafficLights1', cfvo=[first, second, third], showValue=None, percent=None, reverse=None) >>> # assign the icon set to a rule >>> from openpyxl.formatting.rule import Rule >>> rule = Rule(type='iconSet', iconSet=iconset) There is a convenience function for creating IconSet rules: .. doctest >>> from openpyxl.formatting.rule import IconSetRule >>> rule = IconSetRule('5Arrows', 'percent', [10, 20, 30, 40, 50], showValue=None, percent=None, reverse=None) DataBar +++++++ Currently, openpyxl supports the DataBars as defined in the original specification. Borders and directions were added in a later extension. The full syntax for creating a DataBar rule is: .. doctest >>> from openpyxl.formatting.rule import DataBar, FormatObject >>> first = FormatObject(type='min') >>> second = FormatObject(type='max') >>> data_bar = DataBar(cfvo=[first, second], color="638EC6", showValue=None, minLength=None, maxLength=None) >>> # assign the data bar to a rule >>> from openpyxl.formatting.rule import Rule >>> rule = Rule(type='dataBar', dataBar=data_bar) There is a convenience function for creating DataBar rules: .. doctest >>> from openpyxl.formatting.rule import DataBarRule >>> rule = DataBarRule(start_type='percentile', start_value=10, end_type='percentile', end_value='90', ... color="FF638EC6", showValue="None", minLength=None, maxLength=None) Standard conditional formats ---------------------------- The standard conditional formats are: * Average * Percent * Unique or duplicate * Value * Rank .. doctest >>> from openpyxl import Workbook >>> from openpyxl.styles import Color, PatternFill, Font, Border >>> from openpyxl.styles.differential import DifferentialStyle >>> from openpyxl.formatting.rule import ColorScaleRule, CellIsRule, FormulaRule >>> >>> wb = Workbook() >>> ws = wb.active >>> >>> # Create fill >>> redFill = PatternFill(start_color='EE1111', ... end_color='EE1111', ... fill_type='solid') >>> >>> # Add a two-color scale >>> # Takes colors in excel 'RRGGBB' style. >>> ws.conditional_formatting.add('A1:A10', ... ColorScaleRule(start_type='min', start_color='AA0000', ... end_type='max', end_color='00AA00') ... ) >>> >>> # Add a three-color scale >>> ws.conditional_formatting.add('B1:B10', ... ColorScaleRule(start_type='percentile', start_value=10, start_color='AA0000', ... mid_type='percentile', mid_value=50, mid_color='0000AA', ... end_type='percentile', end_value=90, end_color='00AA00') ... ) >>> >>> # Add a conditional formatting based on a cell comparison >>> # addCellIs(range_string, operator, formula, stopIfTrue, wb, font, border, fill) >>> # Format if cell is less than 'formula' >>> ws.conditional_formatting.add('C2:C10', ... CellIsRule(operator='lessThan', formula=['C$1'], stopIfTrue=True, fill=redFill)) >>> >>> # Format if cell is between 'formula' >>> ws.conditional_formatting.add('D2:D10', ... CellIsRule(operator='between', formula=['1','5'], stopIfTrue=True, fill=redFill)) >>> >>> # Format using a formula >>> ws.conditional_formatting.add('E1:E10', ... FormulaRule(formula=['ISBLANK(E1)'], stopIfTrue=True, fill=redFill)) >>> >>> # Aside from the 2-color and 3-color scales, format rules take fonts, borders and fills for styling: >>> myFont = Font() >>> myBorder = Border() >>> ws.conditional_formatting.add('E1:E10', ... FormulaRule(formula=['E1=0'], font=myFont, border=myBorder, fill=redFill)) >>> >>> # Highlight cells that contain particular text by using a special formula >>> red_text = Font(color="9C0006") >>> red_fill = PatternFill(bgColor="FFC7CE") >>> dxf = DifferentialStyle(font=red_text, fill=red_fill) >>> rule = Rule(type="containsText", operator="containsText", text="highlight", dxf=dxf) >>> rule.formula = ['NOT(ISERROR(SEARCH("highlight",A1)))'] >>> ws.conditional_formatting.add('A1:F40', rule) >>> wb.save("test.xlsx") Formatting Entire Rows ---------------------- Sometimes you want to apply a conditional format to more than one cell, say a row of cells which contain a particular value. >>> ws.append(['Software', 'Developer', 'Version']) >>> ws.append(['Excel', 'Microsoft', '2016']) >>> ws.append(['openpyxl', 'Open source', '2.6']) >>> ws.append(['OpenOffice', 'Apache', '4.1.4']) >>> ws.append(['Word', 'Microsoft', '2010']) We want to higlight the rows where the developer is Microsoft. We do this by creating an expression rule and using a formula to identify which rows contain software developed by Microsoft. >>> red_fill = PatternFill(bgColor="FFC7CE") >>> dxf = DifferentialStyle(fill=red_fill) >>> r = Rule(type="expression", dxf=dxf, stopIfTrue=True) >>> r.formula = ['$A2="Microsoft"'] >>> ws.conditional_formatting.add("A1:C10", r) .. note:: The formula uses an **absolute** reference to the column referred to, ``B`` in this case; but a **relative** row number, in this case ``1`` to the range over which the format is applied. It can be tricky to get this right but the rule can be adjusted even after it has been added to the worksheet's condidtional format collection. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/formula.rst0000644000000000000000000001073100000000000013236 0ustar00Parsing Formulas ================ `openpyxl` supports limited parsing of formulas embedded in cells. The `openpyxl.formula` package contains a `Tokenizer` class to break formulas into their consitutuent tokens. Usage is as follows: .. doctest >>> from openpyxl.formula import Tokenizer >>> tok = Tokenizer("""=IF($A$1,"then True",MAX(DEFAULT_VAL,'Sheet 2'!B1))""") >>> print("\n".join("%12s%11s%9s" % (t.value, t.type, t.subtype) for t in tok.items)) IF( FUNC OPEN $A$1 OPERAND RANGE , SEP ARG "then True" OPERAND TEXT , SEP ARG MAX( FUNC OPEN DEFAULT_VAL OPERAND RANGE , SEP ARG 'Sheet 2'!B1 OPERAND RANGE ) FUNC CLOSE ) FUNC CLOSE As shown above, tokens have three attributes of interest: * ``.value``: The substring of the formula that produced this token * ``.type``: The type of token this represents. Can be one of - ``Token.LITERAL``: If the cell does not contain a formula, its value is represented by a single ``LITERAL`` token. - ``Token.OPERAND``: A generic term for any value in the Excel formula. (See ``.subtype`` below for more details). - ``Token.FUNC``: Function calls are broken up into tokens for the opener (e.g., ``SUM(``), followed by the arguments, followed by the closer (i.e., ``)``). The function name and opening parenthesis together form one ``FUNC`` token, and the matching parenthesis forms another ``FUNC`` token. - ``Token.ARRAY``: Array literals (enclosed between curly braces) get two ``ARRAY`` tokens each, one for the opening ``{`` and one for the closing ``}``. - ``Token.PAREN``: When used for grouping subexpressions (and not to denote function calls), parentheses are tokenized as ``PAREN`` tokens (one per character). - ``Token.SEP``: These tokens are created from either commas (``,``) or semicolons (``;``). Commas create ``SEP`` tokens when they are used to separate function arguments (e.g., ``SUM(a,b)``) or when they are used to separate array elements (e.g., ``{a,b}``). (They have another use as an infix operator for joining ranges). Semicolons are always used to separate rows in an array literal, so always create ``SEP`` tokens. - ``Token.OP_PRE``: Designates a prefix unary operator. Its value is always ``+`` or ``-`` - ``Token.OP_IN``: Designates an infix binary operator. Possible values are ``>=``, ``<=``, ``<>``, ``=``, ``>``, ``<``, ``*``, ``/``, ``+``, ``-``, ``^``, or ``&``. - ``Token.OP_POST``: Designates a postfix unary operator. Its value is always ``%``. - ``Token.WSPACE``: Created for any whitespace encountered. Its value is always a single space, regardless of how much whitespace is found. * ``.subtype``: Some of the token types above use the subtype to provide additional information about the token. Possible subtypes are: + ``Token.TEXT``, ``Token.NUMBER``, ``Token.LOGICAL``, ``Token.ERROR``, ``Token.RANGE``: these subtypes describe the various forms of ``OPERAND`` found in formulae. ``LOGICAL`` is either ``TRUE`` or ``FALSE``, ``RANGE`` is either a named range or a direct reference to another range. ``TEXT``, ``NUMBER``, and ``ERROR`` all refer to literal values in the formula + ``Token.OPEN`` and ``Token.CLOSE``: these two subtypes are used by ``PAREN``, ``FUNC``, and ``ARRAY``, to describe whether the token is opening a new subexpression or closing it. + ``Token.ARG`` and ``Token.ROW``: are used by the ``SEP`` tokens, to distinguish between the comma and semicolon. Commas produce tokens of subtype ``ARG`` whereas semicolons produce tokens of subtype ``ROW`` Translating formulae from one location to another ------------------------------------------------- It is possible to translate (in the mathematical sense) formulae from one location to another using the :class:`openpyxl.formulas.translate.Translator` class. For example, there a range of cells ``B2:E7`` with a sum of each row in column ``F``:: >>> from openpyxl.formula.translate import Translator >>> ws['F2'] = "=SUM(B2:E2)" >>> # move the formula one colum to the right >>> ws['G2'] = Translator("=SUM(B2:E2)", origin="F2").translate_formula("G2") >>> ws['G2'].value '=SUM(C2:F2)' .. note:: This is limited to the same general restrictions of formulae: `A1` cell-references only and no support for defined names. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/index.rst0000644000000000000000000001363400000000000012705 0ustar00openpyxl - A Python library to read/write Excel 2010 xlsx/xlsm files =========================================================================== :Author: Eric Gazoni, Charlie Clark :Source code: https://foss.heptapod.net/openpyxl/openpyxl :Issues: https://foss.heptapod.net/openpyxl/openpyxl/-/issues :Generated: |today| :License: MIT/Expat :Version: |release| .. include:: ../README.rst Support ------- This is an open source project, maintained by volunteers in their spare time. This may well mean that particular features or functions that you would like are missing. But things don't have to stay that way. You can contribute the project :doc:`development` yourself or contract a developer for particular features. Professional support for openpyxl is available from `Clark Consulting & Research `_ and `Adimian `_. Donations to the project to support further development and maintenance are welcome. Bug reports and feature requests should be submitted using the `issue tracker `_. Please provide a full traceback of any error you see and if possible a sample file. If for reasons of confidentiality you are unable to make a file publicly available then contact of one the developers. The repository is being provided by `Octobus `_ and `Clever Cloud `_. How to Contribute ----------------- Any help will be greatly appreciated, just follow those steps: 1. Please join the group and create a branch (https://foss.heptapod.net/openpyxl/openpyxl/) and follow the `Merge Request Start Guide `_. for each independent feature, don't try to fix all problems at the same time, it's easier for those who will review and merge your changes ;-) 2. Hack hack hack 3. Don't forget to add unit tests for your changes! (YES, even if it's a one-liner, changes without tests will **not** be accepted.) There are plenty of examples in the source if you lack know-how or inspiration. 4. If you added a whole new feature, or just improved something, you can be proud of it, so add yourself to the AUTHORS file :-) 5. Let people know about the shiny thing you just implemented, update the docs! 6. When it's done, just issue a pull request (click on the large "pull request" button on *your* repository) and wait for your code to be reviewed, and, if you followed all theses steps, merged into the main repository. For further information see :doc:`development` Other ways to help ++++++++++++++++++ There are several ways to contribute, even if you can't code (or can't code well): * triaging bugs on the bug tracker: closing bugs that have already been closed, are not relevant, cannot be reproduced, ... * updating documentation in virtually every area: many large features have been added (mainly about charts and images at the moment) but without any documentation, it's pretty hard to do anything with it * proposing compatibility fixes for different versions of Python: we support 3.6, 3.7, 3.8 and 3.9. Installation ------------ Install openpyxl using pip. It is advisable to do this in a Python virtualenv without system packages:: $ pip install openpyxl .. note:: There is support for the popular `lxml`_ library which will be used if it is installed. This is particular useful when creating large files. .. _lxml: http://lxml.de .. warning:: To be able to include images (jpeg, png, bmp,...) into an openpyxl file, you will also need the "pillow" library that can be installed with:: $ pip install pillow or browse https://pypi.python.org/pypi/Pillow/, pick the latest version and head to the bottom of the page for Windows binaries. Working with a checkout +++++++++++++++++++++++ Sometimes you might want to work with the checkout of a particular version. This may be the case if bugs have been fixed but a release has not yet been made. .. parsed-literal:: $ pip install -e hg+https://foss.heptapod.net/openpyxl/openpyxl/@\ |version|\ #egg=openpyxl Usage examples -------------- Tutorial ++++++++ .. toctree:: tutorial Cookbook ++++++++ .. toctree:: usage Performance ----------- .. toctree:: performance Other topics ------------ .. toctree:: :maxdepth: 2 optimized .. toctree:: :maxdepth: 1 editing_worksheets .. toctree:: :maxdepth: 1 pandas .. toctree:: :maxdepth: 1 charts/introduction .. toctree:: :maxdepth: 1 comments .. toctree:: :maxdepth: 1 styles .. toctree:: :maxdepth: 1 worksheet_properties .. toctree:: :maxdepth: 1 formatting .. toctree:: :maxdepth: 1 pivot .. toctree:: :maxdepth: 1 print_settings .. toctree:: :maxdepth: 1 filters .. toctree:: :maxdepth: 1 validation .. toctree:: :maxdepth: 1 defined_names .. toctree:: :maxdepth: 1 worksheet_tables .. toctree:: :maxdepth: 1 formula .. toctree:: :maxdepth: 1 datetime .. toctree:: :maxdepth: 1 protection Information for Developers -------------------------- .. toctree:: :maxdepth: 1 development API Documentation ------------------ Key Classes +++++++++++ * :class:`openpyxl.workbook.workbook.Workbook` * :class:`openpyxl.worksheet.worksheet.Worksheet` * :class:`openpyxl.cell.cell.Cell` Full API ++++++++ .. toctree:: :maxdepth: 2 api/openpyxl Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` Release Notes ============= .. toctree:: :maxdepth: 1 changes ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/logo.png0000644000000000000000000001260100000000000012503 0ustar00PNG  IHDR#r;sBIT|d pHYs-ۜtEXtSoftwarewww.inkscape.org<IDATx{\]?wfvgwN4q& Q BD4*HJyT «hҖҤ$-؎qv3;;{3wClt5;s=gfg$I :ȬFsY49C]9^ȔZgr\t] [aJƯk]xZ.;B!0G8*@տe+E,,~ۂfV|5d<'n_Ft;\W / L)W ȴaX 1 *jY4j>sIP3e0Yf`"j;|(p]0QZQ3<|{ 8[]G If~`h~8EmۏB @G^C>dxnIrFVWBI 6t0 QE@< 63 x=o|dSfq ~28f ULWhuVuE\ x2I9`c& n΀"R>hkqu 4ـW FmcZ ʇQ%࿈h)~+vڮ*O{~nd_ ǁ?6@#vN׆qdPq.(r~h%IҷnʷRrbTnA<[2}M9 ]Iv`uGj'\D@enդ_:⁍K?oF.GFn` 0X g,Ձb8M*_0vBRRBYX^C2֢GMϙ^#O~?WAEͫ8L968,P lԧ ?!wM?X+π' q,?Ydnƫ }aͼXc`g 'yrꐮ*ԧ!$Άׅu~z~]>2  ǧc&,ՁߍH=sP! b N6qv>퇑@fkg_7R3Œy~U_, -i99ڼ=~KFGovw&DoC+0!WoIfe+h\mWK!_5Ta8hm z!o{9̺ }L_ozaN EBD; UlB6*["mY=,o6";GZ=`a8|x绀sk*?̷Yg_Ǜ|."U_rA]"l6Pދ҄F]Lۯ@A3.b#?d ߻ K ^wE"L[BldBC3 @:ൾv5j 1O G@IYoE6s? рB>3 ԁכmw{ߏho!Y #~w' wo3ާӈF^^M1LqmiB,SY_;1+EDx1`< zoO#Uf5 9E6DcvQڀl^$xTmn%!r~g w bzߋC9^(My9V܉ .eyDP3Oo|ೃT oB4:+}5Ex47< Zyܥ?myӛYg0rßv狝tCsiHAd/f"]Y$5󯗥G"LlBQq "̳1x-D[*Ut ,]X"HSZ%zx3":_"J_3d Α=UOϥp ]H|]jK8-]Z! jqjČϦ-`KoFVSWfevCgJp*H^7W japBG(mEJ4 <i_MTUr˷ٷM!UayօQZAGO{Ok:3N 0߄ce5h7`:r5^6A?sրY.#\:Lyn-zfܘ#ii+8F~&A#ΡhQ1spH⟫fl"`n~wNL߯]Ǘ 4v!#4/E*2‰cpUk$T6?yQ8YnU:T&7G߈q{Fgo9H1ki`BU26r+5 nnj.u]jl{F4Qu44GwBbcܯ0" __!m:u9 *ӈ`o+1w%{*ʰB] Sn$*{&_)B==_?=?)1{\ &qD{j[@4@4^י̬L-]cך6Huo:},C$-7Hu&a\Suj6gJJrG(N?_:,r.cdMDa,ieiFw[]YދlXe~/6nܕ{<5@%#Iߗ?6+0#g%PT-OaXNkԣul+"4BCFK~9716ٴ{9D"@#W-%5b,)4uWCz,vjeUjzԝ,jܟ'd/@2My CnRj"cCpj7y{)opw;SQ0"qǠ"] ;p0횛 9y&6"&l} ~ DYӒg[3c~3+ߊs ߏjq3HqYxH {EKB\OI$x6WR4^KurE Hڀ=ŧncT8P[wAuZXÆ+e+Nd93zKrhr$؛{2IuΕ*85\$589Es6kfdT%eOG5_ ֺjuB"@j8.eUJv-ʫ(W͆AQ0OȦ!w-FiV㋾պUK;* Cȝs.I=1 k]ؼo `오71U,(r=蟆Ʊp)A%(2^' EW=c5JVh{5ɺ1jbT[XD1ѱnXI\Tt6U*fm NBSTgC]㈯!D k{pVnU$[RjIP_]"'F\X% ϝJlfLm`||K25s.nDY0c7nɩAus/f6VMj3ZТI\~KYBM"X{`{v.z^Az57ljRVLZdP K G\]S}(S;Jk]^b%m:UhekqX&fNu>t[Y%e ud(:VzIJNX#5+C/K|3X+m3g;Vpt.ΌWQ,(&ZPk9[Z@k|smc|/S@]Y$by ",:` where ^ is one of echo. html to make standalone HTML files echo. dirhtml to make HTML files named index.html in directories echo. singlehtml to make a single large HTML file echo. pickle to make pickle files echo. json to make JSON files echo. htmlhelp to make HTML files and a HTML help project echo. qthelp to make HTML files and a qthelp project echo. devhelp to make HTML files and a Devhelp project echo. epub to make an epub echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter echo. text to make text files echo. man to make manual pages echo. changes to make an overview over all changed/added/deprecated items echo. linkcheck to check all external links for integrity echo. doctest to run all doctests embedded in the documentation if enabled goto end ) if "%1" == "clean" ( for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i del /q /s %BUILDDIR%\* goto end ) if "%1" == "html" ( %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html echo. echo.Build finished. The HTML pages are in %BUILDDIR%/html. goto end ) if "%1" == "dirhtml" ( %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml echo. echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. goto end ) if "%1" == "singlehtml" ( %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml echo. echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. goto end ) if "%1" == "pickle" ( %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle echo. echo.Build finished; now you can process the pickle files. goto end ) if "%1" == "json" ( %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json echo. echo.Build finished; now you can process the JSON files. goto end ) if "%1" == "htmlhelp" ( %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp echo. echo.Build finished; now you can run HTML Help Workshop with the ^ .hhp project file in %BUILDDIR%/htmlhelp. goto end ) if "%1" == "qthelp" ( %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp echo. echo.Build finished; now you can run "qcollectiongenerator" with the ^ .qhcp project file in %BUILDDIR%/qthelp, like this: echo.^> qcollectiongenerator %BUILDDIR%\qthelp\openpyxl.qhcp echo.To view the help file: echo.^> assistant -collectionFile %BUILDDIR%\qthelp\openpyxl.ghc goto end ) if "%1" == "devhelp" ( %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp echo. echo.Build finished. goto end ) if "%1" == "epub" ( %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub echo. echo.Build finished. The epub file is in %BUILDDIR%/epub. goto end ) if "%1" == "latex" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex echo. echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. goto end ) if "%1" == "text" ( %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text echo. echo.Build finished. The text files are in %BUILDDIR%/text. goto end ) if "%1" == "man" ( %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man echo. echo.Build finished. The manual pages are in %BUILDDIR%/man. goto end ) if "%1" == "changes" ( %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes echo. echo.The overview file is in %BUILDDIR%/changes. goto end ) if "%1" == "linkcheck" ( %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck echo. echo.Link check complete; look for any errors in the above output ^ or in %BUILDDIR%/linkcheck/output.txt. goto end ) if "%1" == "doctest" ( %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest echo. echo.Testing of doctests in the sources finished, look at the ^ results in %BUILDDIR%/doctest/output.txt. goto end ) :end ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/optimized.rst0000644000000000000000000000766100000000000013605 0ustar00Optimised Modes =============== Read-only mode -------------- Sometimes, you will need to open or write extremely large XLSX files, and the common routines in openpyxl won't be able to handle that load. Fortunately, there are two modes that enable you to read and write unlimited amounts of data with (near) constant memory consumption. Introducing :class:`openpyxl.worksheet._read_only.ReadOnlyWorksheet`:: from openpyxl import load_workbook wb = load_workbook(filename='large_file.xlsx', read_only=True) ws = wb['big_data'] for row in ws.rows: for cell in row: print(cell.value) # Close the workbook after reading wb.close() .. warning:: * :class:`openpyxl.worksheet._read_only.ReadOnlyWorksheet` is read-only * Unlike a normal workbook, a read-only workbook will use lazy loading. The workbook must be explicitly closed with the :func:`close()` method. Cells returned are not regular :class:`openpyxl.cell.cell.Cell` but :class:`openpyxl.cell._read_only.ReadOnlyCell`. Worksheet dimensions ++++++++++++++++++++ Read-only mode relies on applications and libraries that created the file providing correct information about the worksheets, specifically the used part of it, known as the dimensions. Some applications set this incorrectly. You can check the apparent dimensions of a worksheet using `ws.calculate_dimension()`. If this returns a range that you know is incorrect, say `A1:A1` then simply resetting the max_row and max_column attributes should allow you to work with the file:: ws.reset_dimensions() Write-only mode --------------- Here again, the regular :class:`openpyxl.worksheet.worksheet.Worksheet` has been replaced by a faster alternative, the :class:`openpyxl.worksheet._write_only.WriteOnlyWorksheet`. When you want to dump large amounts of data make sure you have `lxml` installed. .. :: doctest >>> from openpyxl import Workbook >>> wb = Workbook(write_only=True) >>> ws = wb.create_sheet() >>> >>> # now we'll fill it with 100 rows x 200 columns >>> >>> for irow in range(100): ... ws.append(['%d' % i for i in range(200)]) >>> # save the file >>> wb.save('new_big_file.xlsx') # doctest: +SKIP If you want to have cells with styles or comments then use a :func:`openpyxl.cell.WriteOnlyCell` .. :: doctest >>> from openpyxl import Workbook >>> wb = Workbook(write_only = True) >>> ws = wb.create_sheet() >>> from openpyxl.cell import WriteOnlyCell >>> from openpyxl.comments import Comment >>> from openpyxl.styles import Font >>> cell = WriteOnlyCell(ws, value="hello world") >>> cell.font = Font(name='Courier', size=36) >>> cell.comment = Comment(text="A comment", author="Author's Name") >>> ws.append([cell, 3.14, None]) >>> wb.save('write_only_file.xlsx') This will create a write-only workbook with a single sheet, and append a row of 3 cells: one text cell with a custom font and a comment, a floating-point number, and an empty cell (which will be discarded anyway). .. warning:: * Unlike a normal workbook, a newly-created write-only workbook does not contain any worksheets; a worksheet must be specifically created with the :func:`create_sheet()` method. * In a write-only workbook, rows can only be added with :func:`append()`. It is not possible to write (or read) cells at arbitrary locations with :func:`cell()` or :func:`iter_rows()`. * It is able to export unlimited amount of data (even more than Excel can handle actually), while keeping memory usage under 10Mb. * A write-only workbook can only be saved once. After that, every attempt to save the workbook or append() to an existing worksheet will raise an :class:`openpyxl.utils.exceptions.WorkbookAlreadySaved` exception. * Everything that appears in the file before the actual cell data must be created before cells are added because it must written to the file before then. For example, `freeze_panes` should be set before cells are added. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/pandas.rst0000644000000000000000000000463200000000000013042 0ustar00Working with Pandas and NumPy ============================= openpyxl is able to work with the popular libraries `Pandas `_ and `NumPy `_ NumPy Support ------------- openpyxl has builtin support for the NumPy types float, integer and boolean. DateTimes are supported using the Pandas' Timestamp type. Working with Pandas Dataframes ------------------------------ The :func:`openpyxl.utils.dataframe.dataframe_to_rows` function provides a simple way to work with Pandas Dataframes:: from openpyxl.utils.dataframe import dataframe_to_rows wb = Workbook() ws = wb.active for r in dataframe_to_rows(df, index=True, header=True): ws.append(r) While Pandas itself supports conversion to Excel, this gives client code additional flexibility including the ability to stream dataframes straight to files. To convert a dataframe into a worksheet highlighting the header and index:: wb = Workbook() ws = wb.active for r in dataframe_to_rows(df, index=True, header=True): ws.append(r) for cell in ws['A'] + ws[1]: cell.style = 'Pandas' wb.save("pandas_openpyxl.xlsx") Alternatively, if you just want to convert the data you can use write-only mode:: from openpyxl.cell.cell import WriteOnlyCell wb = Workbook(write_only=True) ws = wb.create_sheet() cell = WriteOnlyCell(ws) cell.style = 'Pandas' def format_first_row(row, cell): for c in row: cell.value = c yield cell rows = dataframe_to_rows(df) first_row = format_first_row(next(rows), cell) ws.append(first_row) for row in rows: row = list(row) cell.value = row[0] row[0] = cell ws.append(row) wb.save("openpyxl_stream.xlsx") This code will work just as well with a standard workbook. Converting a worksheet to a Dataframe ------------------------------------- To convert a worksheet to a Dataframe you can use the `values` property. This is very easy if the worksheet has no headers or indices:: df = DataFrame(ws.values) If the worksheet does have headers or indices, such as one created by Pandas, then a little more work is required:: from itertools import islice data = ws.values cols = next(data)[1:] data = list(data) idx = [r[0] for r in data] data = (islice(r, 1, None) for r in data) df = DataFrame(data, index=idx, columns=cols) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/performance.rst0000644000000000000000000000574600000000000014104 0ustar00Performance =========== openpyxl attempts to balance functionality and performance. Where in doubt, we have focused on functionality over optimisation: performance tweaks are easier once an API has been established. Memory use is fairly high in comparison with other libraries and applications and is approximately 50 times the original file size, e.g. 2.5 GB for a 50 MB Excel file. As many use cases involve either only reading or writing files, the :doc:`optimized` modes mean this is less of a problem. Benchmarks ---------- All benchmarks are synthetic and extremely dependent upon the hardware but they can nevertheless give an indication. Write Performance +++++++++++++++++ The `benchmark code `_ can be adjusted to use more sheets and adjust the proportion of data that is strings. Because the version of Python being used can also significantly affect performance, a `driver script `_ can also be used to test with different Python versions with a tox environment. Performance is compared with the excellent alternative library xlsxwriter .. literalinclude:: write_performance.txt Read Performance ++++++++++++++++ Performance is measured using a file provided with a previous `bug report `_ and compared with the older xlrd library. xlrd is primarily for the older BIFF file format of .XLS files but it does have limited support for XLSX. The code for the `benchmark `_ shows the importance of choosing the right options when working with a file. In this case disabling external links stops openpyxl opening cached copies of the linked worksheets. One major difference between the libraries is that openpyxl's read-only mode opens a workbook almost immediately making it suitable for multiple processes, this also readuces memory use significantly. xlrd does also not automatically convert dates and times into Python datetimes, though it does annotate cells accordingly but to do this in client code significantly reduces performance. .. literalinclude:: read_performance.txt Parallelisation +++++++++++++++ Reading worksheets is fairly CPU-intensive which limits any benefits to be gained by parallelisation. However, if you are mainly interested in dumping the contents of a workbook then you can use openpyxl's read-only mode and open multiple instances of a workbook and take advantage of multiple CPUs. `Sample code `_ using the same source file as for read performance shows that performance scales reasonably with only a slight overhead due to creating additional Python processes. .. code-block:: Parallised Read Workbook loaded 1.12s >>DATA>> 2.27s Output Model 2.30s Store days 100% 37.18s OptimizationData 44.09s Store days 0% 45.60s Total time 46.76s ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/pivot.rst0000644000000000000000000000163400000000000012734 0ustar00Pivot Tables ============ openpyxl provides read-support for pivot tables so that they will be preserved in existing files. The specification for pivot tables, while extensive, is not very clear and it is not intended that client code should be able to create pivot tables. However, it should be possible to edit and manipulate existing pivot tables, eg. change their ranges or whether they should update automatically settings. As is the case for charts, images and tables there is currently no management API for pivot tables so that client code will have to loop over the ``_pivots`` list of a worksheet. Example ------- .. code:: from openpyxl import load_workbook wb = load_workbook("campaign.xlsx") ws = wb["Results"] pivot = ws._pivots[0] # any will do as they share the same cache pivot.cache.refreshOnLoad = True For further information see :class:`openpyxl.pivot.cache.CacheDefinition` ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/print_settings.rst0000644000000000000000000000323300000000000014644 0ustar00Print Settings ============== openpyxl provides reasonably full support for print settings. Edit Print Options ------------------- .. :: doctest >>> from openpyxl.workbook import Workbook >>> >>> wb = Workbook() >>> ws = wb.active >>> >>> ws.print_options.horizontalCentered = True >>> ws.print_options.verticalCentered = True Headers and Footers ------------------- Headers and footers use their own formatting language. This is fully supported when writing them but, due to the complexity and the possibility of nesting, only partially when reading them. There is support for the font, size and color for a left, centre/center, or right element. Granular control (highlighting individuals words) will require applying control codes manually. .. :: doctest >>> from openpyxl.workbook import Workbook >>> >>> wb = Workbook() >>> ws = wb.active >>> >>> ws.oddHeader.left.text = "Page &[Page] of &N" >>> ws.oddHeader.left.size = 14 >>> ws.oddHeader.left.font = "Tahoma,Bold" >>> ws.oddHeader.left.color = "CC3366" Also supported are `evenHeader` and `evenFooter` as well as `firstHeader` and `firstFooter`. Add Print Titles ---------------- You can print titles on every page to ensure that the data is properly labelled. .. :: doctest >>> from openpyxl.workbook import Workbook >>> >>> wb = Workbook() >>> ws = wb.active >>> >>> ws.print_title_cols = 'A:B' # the first two cols >>> ws.print_title_rows = '1:1' # the first row Add a Print Area ---------------- You can select a part of a worksheet as the only part that you want to print .. :: doctest >>> from openpyxl.workbook import Workbook >>> >>> wb = Workbook() >>> ws = wb.active >>> >>> ws.print_area = 'A1:F10' ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/protection.rst0000644000000000000000000000533300000000000013761 0ustar00Protection ========== .. warning:: Password protecting a workbook or worksheet only provides a quite basic level of security. The data is not encrypted, so can be modified by any number of freely available tools. In fact the specification states: "Worksheet or workbook element protection should not be confused with file security. It is meant to make your workbook safe from unintentional modification, and cannot protect it from malicious modification." Openpyxl provides support for protecting a workbook and worksheet from modification. The Open XML "Legacy Password Hash Algorithm" is used to generate hashed password values unless another algorithm is explicitly configured. Workbook Protection ------------------- To prevent other users from viewing hidden worksheets, adding, moving, deleting, or hiding worksheets, and renaming worksheets, you can protect the structure of your workbook with a password. The password can be set using the :func:`openpyxl.workbook.protection.WorkbookProtection.workbookPassword` property :: >>> wb.security.workbookPassword = '...' >>> wb.security.lockStructure = True Similarly removing change tracking and change history from a shared workbook can be prevented by setting another password. This password can be set using the :func:`openpyxl.workbook.protection.WorkbookProtection.revisionsPassword` property :: >>> wb.security.revisionsPassword = '...' Other properties on the :class:`openpyxl.workbook.protection.WorkbookProtection` object control exactly what restrictions are in place, but these will only be enforced if the appropriate password is set. Specific setter functions are provided if you need to set the raw password value without using the default hashing algorithm - e.g. :: hashed_password = ... wb.security.set_workbook_password(hashed_password, already_hashed=True) Worksheet Protection -------------------- Various aspects of a worksheet can also be locked by setting attributes on the :class:`openpyxl.worksheet.protection.SheetProtection` object. Unlike workbook protection, sheet protection may be enabled with or without using a password. Sheet protection is enabled using the :attr:`openpxyl.worksheet.protection.SheetProtection.sheet` attribute or calling `enable()` or `disable()`:: >>> ws = wb.active >>> ws.protection.sheet = True >>> ws.protection.enable() >>> ws.protection.disable() If no password is specified, users can disable configured sheet protection without specifying a password. Otherwise they must supply a password to change configured protections. The password is set using the :func:`openpxyl.worksheet.protection.SheetProtection.password` property :: >>> ws = wb.active >>> ws.protection.password = '...' ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/read_performance.txt0000644000000000000000000000144000000000000015071 0ustar00Versions: python: 3.6.9 xlread: 1.2.0 openpyxl: 3.0.1 openpyxl, read-only Workbook loaded 1.14s OptimizationData 23.17s Output Model 0.00s >>DATA>> 0.00s Store days 0% 23.92s Store days 100% 17.35s Total time 65.59s 0 cells in total Versions: python: 3.7.5 xlread: 1.2.0 openpyxl: 3.0.1 openpyxl, read-only Workbook loaded 0.98s OptimizationData 21.35s Output Model 0.00s >>DATA>> 0.00s Store days 0% 20.70s Store days 100% 16.16s Total time 59.19s 0 cells in total Versions: python: 3.8.0 xlread: 1.2.0 openpyxl: 3.0.1 openpyxl, read-only Workbook loaded 0.90s OptimizationData 19.58s Output Model 0.00s >>DATA>> 0.00s Store days 0% 19.35s Store days 100% 15.02s Total time 54.85s 0 cells in total ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/styles.rst0000644000000000000000000002164400000000000013121 0ustar00Working with styles =================== Introduction ------------ Styles are used to change the look of your data while displayed on screen. They are also used to determine the formatting for numbers. Styles can be applied to the following aspects: * font to set font size, color, underlining, etc. * fill to set a pattern or color gradient * border to set borders on a cell * cell alignment * protection The following are the default values .. :: doctest >>> from openpyxl.styles import PatternFill, Border, Side, Alignment, Protection, Font >>> font = Font(name='Calibri', ... size=11, ... bold=False, ... italic=False, ... vertAlign=None, ... underline='none', ... strike=False, ... color='FF000000') >>> fill = PatternFill(fill_type=None, ... start_color='FFFFFFFF', ... end_color='FF000000') >>> border = Border(left=Side(border_style=None, ... color='FF000000'), ... right=Side(border_style=None, ... color='FF000000'), ... top=Side(border_style=None, ... color='FF000000'), ... bottom=Side(border_style=None, ... color='FF000000'), ... diagonal=Side(border_style=None, ... color='FF000000'), ... diagonal_direction=0, ... outline=Side(border_style=None, ... color='FF000000'), ... vertical=Side(border_style=None, ... color='FF000000'), ... horizontal=Side(border_style=None, ... color='FF000000') ... ) >>> alignment=Alignment(horizontal='general', ... vertical='bottom', ... text_rotation=0, ... wrap_text=False, ... shrink_to_fit=False, ... indent=0) >>> number_format = 'General' >>> protection = Protection(locked=True, ... hidden=False) >>> Cell Styles and Named Styles ---------------------------- There are two types of styles: cell styles and named styles, also known as style templates. Cell Styles +++++++++++ Cell styles are shared between objects and once they have been assigned they cannot be changed. This stops unwanted side-effects such as changing the style for lots of cells when only one changes. .. :: doctest >>> from openpyxl.styles import colors >>> from openpyxl.styles import Font, Color >>> from openpyxl import Workbook >>> wb = Workbook() >>> ws = wb.active >>> >>> a1 = ws['A1'] >>> d4 = ws['D4'] >>> ft = Font(color="FF0000") >>> a1.font = ft >>> d4.font = ft >>> >>> a1.font.italic = True # is not allowed # doctest: +SKIP >>> >>> # If you want to change the color of a Font, you need to reassign it:: >>> >>> a1.font = Font(color="FF0000", italic=True) # the change only affects A1 Copying styles -------------- Styles can also be copied .. :: doctest >>> from openpyxl.styles import Font >>> from copy import copy >>> >>> ft1 = Font(name='Arial', size=14) >>> ft2 = copy(ft1) >>> ft2.name = "Tahoma" >>> ft1.name 'Arial' >>> ft2.name 'Tahoma' >>> ft2.size # copied from the 14.0 Colours ------- Colours for fonts, backgrounds, borders, etc. can be set in three ways: indexed, aRGB or theme. Indexed colours are the legacy implementation and the colours themselves depend upon the index provided with the workbook or with the application default. Theme colours are useful for complementary shades of colours but also depend upon the theme being present in the workbook. It is, therefore, advisable to use aRGB colours. .. :: doctest aRGB colours ++++++++++++ RGB colours are set using hexadecimal values for red, green and blue. >>> from openpyxl.styles import Font >>> font = Font(color="FF0000") The alpha value refers in theory to the transparency of the colour but this is not relevant for cell styles. The default of 00 will prepended to any simple RGB value: >>> from openpyxl.styles import Font >>> font = Font(color="00FF00") >>> font.color.rgb '0000FF00' There is also support for legacy indexed colours as well as themes and tints. >>> from openpyxl.styles.colors import Color >>> c = Color(indexed=32) >>> c = Color(theme=6, tint=0.5) Indexed Colours +++++++++++++++ .. raw:: html :file: colours.html The indices 64 and 65 cannot be set and are reserved for the system foreground and background colours respectively. Applying Styles --------------- Styles are applied directly to cells .. :: doctest >>> from openpyxl.workbook import Workbook >>> from openpyxl.styles import Font, Fill >>> wb = Workbook() >>> ws = wb.active >>> c = ws['A1'] >>> c.font = Font(size=12) Styles can also applied to columns and rows but note that this applies only to cells created (in Excel) after the file is closed. If you want to apply styles to entire rows and columns then you must apply the style to each cell yourself. This is a restriction of the file format:: >>> col = ws.column_dimensions['A'] >>> col.font = Font(bold=True) >>> row = ws.row_dimensions[1] >>> row.font = Font(underline="single") .. _styling-merged-cells: Styling Merged Cells -------------------- The merged cell behaves similarly to other cell ojects. Its value and format is defined in its top-left cell. In order to change the border of the whole merged cell, change the border of its top-left cell. The formatting is generated for the purpose of writing. .. :: doctest >>> from openpyxl.styles import Border, Side, PatternFill, Font, GradientFill, Alignment >>> from openpyxl import Workbook >>> >>> wb = Workbook() >>> ws = wb.active >>> ws.merge_cells('B2:F4') >>> >>> top_left_cell = ws['B2'] >>> top_left_cell.value = "My Cell" >>> >>> thin = Side(border_style="thin", color="000000") >>> double = Side(border_style="double", color="ff0000") >>> >>> top_left_cell.border = Border(top=double, left=thin, right=thin, bottom=double) >>> top_left_cell.fill = PatternFill("solid", fgColor="DDDDDD") >>> top_left_cell.fill = fill = GradientFill(stop=("000000", "FFFFFF")) >>> top_left_cell.font = Font(b=True, color="FF0000") >>> top_left_cell.alignment = Alignment(horizontal="center", vertical="center") >>> >>> wb.save("styled.xlsx") Edit Page Setup ------------------- .. :: doctest >>> from openpyxl.workbook import Workbook >>> >>> wb = Workbook() >>> ws = wb.active >>> >>> ws.page_setup.orientation = ws.ORIENTATION_LANDSCAPE >>> ws.page_setup.paperSize = ws.PAPERSIZE_TABLOID >>> ws.page_setup.fitToHeight = 0 >>> ws.page_setup.fitToWidth = 1 Named Styles ++++++++++++ In contrast to Cell Styles, Named Styles are mutable. They make sense when you want to apply formatting to lots of different cells at once. NB. once you have assigned a named style to a cell, additional changes to the style will **not** affect the cell. Once a named style has been registered with a workbook, it can be referred to simply by name. Creating a Named Style ---------------------- .. :: doctest >>> from openpyxl.styles import NamedStyle, Font, Border, Side >>> highlight = NamedStyle(name="highlight") >>> highlight.font = Font(bold=True, size=20) >>> bd = Side(style='thick', color="000000") >>> highlight.border = Border(left=bd, top=bd, right=bd, bottom=bd) Once a named style has been created, it can be registered with the workbook: >>> wb.add_named_style(highlight) But named styles will also be registered automatically the first time they are assigned to a cell: >>> ws['A1'].style = highlight Once registered, assign the style using just the name: >>> ws['D5'].style = 'highlight' Using builtin styles -------------------- The specification includes some builtin styles which can also be used. Unfortunately, the names for these styles are stored in their localised forms. openpyxl will only recognise the English names and only exactly as written here. These are as follows: * 'Normal' # same as no style Number formats ++++++++++++++ * 'Comma' * 'Comma [0]' * 'Currency' * 'Currency [0]' * 'Percent' Informative +++++++++++ * 'Calculation' * 'Total' * 'Note' * 'Warning Text' * 'Explanatory Text' Text styles +++++++++++ * 'Title' * 'Headline 1' * 'Headline 2' * 'Headline 3' * 'Headline 4' * 'Hyperlink' * 'Followed Hyperlink' * 'Linked Cell' Comparisons +++++++++++ * 'Input' * 'Output' * 'Check Cell' * 'Good' * 'Bad' * 'Neutral' Highlights ++++++++++ * 'Accent1' * '20 % - Accent1' * '40 % - Accent1' * '60 % - Accent1' * 'Accent2' * '20 % - Accent2' * '40 % - Accent2' * '60 % - Accent2' * 'Accent3' * '20 % - Accent3' * '40 % - Accent3' * '60 % - Accent3' * 'Accent4' * '20 % - Accent4' * '40 % - Accent4' * '60 % - Accent4' * 'Accent5' * '20 % - Accent5' * '40 % - Accent5' * '60 % - Accent5' * 'Accent6' * '20 % - Accent6' * '40 % - Accent6' * '60 % - Accent6' * 'Pandas' For more information about the builtin styles please refer to the :mod:`openpyxl.styles.builtins` ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/table.png0000644000000000000000000004754400000000000012650 0ustar00PNG  IHDRv6sRGB@IDATx]|CI Bw$"ADAETT4+MEi -@$K?wp wkɽf޾6y;;;vFq=/D GDD7onE+@@BpC'7ΖΩtN 7iB& uW?D@ٳH@xQw\섂ƍزe x/@@ ũOڼic!A w.`~^' Vk.DFFbΝ6lT*Ö,?|N_p+WܹÇ"::u;;d_|Ή?͟4hSӖA[:miq'h./^ę3gy%z),kt>p@>58SoE#**_tt$F'ԗ g\;ۏ"FΐF֗?Ĥt)IYM2la]2NH<)%''cǎHO#"iϿT,}Ji5VKKKCxxxc+h$ĚzNPn]7C )h'as\<ʗ jqᜫWDmp,ΪobEw)VC5vh7\'ߎµ˃7,F>v옴Q+WY9EVV]eΦ >lfcbnw DTV-(Ju(U<5v$>nA93z)m33E7b3UOFP׷Kʺ{%lbsv96`5_y I ooozٞypSJ$- RYsOII~PgWreKwg{z*xϼ.]te=7-[l:r>o8lvP@1tFENUZ47Zp (Z?jeu(b{kѼ诊qȪo 4ێ3Ȫ+_EUc {}: OmctzsVZl@|RJFZrr$B5Y>o!"1p% [Ԣ1abמ={ЧO[,|^/ =߼0ܸ0^P_u41s>^u#PIH*R4iK)2t2| ?cTUߡj j'9O^c[< Jɕ_cհ罸]HBX!RI7UV ׯKB5uK u釄r'ɉ/΂ݒxXtdK秔Yf~lF%6oތ_~K,)p~Ĝ~X MJCYif |IرP(x57I"(XyW,H,\kԨWWWɦ.a;t o^¦&N%KD%7⧟~!ד&_҅L.I:MVT(:W|*OrYU9cD}cPʻLa/orΘ'or"]JڟA9k5,E2꼬0) UfeӈBrYKf;zXX$Y•_ʼ}]]MnBk{\_>>PG^s%,Zgرc'uI~c> ;wbasYodMYiмz#|Vi zSv\DZB۔O=L= FͿA섔HBFТz>p &sv0n[ܿ{mCrE rQnrZv=o߾]xu۳f͜5t,\9f9Qe~<k'6ӪUJ]Xk׮СCѲeKgl2rC2]㽜Ǭ߶~YCeer_V.'חr74^nG' qȉ9Γ*2r;R%'oG?/wr;[/K?>}2KnG܎~\_erׯ\V/{Cexr|N{܎Tɿݮ܎Kocr1Ra(#bX-]JWA7^xY3? {U֮G1/+wyS>'Ts'}99jC.#bF~erÿj˘v>'CmpLUK?lŸ#k}\W׬R߇=mVݢP}Ȯi=hZĦbW lӵ̓t8"<IR^w<POL;3WoS='.f ^ :ݱٕ___v|fwk}F;J~1D{VZ,'g2θwf3j|]يV򔅺š92ˌkhl_J/ghoU=/n+# ۉmƹm̂~[\Vy uqY}ҫdyϲ3act;}}UV ukal[?W˾Q*gZ"n؅0%JDPꆸAǑ8׿~3th em>?俄Douc#= mO lAԄU`xڊ~_u&Srl?i_(lsJ՛Ɵgn +"6?X?@{/wg\ O$a?siAUgP8rp>s&4wbG1%m2 4ي~ެꌢZr&vN.nIɈڳxEGYDD]lnh 쎡'㍅p9[>lkڃ~*毾_Jc|=6.F66=~ػx:ǕU#|姘r7^K$i2ON5l{V[Lc7VjGHZ#1W=xkX[1^4k4_F3&ʸz$'$#A֍P*/;05~\fsG,Uj, {N5:Я)!ޤX}ft T%>hT*^t_h+ԙ"cΌX52vܾ3è ǔӹ RI«?}34ohׅ]rU)6YC{cP]/:7ՏI?_n%M_{|Ek+;]+ԭ>s@'Ju~?ksx9dxށ]w^+Nǚ`VɂՔ4V3* n/]EݰRi%B?Y-zdn3g`{#кpcr,zKk_%Bw"q{ Xզs.3uK@Z 7R(EaH(ي~{AZZ^!:: M%\b3D )Idc R}XL2ǚ跭q@`Wi'jw1l?;ЯŢ ~7i ~335~yb`o!4J ߖK]bUw#v79ІBB-m4nT^/3#)ӯ!YY.Hn^S 9" xy/qL szBwlgN@J deۅp]~\FOoK ugfn;;,(nI7ngL-m -Z;ZZ؝)ϙojgA/jGm|5vk ugfɑ<+Mo/V N?{BAgi? 9-' g9@ vKPÞ&[ ߠ-0b꼒]6_E=}Ո2 C/o홧jtZ%ZmBzdsy@yq|)ii:M=|)SJtp6. , xweެRb*_/^j :*7O;[}6OMa#OmKSɕ^QeOJQ t`E`q4Użlv℘`A7G7sV&/ʴ4Ԩ=o$i0XCD2MO'c6m۲_ߜlN[kc*,dq8> ( fyc+]ʢlN}%oKtŬwA (-Ч!0uј{,^<a˝meլ$4"%^~Y8RK&ǦD@oC.љ$_#cY3~Oxpd$t&N:{Y B`oɩטI]q<gZטJaSUux#4_6 >4kkPrZwT3'ݢ!X#M˞4T&_R* ʠ4WtoӅI>&h]F>Ao9 U{R~TX|_ho6)зx|kO6D{IyIJݡ&P>1Ix+tV.iؘS٤WQ٨L_ \]Z,{yb@}UMNK]'6Dǭ*ΈGo-N7 %,Yq"$Imix)^v-n߾M.`)ZU 0`tƐVȐ6*>êy§~ +,oyB1/$~+.eK!;EiZz*"=Pd3װ ӑW$7s ^--oݦ%mSPDcw4gFDaݡ#<z UH}+ ˷S]Igd׀%/T$VTsXM8IKdr1)=ݡ^삗?rA=+..L?j-2~CVqgܔ9_Ú N?Tbt-ZfၘX'5GgqsC``a2τ3ڱL;ԸWJRv8i vD2^gEbC]B܎ŋ2pP;|QJDh|t㻐AKRj$G܁+8Ǥғp%/-o߳"F?P kX_#H)f*(I] lDb]Q.q]pHƈgP\HEc;yEwa{N[M D0&5춾{,8ow֭[#55!!!;`5jM69/Z^ީmO(-ԐojtaqGYIS7 TosK^ҹ7#/WHfɿ-rL}Mw#e˚#* w_,'M% &oz\:чRPP$}FnJu Sw'RcKXw6-lҀ$>$>*֙>ԙy ReeʔA-[V]Vcȿ%z}uxZ;vZ(*{j_ue~?iRY:ɑOǒ1uPε]G1Û`p$ e(qJܦnˠBx+`[rmԻ5&\ًr,zP0-:G3I+3e8LAR߄K默٢# CsHU2Vu/)/Ճv$5`Ŗ])k,`XL05k֔42\/w j7koS<0Ue`۸Ik>P5Кi.C[ #~ۊaWe] ħ}PX?lJ⍆{YiH(WS_Q=>cK]tbqsKM`Q5)$E3Zwg7R uKҟ[XIHCԭ˒P" n%l|w5Y; At>|;#n2b"LiT7Q8?ZC[Ll$n6uLIeJ&|@49e.}w=۠E%)֙v]:6*)hqDEk pO`c ZTM.^mv͚53J)N3 G;s дiSjS;pXNXa`Wqdݚ3-c&wn<9`dSnmb}d?L_؎#1.@QB/S0 E܉C]60b%,{Ńy,"3Ps_sG̺#Zؤ`))Rޘp44i^|P9g@8)p}z:vШKb8_70]{Cםa^U:s2iOۡcWf߻,33e:F['ZƱH9m+HCAEg'Ha0[T/7IcWC3Wy0v9ƽ3A= }-~c ik\\ z _hB {aAY<6}}`"@uiru| } j;x+ !{5fy7:tɈƖ?az/\Fl-oZơ*#w̛%ѤaY}L|ozͲM<NJנ$MIu?A^ Bcg -!7; Į6ո$ց_)F&OA=::J\2B'Uz,BDT7*5k: E*= ;U_ak#rhrM=_`֢\{7, + 1 mȧX x8N6X6&k|&9kUʳeHSf̮lmGrPHXWa=ahNj^˴]0;~הsU\/k,u$\\SNa [$=˽ u.a)]0=!vC}9m;/|)0S} 9Ǥ_89mmE,ko}![٫}_$տ Z`ܪg0MTmj3S8Bu{dW-n@>.FAIhuD=2Qu;艭s#- ׬ziy;>P2E]t 7, =9dRo5uD8!kRS9 mÿ!ٷJ^p.0f7|~p)ZgxIxqh}TۤSmϦ`RLlW~ƃt7`IԤlN4LGԤH 6e*YԨ*hG* tC{?oZ po'w0n)&{)/zpTЍ훾Dr(m kDI<7@]ʬ&M)qf*d?C/!,]Acc?mXj*PGwN8p'81m;>{Q_F6^X _.:-M4{~cX t&_ސ2v#ЯK!峼O! =nPN'ۓ:^VO6Nv"oZ(׎Gu($S໹h%~vXxv.ŶUI+7Y*D{73oc5 4[nfDAiX|4ӥO]2u{2 c9C9:⮑6{Aި7i/֭_Y19~RL9)Dٙ}C?!` s%I/K'H6u%/Ïꕥx;#f?V[ib\g{r׎W!ǎby`ݿ*ZF‘ǡ0OcݰKTp$;OL{I2BA+F~%Pӯʢ)L[ o_O{ƶuHȂ9cz{:T..PP#9yzt.H#,sSf:P=KNsTy~J98&LEPxK7V%熣ү$m@?ukCf:)l}VP,G\Up}RT^.씿U , %iK3yg0,-54ʅRj^?hw-B5kCߏ%%swN GAq;!Y*T~"S `JqjU<ۅ>EI 8!E. NX{EopYşЬ[?Bg>Ma֨F}ԭU1XKQ%-su Qǃ>gF~򀬳KVC%?ܧ>?~*cDK1A 0 &H[6%Fk6ܮo3O~U'sF2Iٖ"(}7eX5ߡ1D$ޯ^C؎Cޫܠse (E} pG9ʌ AKt/ TZfxiY:{!7S(zR4S>f HURW{ξrT157( !hTi Wja/"k%yyGgr"5r6 YS:5Olܝpby~FC G)OoA(:5NAH=9o= 5MEIYIE5IAI< 'wb=,:QӛOQJNSt#&9+ƻAC3> n~G^AQZxTw5c1ki-6|&EOAѓcϿ,ZN+թ(؍x4LzL~ILJV4ׁ; "6w6e{˹=F5 qKĢE2IcgbWL}ZC=0.gD~6 "qQE)b/y:#=& k(]TQ>6oSIYEUT,Z<^H9GcXMҳ4}':<vNyѿptKe6mUS$w&gK)#xY'S`#בaR2'MG{Cf/P4 E UiÓ"A$zd%]w7%գX,H3mKQzjcpG(2DzQ&ZPT򶭸&J$*ywvP$؉Xի bE;H֖b[_דqu7yd|"Ri'BӶ/xJPN- Hـ3Á;_2ǖbkv1\!]g[#1mL)_T#h<ǟ!~/hj;KN$'6`[c |u̠rrze](ZMİ?cSٴg2t# 'Fa'b}9*;aft4/#)66ۗ`wiWWA_ 2O;nCb=Rb~:=e.o'[C=:,*=).ZŴOzSg4AI!e]tWSF299hDz:ў4iX1AIר0*\O:{H5wK&.'`Z$) JxR4ƝC#VrT'`D27CS]ycd Q-!#(9]/LB>&-,en$E1pO]ޭ>%~ >>Kf< +hHlA2͉e^t)!a8^-lFQP 솀v^t,*;;[/<i,wܿp>y"Ry  g"!= 'G@v'|@!#FGs)ܷ;oCnfBqUq3.gק4i*]?bgR/=CQ: @{fZ]#bC<}vJ.8~ Lo t.oh7E$JU:sM5c'AO8{ރHmm*4wo،C"JbEV}y&°1)yZ!mckV pl9$*,Fap) C|3A:wĴm\+?aߑGLn~4EjYqML*7Ycg_^ƍP̝A/GPcZ x8N6ElL]寡m҇8j~x*QaBOzz0࿣5u(aJ;K{@itJ#=yy+R2+?AOcU'^q4pۗè<[l:"2}Ӥ~]6kqv"7})Y;(v'!QyP~P x~jQO׻n{vDN@.r ֹT*7#7/OM J>Ժ+Wpi kWؓE!SJ@%R (?VF?ѕURyX1}%;)Տв~x>m cxpq ]݈Co;6J`0~zM\oO1㛔SW#V4ʷ,EDHO{i3fi|t%_Mڋub|tLQE$sHVv,Eq=Q~;st—T&eilӼJ54i?;Cڰf8~͡:eKj} ؋#hXEX[EY?|(>?,2 ܠuˤHe1>R^FGW2KAls-s#F<ҋ`/ߐkH~pGLjKAT/}3bS;,[UG)t,2cϼ)4W3~$oAQAXJAAم+wzCނ`dcw!?h+Zam"vT|ǤnxUuա<')I*h_I+vUES]OBlɜxyb/'JeP[Yu+$ϑ1(EM5^;/>ES3 '.;%I{˒SR_8b1Vt&؋*M z$F|Ldl$,\ ,7<Jk1{6tD'PJuҳRF( ``n!AMcM E*B^l|4 k1%\nP(>". ?~=HqOߜnNl?0QAE~E8[W׬TtQF(E濂IߝP(oKZ'u Z" e #̤HGOYڳ/aH:>3w[pՉ,.иOW]V7IcWRaO\(D뤼#4PFLz6F$٢f)\ҮcńXx,Ξ3p]vDQRWǐcq,EP̭%F^/<6XGR h@Ej9VdOxGgr:r6 YSzH pp ^_Ԋjrt )T+8pu8YFQNfC16mRr .1 m57IcTs!Ă(ϸJaJP4;8itkbȺ;z Ԓݿq"(IbZ1q^뇏V&ұׯF-.lgF}z I;(8Xj; \M;;v^l/StLJV4uJ4&؂شBڽVҐ|jykJRoZxY%B:WSA{^ߎww>B4vS4Ëఎ*蜛#aqM{By]]OŢţQʨIJ+GMp*6 EIjua*V S1^ ^7Kъb o0 /Nڃē}.)vA9rZD@GUֿ֢N'r\0{-:@@i:uO&t\8ܣ`x=B\Rt8rV闹tw||C?F]՟"-jlM#@s|g[ K.k^=+3{VnL<` 3%ӵ$ds$)MwLڡt  =NogOW@Ug<W2J) ~BsΔ<`|ty􃀭mEVY:44*4Lhj\s"MVW,Šm'?@,9H3ŐBXw 0Luх *ʮx)..Ga {I|OSrM߱o`tvvټ=Z2_>g-oQz%횦tj<]0r2'JR8>.~&ŰsўB6{A+Vjt;,boN4_҄DB湰tϋws^*6T|0* ?h9OG#ORL.6prPXO#|P"ݲ[O(& [EMLݰ@TNJT/VgД}>?W"(J>B9%)="(*\A߳#h %M{=V xO…aP+pyV\LGJIL(M/?wq'd+~Nfr]-&_דqu7ck!'vEҲOm_Fh)T-us?Ibc@?TleFtBE4X~Wv"VkzWs3 S^3ZfVr|?tߵl,Avgk*MH.W1(Zi)9=+Q^%ɵ'iXȊ _`=H]oU'Fa'x6i\n4Er8|J|)SklRۗ`wi䫫Π~/c6-)%FCQbY"3ti͈.%XX!2R3:J$O$./`C`9H0 w̠T1$eT1l;VyX,ܛyG1/|qs\ҳ&0z#l;w%!%Rl튥L@@ ȚAU@ⶆW'l*;;[dJ'Q(sDPV^UTyRXMj_1[rL-"Xr̖lK_׿I-9E[@@ ``U@@ `7`c@@ `L^\܏-L7F_UD@@ `2&k췶qXԤOEB.O~&BT!`ƮJ_ֆo74AȯE-6jѐ@@ 䉀I{ֵ3Psi d{_(D" #!`Ʈb`ǚ#\oT7+Jݑ*"81& v Cfph ]?JaNvEG91t@@ `_L2PhCJqx{YQ}G/z0ITC⏭瑘/& D}}!6F$SDsL h@tp86fN 䍀I&~0ij5Q$@@ pL쬜k\\N6Y& "" 9& 9b@)), Eff&Op6kDPq~J;ƂV@@ `5k5N[2mvOߜnJ B9dtD)1;-/L1)Šn>v@@ pH`wHA dQnn㏈Fō˓ⴕm\ƕ6q# Dv@8{|n!/-?P=W\\9"6K$>'; @@ `U1,YFBr,r%.ȕh: {>@I ,Y>2Yf#e]`Hsa`'DvB@Ӭl+pAY38OΧC@M_; {YK6v6 vXg.kA/!@@ ZxDee΂H@CY3獅;iy{Dc|*gr|̅5u! βZs9,y/elW:#&@@ ٪" x>sF_XǼg E! wI0=H: i3GIENDB`././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/table.py0000644000000000000000000000167300000000000012505 0ustar00from openpyxl import Workbook from openpyxl.worksheet.table import Table, TableStyleInfo wb = Workbook() ws = wb.active data = [ ['Apples', 10000, 5000, 8000, 6000], ['Pears', 2000, 3000, 4000, 5000], ['Bananas', 6000, 6000, 6500, 6000], ['Oranges', 500, 300, 200, 700], ] # add column headings. NB. these must be strings ws.append(["Fruit", "2011", "2012", "2013", "2014"]) for row in data: ws.append(row) tab = Table(displayName="Table1", ref="A1:E5") # Add a default style with striped rows and banded columns style = TableStyleInfo(name="TableStyleMedium9", showFirstColumn=False, showLastColumn=False, showRowStripes=True, showColumnStripes=True) tab.tableStyleInfo = style ''' Table must be added using ws.add_table() method to avoid duplicate names. Using this method ensures table name is unque through out defined names and all other table name. ''' ws.add_table(tab) wb.save("table.xlsx") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/tutorial.rst0000644000000000000000000002173000000000000013435 0ustar00Tutorial ======== Create a workbook ----------------- There is no need to create a file on the filesystem to get started with openpyxl. Just import the :class:`Workbook` class and start work:: >>> from openpyxl import Workbook >>> wb = Workbook() A workbook is always created with at least one worksheet. You can get it by using the :obj:`Workbook.active` property:: >>> ws = wb.active .. note:: This is set to 0 by default. Unless you modify its value, you will always get the first worksheet by using this method. You can create new worksheets using the :meth:`Workbook.create_sheet` method:: >>> ws1 = wb.create_sheet("Mysheet") # insert at the end (default) # or >>> ws2 = wb.create_sheet("Mysheet", 0) # insert at first position # or >>> ws3 = wb.create_sheet("Mysheet", -1) # insert at the penultimate position Sheets are given a name automatically when they are created. They are numbered in sequence (Sheet, Sheet1, Sheet2, ...). You can change this name at any time with the :obj:`Worksheet.title` property:: ws.title = "New Title" The background color of the tab holding this title is white by default. You can change this providing an :code:`RRGGBB` color code to the :obj:`Worksheet.sheet_properties.tabColor` attribute:: ws.sheet_properties.tabColor = "1072BA" Once you gave a worksheet a name, you can get it as a key of the workbook:: >>> ws3 = wb["New Title"] You can review the names of all worksheets of the workbook with the :obj:`Workbook.sheetname` attribute :: >>> print(wb.sheetnames) ['Sheet2', 'New Title', 'Sheet1'] You can loop through worksheets :: >>> for sheet in wb: ... print(sheet.title) You can create copies of worksheets **within a single workbook**: :meth:`Workbook.copy_worksheet` method:: >>> source = wb.active >>> target = wb.copy_worksheet(source) .. note:: Only cells (including values, styles, hyperlinks and comments) and certain worksheet attribues (including dimensions, format and properties) are copied. All other workbook / worksheet attributes are not copied - e.g. Images, Charts. You also **cannot** copy worksheets between workbooks. You cannot copy a worksheet if the workbook is open in `read-only` or `write-only` mode. Playing with data ------------------ Accessing one cell ++++++++++++++++++ Now we know how to get a worksheet, we can start modifying cells content. Cells can be accessed directly as keys of the worksheet:: >>> c = ws['A4'] This will return the cell at A4, or create one if it does not exist yet. Values can be directly assigned:: >>> ws['A4'] = 4 There is also the :meth:`Worksheet.cell` method. This provides access to cells using row and column notation:: >>> d = ws.cell(row=4, column=2, value=10) .. note:: When a worksheet is created in memory, it contains no `cells`. They are created when first accessed. .. warning:: Because of this feature, scrolling through cells instead of accessing them directly will create them all in memory, even if you don't assign them a value. Something like :: >>> for x in range(1,101): ... for y in range(1,101): ... ws.cell(row=x, column=y) will create 100x100 cells in memory, for nothing. Accessing many cells ++++++++++++++++++++ Ranges of cells can be accessed using slicing:: >>> cell_range = ws['A1':'C2'] Ranges of rows or columns can be obtained similarly:: >>> colC = ws['C'] >>> col_range = ws['C:D'] >>> row10 = ws[10] >>> row_range = ws[5:10] You can also use the :meth:`Worksheet.iter_rows` method:: >>> for row in ws.iter_rows(min_row=1, max_col=3, max_row=2): ... for cell in row: ... print(cell) Likewise the :meth:`Worksheet.iter_cols` method will return columns:: >>> for col in ws.iter_cols(min_row=1, max_col=3, max_row=2): ... for cell in col: ... print(cell) .. note:: For performance reasons the :obj:`Worksheet.iter_cols()` method is not available in read-only mode. If you need to iterate through all the rows or columns of a file, you can instead use the :obj:`Worksheet.rows` property:: >>> ws = wb.active >>> ws['C9'] = 'hello world' >>> tuple(ws.rows) ((, , ), (, , ), (, , ), (, , ), (, , ), (, , ), (, , ), (, , ), (, , )) or the :obj:`Worksheet.columns` property:: >>> tuple(ws.columns) ((, , , , , , ... , , ), (, , , , , , , , )) .. note:: For performance reasons the :obj:`Worksheet.columns` property is not available in read-only mode. Values only +++++++++++ If you just want the values from a worksheet you can use the :obj:`Worksheet.values` property. This iterates over all the rows in a worksheet but returns just the cell values:: for row in ws.values: for value in row: print(value) Both :meth:`Worksheet.iter_rows` and :meth:`Worksheet.iter_cols` can take the :code:`values_only` parameter to return just the cell's value:: >>> for row in ws.iter_rows(min_row=1, max_col=3, max_row=2, values_only=True): ... print(row) (None, None, None) (None, None, None) Data storage ------------ Once we have a :class:`Cell`, we can assign it a value:: >>> c.value = 'hello, world' >>> print(c.value) 'hello, world' >>> d.value = 3.14 >>> print(d.value) 3.14 Saving to a file ++++++++++++++++ The simplest and safest way to save a workbook is by using the :func:`Workbook.save` method of the :class:`Workbook` object:: >>> wb = Workbook() >>> wb.save('balances.xlsx') .. warning:: This operation will overwrite existing files without warning. .. note:: The filename extension is not forced to be xlsx or xlsm, although you might have some trouble opening it directly with another application if you don't use an official extension. As OOXML files are basically ZIP files, you can also open it with your favourite ZIP archive manager. Saving as a stream ++++++++++++++++++ If you want to save the file to a stream, e.g. when using a web application such as Pyramid, Flask or Django then you can simply provide a :func:`NamedTemporaryFile`:: >>> from tempfile import NamedTemporaryFile >>> from openpyxl import Workbook >>> wb = Workbook() >>> with NamedTemporaryFile() as tmp: wb.save(tmp.name) tmp.seek(0) stream = tmp.read() You can specify the attribute `template=True`, to save a workbook as a template:: >>> wb = load_workbook('document.xlsx') >>> wb.template = True >>> wb.save('document_template.xltx') or set this attribute to `False` (default), to save as a document:: >>> wb = load_workbook('document_template.xltx') >>> wb.template = False >>> wb.save('document.xlsx', as_template=False) .. warning:: You should monitor the data attributes and document extensions for saving documents in the document templates and vice versa, otherwise the result table engine can not open the document. .. note:: The following will fail:: >>> wb = load_workbook('document.xlsx') >>> # Need to save with the extension *.xlsx >>> wb.save('new_document.xlsm') >>> # MS Excel can't open the document >>> >>> # or >>> >>> # Need specify attribute keep_vba=True >>> wb = load_workbook('document.xlsm') >>> wb.save('new_document.xlsm') >>> # MS Excel will not open the document >>> >>> # or >>> >>> wb = load_workbook('document.xltm', keep_vba=True) >>> # If we need a template document, then we must specify extension as *.xltm. >>> wb.save('new_document.xlsm') >>> # MS Excel will not open the document Loading from a file ------------------- The same way as writing, you can use the :func:`openpyxl.load_workbook` to open an existing workbook:: >>> from openpyxl import load_workbook >>> wb2 = load_workbook('test.xlsx') >>> print(wb2.sheetnames) ['Sheet2', 'New Title', 'Sheet1'] This ends the tutorial for now, you can proceed to the :doc:`usage` section ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/usage.rst0000644000000000000000000000743000000000000012677 0ustar00Simple usage ============ Write a workbook ---------------- .. :: doctest >>> from openpyxl import Workbook >>> from openpyxl.utils import get_column_letter >>> >>> wb = Workbook() >>> >>> dest_filename = 'empty_book.xlsx' >>> >>> ws1 = wb.active >>> ws1.title = "range names" >>> >>> for row in range(1, 40): ... ws1.append(range(600)) >>> >>> ws2 = wb.create_sheet(title="Pi") >>> >>> ws2['F5'] = 3.14 >>> >>> ws3 = wb.create_sheet(title="Data") >>> for row in range(10, 20): ... for col in range(27, 54): ... _ = ws3.cell(column=col, row=row, value="{0}".format(get_column_letter(col))) >>> print(ws3['AA10'].value) AA >>> wb.save(filename = dest_filename) Read an existing workbook ------------------------- .. :: doctest >>> from openpyxl import load_workbook >>> wb = load_workbook(filename = 'empty_book.xlsx') >>> sheet_ranges = wb['range names'] >>> print(sheet_ranges['D18'].value) 3 .. note :: There are several flags that can be used in load_workbook. - `data_only` controls whether cells with formulae have either the formula (default) or the value stored the last time Excel read the sheet. - `keep_vba` controls whether any Visual Basic elements are preserved or not (default). If they are preserved they are still not editable. .. warning :: openpyxl does currently not read all possible items in an Excel file so images and charts will be lost from existing files if they are opened and saved with the same name. Using number formats -------------------- .. :: doctest >>> import datetime >>> from openpyxl import Workbook >>> wb = Workbook() >>> ws = wb.active >>> # set date using a Python datetime >>> ws['A1'] = datetime.datetime(2010, 7, 21) >>> >>> ws['A1'].number_format 'yyyy-mm-dd h:mm:ss' Using formulae -------------- .. :: doctest >>> from openpyxl import Workbook >>> wb = Workbook() >>> ws = wb.active >>> # add a simple formula >>> ws["A1"] = "=SUM(1, 1)" >>> wb.save("formula.xlsx") .. warning:: NB you must use the English name for a function and function arguments *must* be separated by commas and not other punctuation such as semi-colons. openpyxl never evaluates formula but it is possible to check the name of a formula: .. :: doctest >>> from openpyxl.utils import FORMULAE >>> "HEX2DEC" in FORMULAE True If you're trying to use a formula that isn't known this could be because you're using a formula that was not included in the initial specification. Such formulae must be prefixed with `_xlfn.` to work. Merge / Unmerge cells --------------------- When you merge cells all cells but the top-left one are **removed** from the worksheet. To carry the border-information of the merged cell, the boundary cells of the merged cell are created as MergeCells which always have the value None. See :ref:`styling-merged-cells` for information on formatting merged cells. .. :: doctest >>> from openpyxl.workbook import Workbook >>> >>> wb = Workbook() >>> ws = wb.active >>> >>> ws.merge_cells('A2:D2') >>> ws.unmerge_cells('A2:D2') >>> >>> # or equivalently >>> ws.merge_cells(start_row=2, start_column=1, end_row=4, end_column=4) >>> ws.unmerge_cells(start_row=2, start_column=1, end_row=4, end_column=4) Inserting an image ------------------- .. :: doctest >>> from openpyxl import Workbook >>> from openpyxl.drawing.image import Image >>> >>> wb = Workbook() >>> ws = wb.active >>> ws['A1'] = 'You should see three logos below' >>> # create an image >>> img = Image('logo.png') >>> # add to worksheet and anchor next to cells >>> ws.add_image(img, 'A1') >>> wb.save('logo.xlsx') Fold (outline) ---------------------- .. :: doctest >>> import openpyxl >>> wb = openpyxl.Workbook() >>> ws = wb.create_sheet() >>> ws.column_dimensions.group('A','D', hidden=True) >>> ws.row_dimensions.group(1,10, hidden=True) >>> wb.save('group.xlsx') ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/validation.rst0000644000000000000000000000514500000000000013726 0ustar00Validating cells ================ Data validators can be applied to ranges of cells but are not enforced or evaluated. Ranges do not have to be contiguous: eg. "A1 B2:B5" is contains A1 and the cells B2 to B5 but not A2 or B2. Examples -------- .. :: doctest >>> from openpyxl import Workbook >>> from openpyxl.worksheet.datavalidation import DataValidation >>> >>> # Create the workbook and worksheet we'll be working with >>> wb = Workbook() >>> ws = wb.active >>> >>> # Create a data-validation object with list validation >>> dv = DataValidation(type="list", formula1='"Dog,Cat,Bat"', allow_blank=True) >>> >>> # Optionally set a custom error message >>> dv.error ='Your entry is not in the list' >>> dv.errorTitle = 'Invalid Entry' >>> >>> # Optionally set a custom prompt message >>> dv.prompt = 'Please select from the list' >>> dv.promptTitle = 'List Selection' >>> >>> # Add the data-validation object to the worksheet >>> ws.add_data_validation(dv) >>> # Create some cells, and add them to the data-validation object >>> c1 = ws["A1"] >>> c1.value = "Dog" >>> dv.add(c1) >>> c2 = ws["A2"] >>> c2.value = "An invalid value" >>> dv.add(c2) >>> >>> # Or, apply the validation to a range of cells >>> dv.add('B1:B1048576') # This is the same as for the whole of column B >>> >>> # Check with a cell is in the validator >>> "B4" in dv True .. note :: Validations without any cell ranges will be ignored when saving a workbook. Other validation examples ------------------------- Any whole number: :: dv = DataValidation(type="whole") Any whole number above 100: :: dv = DataValidation(type="whole", operator="greaterThan", formula1=100) Any decimal number: :: dv = DataValidation(type="decimal") Any decimal number between 0 and 1: :: dv = DataValidation(type="decimal", operator="between", formula1=0, formula2=1) Any date: :: dv = DataValidation(type="date") or time: :: dv = DataValidation(type="time") Any string at most 15 characters: :: dv = DataValidation(type="textLength", operator="lessThanOrEqual"), formula1=15) Cell range validation: :: from openpyxl.utils import quote_sheetname dv = DataValidation(type="list", formula1="{0}!$B$1:$B$10".format(quote_sheetname(sheetname)) ) Custom rule: :: dv = DataValidation(type="custom", formula1"=SOMEFORMULA") .. note:: See http://www.contextures.com/xlDataVal07.html for custom rules ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/worksheet_properties.rst0000644000000000000000000000340000000000000016053 0ustar00Additional Worksheet Properties =============================== These are advanced properties for particular behaviours, the most used ones are the "fitTopage" page setup property and the tabColor that define the background color of the worksheet tab. Available properties for worksheets ----------------------------------- * "enableFormatConditionsCalculation" * "filterMode" * "published" * "syncHorizontal" * "syncRef" * "syncVertical" * "transitionEvaluation" * "transitionEntry" * "tabColor" Available fields for page setup properties ------------------------------------------ "autoPageBreaks" "fitToPage" Available fields for outlines ----------------------------- * "applyStyles" * "summaryBelow" * "summaryRight" * "showOutlineSymbols" see http://msdn.microsoft.com/en-us/library/documentformat.openxml.spreadsheet.sheetproperties%28v=office.14%29.aspx_ for details. .. note:: By default, outline properties are intitialized so you can directly modify each of their 4 attributes, while page setup properties don't. If you want modify the latter, you should first initialize a :class:`openpyxl.worksheet.properties.PageSetupProperties` object with the required parameters. Once done, they can be directly modified by the routine later if needed. .. :: doctest >>> from openpyxl.workbook import Workbook >>> from openpyxl.worksheet.properties import WorksheetProperties, PageSetupProperties >>> >>> wb = Workbook() >>> ws = wb.active >>> >>> wsprops = ws.sheet_properties >>> wsprops.tabColor = "1072BA" >>> wsprops.filterMode = False >>> wsprops.pageSetUpPr = PageSetupProperties(fitToPage=True, autoPageBreaks=False) >>> wsprops.outlinePr.summaryBelow = False >>> wsprops.outlinePr.applyStyles = True >>> wsprops.pageSetUpPr.autoPageBreaks = True ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/worksheet_tables.rst0000644000000000000000000000421000000000000015131 0ustar00Worksheet Tables ================ Worksheet tables are references to groups of cells. This makes certain operations such as styling the cells in a table easier. Creating a table ---------------- .. literalinclude:: table.py Table names must be unique within a workbook. By default tables are created with a header from the first row and filters for all the columns and table headers and column headings must always contain strings. .. warning:: In write-only mode you must add column headings to tables manually and the values must always be the same as the values of the corresponding cells (ee below for an example of how to do this), otherwise Excel may consider the file invalid and remove the table. Styles are managed using the the `TableStyleInfo` object. This allows you to stripe rows or columns and apply the different colour schemes. Working with Tables ------------------- ``ws.tables`` is a dictionary-like object of all the tables in a particular worksheet:: >>> ws.tables {"Table1", } Get Table by name or range ++++++++++++++++++++++++++ .. code:: >>> ws.tables["Table1"] or >>> ws.tables["A1:D10"] Iterate through all tables in a worksheet +++++++++++++++++++++++++++++++++++++++++ .. code:: >>> for table in ws.tables.values(): >>> print(table) Get table name and range of all tables in a worksheet +++++++++++++++++++++++++++++++++++++++++++++++++++++ Returns a list of table name and their ranges. .. code:: >>> ws.tables.items() >>> [("Table1", "A1:D10")] Delete a table ++++++++++++++ .. code:: >>> del ws.tables["Table1"] The number of tables in a worksheet +++++++++++++++++++++++++++++++++++ .. code:: >>> len(ws.tables) >>> 1 Manually adding column headings ------------------------------- In write-only mode you can either only add tables without headings:: >>> table.headerRowCount = False Or initialise the column headings manually:: >>> headings = ["Fruit", "2011", "2012", "2013", "2014"] # all values must be strings >>> table._initialise_columns() >>> for column, value in zip(table.tableColumns, headings): column.name = value././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/doc/write_performance.txt0000644000000000000000000000155500000000000015317 0ustar00Versions: python: 3.6.9 openpyxl: 3.0.1 xlsxwriter: 1.2.5 Dimensions: Rows = 1000 Cols = 50 Sheets = 1 Proportion text = 0.10 Times: xlsxwriter : 0.59 xlsxwriter (optimised): 0.54 openpyxl : 0.73 openpyxl (optimised) : 0.61 Versions: python: 3.7.5 openpyxl: 3.0.1 xlsxwriter: 1.2.5 Dimensions: Rows = 1000 Cols = 50 Sheets = 1 Proportion text = 0.10 Times: xlsxwriter : 0.65 xlsxwriter (optimised): 0.53 openpyxl : 0.70 openpyxl (optimised) : 0.63 Versions: python: 3.8.0 openpyxl: 3.0.1 xlsxwriter: 1.2.5 Dimensions: Rows = 1000 Cols = 50 Sheets = 1 Proportion text = 0.10 Times: xlsxwriter : 0.54 xlsxwriter (optimised): 0.50 openpyxl : 1.10 openpyxl (optimised) : 0.57 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/__init__.py0000644000000000000000000000111500000000000014255 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.compat.numbers import NUMPY from openpyxl.xml import DEFUSEDXML, LXML from openpyxl.workbook import Workbook from openpyxl.reader.excel import load_workbook as open from openpyxl.reader.excel import load_workbook import openpyxl._constants as constants # Expose constants especially the version number __author__ = constants.__author__ __author_email__ = constants.__author_email__ __license__ = constants.__license__ __maintainer_email__ = constants.__maintainer_email__ __url__ = constants.__url__ __version__ = constants.__version__ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/_constants.py0000644000000000000000000000046200000000000014675 0ustar00# Copyright (c) 2010-2021 openpyxl """ Package metadata """ __author__ = "See AUTHORS" __author_email__ = "charlie.clark@clark-consulting.eu" __license__ = "MIT" __maintainer_email__ = "openpyxl-users@googlegroups.com" __url__ = "https://openpyxl.readthedocs.io" __version__ = "3.0.9" __python__ = "3.6" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/cell/__init__.py0000644000000000000000000000017200000000000015176 0ustar00# Copyright (c) 2010-2021 openpyxl from .cell import Cell, WriteOnlyCell, MergedCell from .read_only import ReadOnlyCell ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/cell/_writer.py0000644000000000000000000000616200000000000015117 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.compat import safe_string from openpyxl.xml.functions import Element, SubElement, whitespace, XML_NS, REL_NS from openpyxl import LXML from openpyxl.utils.datetime import to_excel, to_ISO8601 from datetime import timedelta def _set_attributes(cell, styled=None): """ Set coordinate and datatype """ coordinate = cell.coordinate attrs = {'r': coordinate} if styled: attrs['s'] = f"{cell.style_id}" if cell.data_type == "s": attrs['t'] = "inlineStr" elif cell.data_type != 'f': attrs['t'] = cell.data_type value = cell._value if cell.data_type == "d": if hasattr(value, "tzinfo") and value.tzinfo is not None: raise TypeError("Excel does not support timezones in datetimes. " "The tzinfo in the datetime/time object must be set to None.") if cell.parent.parent.iso_dates and not isinstance(value, timedelta): value = to_ISO8601(value) else: attrs['t'] = "n" value = to_excel(value, cell.parent.parent.epoch) if cell.hyperlink: cell.parent._hyperlinks.append(cell.hyperlink) return value, attrs def etree_write_cell(xf, worksheet, cell, styled=None): value, attributes = _set_attributes(cell, styled) el = Element("c", attributes) if value is None or value == "": xf.write(el) return if cell.data_type == 'f': shared_formula = worksheet.formula_attributes.get(cell.coordinate, {}) formula = SubElement(el, 'f', shared_formula) if value is not None: formula.text = value[1:] value = None if cell.data_type == 's': inline_string = SubElement(el, 'is') text = SubElement(inline_string, 't') text.text = value whitespace(text) else: cell_content = SubElement(el, 'v') if value is not None: cell_content.text = safe_string(value) xf.write(el) def lxml_write_cell(xf, worksheet, cell, styled=False): value, attributes = _set_attributes(cell, styled) if value == '' or value is None: with xf.element("c", attributes): return with xf.element('c', attributes): if cell.data_type == 'f': shared_formula = worksheet.formula_attributes.get(cell.coordinate, {}) with xf.element('f', shared_formula): if value is not None: xf.write(value[1:]) value = None if cell.data_type == 's': with xf.element("is"): attrs = {} if value != value.strip(): attrs["{%s}space" % XML_NS] = "preserve" el = Element("t", attrs) # lxml can't handle xml-ns el.text = value xf.write(el) #with xf.element("t", attrs): #xf.write(value) else: with xf.element("v"): if value is not None: xf.write(safe_string(value)) if LXML: write_cell = lxml_write_cell else: write_cell = etree_write_cell ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/cell/cell.py0000644000000000000000000002073600000000000014366 0ustar00# Copyright (c) 2010-2021 openpyxl """Manage individual cells in a spreadsheet. The Cell class is required to know its value and type, display options, and any other features of an Excel cell. Utilities for referencing cells using Excel's 'A1' column/row nomenclature are also provided. """ __docformat__ = "restructuredtext en" # Python stdlib imports from copy import copy import datetime import re from openpyxl.compat import ( NUMERIC_TYPES, deprecated, ) from openpyxl.utils.exceptions import IllegalCharacterError from openpyxl.utils import get_column_letter from openpyxl.styles import numbers, is_date_format from openpyxl.styles.styleable import StyleableObject from openpyxl.worksheet.hyperlink import Hyperlink # constants TIME_TYPES = (datetime.datetime, datetime.date, datetime.time, datetime.timedelta) TIME_FORMATS = { datetime.datetime:numbers.FORMAT_DATE_DATETIME, datetime.date:numbers.FORMAT_DATE_YYYYMMDD2, datetime.time:numbers.FORMAT_DATE_TIME6, datetime.timedelta:numbers.FORMAT_DATE_TIMEDELTA, } STRING_TYPES = (str, bytes) KNOWN_TYPES = NUMERIC_TYPES + TIME_TYPES + STRING_TYPES + (bool, type(None)) ILLEGAL_CHARACTERS_RE = re.compile(r'[\000-\010]|[\013-\014]|[\016-\037]') ERROR_CODES = ('#NULL!', '#DIV/0!', '#VALUE!', '#REF!', '#NAME?', '#NUM!', '#N/A') TYPE_STRING = 's' TYPE_FORMULA = 'f' TYPE_NUMERIC = 'n' TYPE_BOOL = 'b' TYPE_NULL = 'n' TYPE_INLINE = 'inlineStr' TYPE_ERROR = 'e' TYPE_FORMULA_CACHE_STRING = 'str' VALID_TYPES = (TYPE_STRING, TYPE_FORMULA, TYPE_NUMERIC, TYPE_BOOL, TYPE_NULL, TYPE_INLINE, TYPE_ERROR, TYPE_FORMULA_CACHE_STRING) _TYPES = {int:'n', float:'n', str:'s', bool:'b'} def get_type(t, value): if isinstance(value, NUMERIC_TYPES): dt = 'n' elif isinstance(value, STRING_TYPES): dt = 's' elif isinstance(value, TIME_TYPES): dt = 'd' else: return _TYPES[t] = dt return dt def get_time_format(t): value = TIME_FORMATS.get(t) if value: return value for base in t.mro()[1:]: value = TIME_FORMATS.get(base) if value: TIME_FORMATS[t] = value return value raise ValueError("Could not get time format for {0!r}".format(value)) class Cell(StyleableObject): """Describes cell associated properties. Properties of interest include style, type, value, and address. """ __slots__ = ( 'row', 'column', '_value', 'data_type', 'parent', '_hyperlink', '_comment', ) def __init__(self, worksheet, row=None, column=None, value=None, style_array=None): super(Cell, self).__init__(worksheet, style_array) self.row = row """Row number of this cell (1-based)""" self.column = column """Column number of this cell (1-based)""" # _value is the stored value, while value is the displayed value self._value = None self._hyperlink = None self.data_type = 'n' if value is not None: self.value = value self._comment = None @property def coordinate(self): """This cell's coordinate (ex. 'A5')""" col = get_column_letter(self.column) return f"{col}{self.row}" @property def col_idx(self): """The numerical index of the column""" return self.column @property def column_letter(self): return get_column_letter(self.column) @property def encoding(self): return self.parent.encoding @property def base_date(self): return self.parent.parent.epoch def __repr__(self): return "".format(self.parent.title, self.coordinate) def check_string(self, value): """Check string coding, length, and line break character""" if value is None: return # convert to str string if not isinstance(value, str): value = str(value, self.encoding) value = str(value) # string must never be longer than 32,767 characters # truncate if necessary value = value[:32767] if next(ILLEGAL_CHARACTERS_RE.finditer(value), None): raise IllegalCharacterError return value def check_error(self, value): """Tries to convert Error" else N/A""" try: return str(value) except UnicodeDecodeError: return u'#N/A' def _bind_value(self, value): """Given a value, infer the correct data type""" self.data_type = "n" t = type(value) try: dt = _TYPES[t] except KeyError: dt = get_type(t, value) if dt is None and value is not None: raise ValueError("Cannot convert {0!r} to Excel".format(value)) if dt: self.data_type = dt if dt == 'd': if not is_date_format(self.number_format): self.number_format = get_time_format(t) elif dt == "s": value = self.check_string(value) if len(value) > 1 and value.startswith("="): self.data_type = 'f' elif value in ERROR_CODES: self.data_type = 'e' self._value = value @property def value(self): """Get or set the value held in the cell. :type: depends on the value (string, float, int or :class:`datetime.datetime`) """ return self._value @value.setter def value(self, value): """Set the value and infer type and display options.""" self._bind_value(value) @property def internal_value(self): """Always returns the value for excel.""" return self._value @property def hyperlink(self): """Return the hyperlink target or an empty string""" return self._hyperlink @hyperlink.setter def hyperlink(self, val): """Set value and display for hyperlinks in a cell. Automatically sets the `value` of the cell with link text, but you can modify it afterwards by setting the `value` property, and the hyperlink will remain. Hyperlink is removed if set to ``None``.""" if val is None: self._hyperlink = None else: if not isinstance(val, Hyperlink): val = Hyperlink(ref="", target=val) val.ref = self.coordinate self._hyperlink = val if self._value is None: self.value = val.target or val.location @property def is_date(self): """True if the value is formatted as a date :type: bool """ return self.data_type == 'd' or ( self.data_type == 'n' and is_date_format(self.number_format) ) def offset(self, row=0, column=0): """Returns a cell location relative to this cell. :param row: number of rows to offset :type row: int :param column: number of columns to offset :type column: int :rtype: :class:`openpyxl.cell.Cell` """ offset_column = self.col_idx + column offset_row = self.row + row return self.parent.cell(column=offset_column, row=offset_row) @property def comment(self): """ Returns the comment associated with this cell :type: :class:`openpyxl.comments.Comment` """ return self._comment @comment.setter def comment(self, value): """ Assign a comment to a cell """ if value is not None: if value.parent: value = copy(value) value.bind(self) elif value is None and self._comment: self._comment.unbind() self._comment = value class MergedCell(StyleableObject): """ Describes the properties of a cell in a merged cell and helps to display the borders of the merged cell. The value of a MergedCell is always None. """ __slots__ = ('row', 'column') _value = None data_type = "n" comment = None hyperlink = None def __init__(self, worksheet, row=None, column=None): super(MergedCell, self).__init__(worksheet) self.row = row self.column = column def __repr__(self): return "".format(self.parent.title, self.coordinate) coordinate = Cell.coordinate _comment = comment value = _value def WriteOnlyCell(ws=None, value=None): return Cell(worksheet=ws, column=1, row=1, value=value) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/cell/read_only.py0000644000000000000000000000605100000000000015415 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.cell import Cell from openpyxl.utils import get_column_letter from openpyxl.utils.datetime import from_excel from openpyxl.styles import is_date_format from openpyxl.styles.numbers import BUILTIN_FORMATS, BUILTIN_FORMATS_MAX_SIZE class ReadOnlyCell(object): __slots__ = ('parent', 'row', 'column', '_value', 'data_type', '_style_id') def __init__(self, sheet, row, column, value, data_type='n', style_id=0): self.parent = sheet self._value = None self.row = row self.column = column self.data_type = data_type self.value = value self._style_id = style_id def __eq__(self, other): for a in self.__slots__: if getattr(self, a) != getattr(other, a): return return True def __ne__(self, other): return not self.__eq__(other) def __repr__(self): return "".format(self.parent.title, self.coordinate) @property def coordinate(self): column = get_column_letter(self.column) return "{1}{0}".format(self.row, column) @property def coordinate(self): return Cell.coordinate.__get__(self) @property def column_letter(self): return Cell.column_letter.__get__(self) @property def style_array(self): return self.parent.parent._cell_styles[self._style_id] @property def has_style(self): return self._style_id != 0 @property def number_format(self): _id = self.style_array.numFmtId if _id < BUILTIN_FORMATS_MAX_SIZE: return BUILTIN_FORMATS.get(_id, "General") else: return self.parent.parent._number_formats[ _id - BUILTIN_FORMATS_MAX_SIZE] @property def font(self): _id = self.style_array.fontId return self.parent.parent._fonts[_id] @property def fill(self): _id = self.style_array.fillId return self.parent.parent._fills[_id] @property def border(self): _id = self.style_array.borderId return self.parent.parent._borders[_id] @property def alignment(self): _id = self.style_array.alignmentId return self.parent.parent._alignments[_id] @property def protection(self): _id = self.style_array.protectionId return self.parent.parent._protections[_id] @property def is_date(self): return Cell.is_date.__get__(self) @property def internal_value(self): return self._value @property def value(self): return self._value @value.setter def value(self, value): if self._value is not None: raise AttributeError("Cell is read only") self._value = value class EmptyCell(object): __slots__ = () value = None is_date = False font = None border = None fill = None number_format = None alignment = None data_type = 'n' def __repr__(self): return "" EMPTY_CELL = EmptyCell() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/cell/tests/__init__.py0000644000000000000000000000000000000000000016326 0ustar00././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/cell/tests/test_cell.py0000644000000000000000000002470400000000000016566 0ustar00# Copyright (c) 2010-2021 openpyxl # Python stdlib imports from datetime import ( time, datetime, date, timedelta, ) # 3rd party imports import pytest # package imports from openpyxl.comments import Comment from openpyxl.cell.cell import ERROR_CODES, get_time_format @pytest.fixture def DummyWorksheet(): from openpyxl.utils.indexed_list import IndexedList from openpyxl.utils.datetime import CALENDAR_WINDOWS_1900 from openpyxl.cell import Cell class Wb(object): epoch = CALENDAR_WINDOWS_1900 _fonts = IndexedList() _fills = IndexedList() _borders = IndexedList() _protections = IndexedList() _alignments = IndexedList() _number_formats = IndexedList() _cell_styles = IndexedList() class Ws(object): encoding = 'utf-8' parent = Wb() title = "Dummy Worksheet" _comment_count = 0 def cell(self, column, row): return Cell(self, row=row, column=column) return Ws() @pytest.fixture def Cell(): from ..cell import Cell return Cell @pytest.fixture def dummy_cell(DummyWorksheet, Cell): ws = DummyWorksheet cell = Cell(ws, column=1, row=1) return cell def test_ctor(dummy_cell): cell = dummy_cell assert cell.data_type == 'n' assert cell.column == 1 assert cell.row == 1 assert cell.coordinate == "A1" assert cell.value is None assert cell.comment is None @pytest.mark.parametrize("datatype", ['n', 'd', 's', 'b', 'f', 'e']) def test_null(dummy_cell, datatype): cell = dummy_cell cell.data_type = datatype assert cell.data_type == datatype cell.value = None assert cell.data_type == 'n' @pytest.mark.parametrize("value", ['hello', ".", '0800']) def test_string(dummy_cell, value): cell = dummy_cell cell.value = 'hello' assert cell.data_type == 's' @pytest.mark.parametrize("value", ['=42', '=if(A1<4;-1;1)']) def test_formula(dummy_cell, value): cell = dummy_cell cell.value = value assert cell.data_type == 'f' def test_not_formula(dummy_cell): dummy_cell.value = "=" assert dummy_cell.data_type == 's' assert dummy_cell.value == "=" @pytest.mark.parametrize("value", [True, False]) def test_boolean(dummy_cell, value): cell = dummy_cell cell.value = value assert cell.data_type == 'b' @pytest.mark.parametrize("error_string", ERROR_CODES) def test_error_codes(dummy_cell, error_string): cell = dummy_cell cell.value = error_string assert cell.data_type == 'e' @pytest.mark.parametrize("value, number_format", [ ( datetime(2010, 7, 13, 6, 37, 41), "yyyy-mm-dd h:mm:ss" ), ( date(2010, 7, 13), "yyyy-mm-dd" ), ( time(1, 3), "h:mm:ss", ) ] ) def test_insert_date(dummy_cell, value, number_format): cell = dummy_cell cell.value = value assert cell.data_type == 'd' assert cell.is_date assert cell.number_format == number_format @pytest.mark.pandas_required def test_timstamp(dummy_cell): from pandas import Timestamp cell = dummy_cell cell.value = Timestamp("2018-09-05") assert cell.number_format == "yyyy-mm-dd h:mm:ss" def test_time_format_datetime_subclass(): class TestDatetime(datetime): pass number_format = get_time_format(TestDatetime) assert number_format == "yyyy-mm-dd h:mm:ss" def test_time_format_date_subclass(): class TestDate(date): pass number_format = get_time_format(TestDate) assert number_format == "yyyy-mm-dd" def test_time_format_no_date_subclass(): with pytest.raises(ValueError): number_format = get_time_format(object) def test_not_overwrite_time_format(dummy_cell): cell = dummy_cell cell.number_format = "mmm-yy" cell.value = date(2010, 7, 13) assert cell.number_format == "mmm-yy" @pytest.mark.parametrize("value, is_date", [ (None, True,), ("testme", False), (True, False), ] ) def test_cell_formatted_as_date(dummy_cell, value, is_date): cell = dummy_cell cell.value = datetime.today() cell.value = value assert cell.is_date == is_date assert cell.value == value def test_illegal_characters(dummy_cell): from openpyxl.utils.exceptions import IllegalCharacterError from itertools import chain cell = dummy_cell # The bytes 0x00 through 0x1F inclusive must be manually escaped in values. illegal_chrs = chain(range(9), range(11, 13), range(14, 32)) for i in illegal_chrs: with pytest.raises(IllegalCharacterError): cell.value = chr(i) with pytest.raises(IllegalCharacterError): cell.value = "A {0} B".format(chr(i)) cell.value = chr(33) cell.value = chr(9) # Tab cell.value = chr(10) # Newline cell.value = chr(13) # Carriage return cell.value = " Leading and trailing spaces are legal " @pytest.mark.xfail def test_timedelta(dummy_cell): cell = dummy_cell cell.value = timedelta(days=1, hours=3) assert cell.value == 1.125 assert cell.data_type == 'n' assert cell.is_date is False assert cell.number_format == "[hh]:mm:ss" def test_repr(dummy_cell): cell = dummy_cell assert repr(cell) == "" def test_repr_object(dummy_cell): class Dummy: def __str__(self): return "something" cell = dummy_cell try: cell._bind_value(Dummy()) except ValueError as err: assert "something" not in str(err) def test_comment_assignment(dummy_cell): assert dummy_cell.comment is None comm = Comment("text", "author") dummy_cell.comment = comm assert dummy_cell.comment == comm def test_only_one_cell_per_comment(dummy_cell): ws = dummy_cell.parent comm = Comment('text', 'author') dummy_cell.comment = comm c2 = ws.cell(column=1, row=2) c2.comment = comm assert c2.comment.parent is c2 def test_remove_comment(dummy_cell): comm = Comment('text', 'author') dummy_cell.comment = comm dummy_cell.comment = None assert dummy_cell.comment is None def test_cell_offset(dummy_cell): cell = dummy_cell assert cell.offset(2, 1).coordinate == 'B3' class TestEncoding: try: # Python 2 pound = unichr(163) except NameError: # Python 3 pound = chr(163) test_string = ('Compound Value (' + pound + ')').encode('latin1') def test_bad_encoding(self): from openpyxl import Workbook wb = Workbook() ws = wb.active cell = ws['A1'] with pytest.raises(UnicodeDecodeError): cell.check_string(self.test_string) with pytest.raises(UnicodeDecodeError): cell.value = self.test_string def test_good_encoding(self): from openpyxl import Workbook wb = Workbook() wb.encoding = 'latin1' ws = wb.active cell = ws['A1'] cell.value = self.test_string def test_font(DummyWorksheet, Cell): from openpyxl.styles import Font font = Font(bold=True) ws = DummyWorksheet ws.parent._fonts.add(font) cell = Cell(ws, row=1, column=1) assert cell.font == font def test_fill(DummyWorksheet, Cell): from openpyxl.styles import PatternFill fill = PatternFill(patternType="solid", fgColor="FF0000") ws = DummyWorksheet ws.parent._fills.add(fill) cell = Cell(ws, column='A', row=1) assert cell.fill == fill def test_border(DummyWorksheet, Cell): from openpyxl.styles import Border border = Border() ws = DummyWorksheet ws.parent._borders.add(border) cell = Cell(ws, column='A', row=1) assert cell.border == border def test_number_format(DummyWorksheet, Cell): ws = DummyWorksheet ws.parent._number_formats.add("dd--hh--mm") cell = Cell(ws, column="A", row=1) cell.number_format = "dd--hh--mm" assert cell.number_format == "dd--hh--mm" def test_alignment(DummyWorksheet, Cell): from openpyxl.styles import Alignment align = Alignment(wrapText=True) ws = DummyWorksheet ws.parent._alignments.add(align) cell = Cell(ws, column="A", row=1) assert cell.alignment == align def test_protection(DummyWorksheet, Cell): from openpyxl.styles import Protection prot = Protection(locked=False) ws = DummyWorksheet ws.parent._protections.add(prot) cell = Cell(ws, column="A", row=1) assert cell.protection == prot def test_pivot_button(DummyWorksheet, Cell): ws = DummyWorksheet cell = Cell(ws, column="A", row=1) cell.style_id cell._style.pivotButton = 1 assert cell.pivotButton is True def test_quote_prefix(DummyWorksheet, Cell): ws = DummyWorksheet cell = Cell(ws, column="A", row=1) cell.style_id cell._style.quotePrefix = 1 assert cell.quotePrefix is True def test_remove_hyperlink(dummy_cell): """Remove a cell hyperlink""" cell = dummy_cell cell.hyperlink = "http://test.com" cell.hyperlink = None assert cell.hyperlink is None @pytest.fixture def MergedCell(DummyWorksheet): from ..cell import MergedCell return MergedCell(DummyWorksheet) class TestMergedCell: def test_value(self, MergedCell): cell = MergedCell assert cell._value is None def test_data_type(self, MergedCell): cell = MergedCell assert cell.data_type == 'n' def test_comment(self, MergedCell): cell = MergedCell assert cell.comment is None def test_coordinate(self, MergedCell): cell = MergedCell cell.row = 1 cell.column = 1 assert cell.coordinate == "A1" def test_repr(self, MergedCell): cell = MergedCell cell.row = 1 cell.column = 1 assert repr(cell) == "" def test_hyperlink(self, MergedCell): cell = MergedCell assert cell.hyperlink is None @pytest.mark.numpy_required def test_write_numpy_to_cell(dummy_cell): import numpy data = numpy.array([1.0]) cell = dummy_cell cell.value = data[0] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/cell/tests/test_read_only.py0000644000000000000000000000473100000000000017621 0ustar00from __future__ import absolute_import # Copyright (c) 2010-2021 openpyxl import datetime import pytest from openpyxl.cell.read_only import ReadOnlyCell from openpyxl.utils.indexed_list import IndexedList from openpyxl.styles.styleable import StyleArray @pytest.fixture(scope='module') def dummy_sheet(): class DummyWorkbook(object): shared_styles = IndexedList() style = StyleArray() shared_styles.add(style) # Workbooks always have a default style _cell_styles = IndexedList() _cell_styles.add(style) _number_formats = IndexedList() _fonts = IndexedList() _fonts.add(None) class DummySheet(object): base_date = 2415018.5 style_table = {} shared_strings = ['Hello world'] parent = DummyWorkbook() return DummySheet() def test_ctor(dummy_sheet): cell = ReadOnlyCell(dummy_sheet, None, None, '10', 'n') assert cell.value == '10' def test_empty_cell(dummy_sheet): from openpyxl.cell.read_only import EMPTY_CELL assert EMPTY_CELL.value is None assert EMPTY_CELL.data_type == 'n' def test_coordinate(dummy_sheet): cell = ReadOnlyCell(dummy_sheet, 1, 1, 10, None) assert cell.coordinate == "A1" @pytest.fixture(scope="class") def DummyCell(dummy_sheet): dummy_sheet.parent._number_formats.add('d-mmm-yy') style = StyleArray([0,0,0,164,0,0,0,0,0]) dummy_sheet.parent._cell_styles.add(style) cell = ReadOnlyCell(dummy_sheet, None, None, "23596", 'n', 1) return cell class TestStyle: def test_style_array(self, dummy_sheet): cell = ReadOnlyCell(dummy_sheet, None, None, None) assert cell.style_array == StyleArray() def test_font(self, dummy_sheet): cell = ReadOnlyCell(dummy_sheet, None, None, None) assert cell.font == None def test_has_style(self, DummyCell): cell = DummyCell assert DummyCell.has_style def test_read_only(dummy_sheet): cell = ReadOnlyCell(sheet=dummy_sheet, row=None, column=None, value=1) assert cell.value == 1 with pytest.raises(AttributeError): cell.value = 10 with pytest.raises(AttributeError): cell.style = 1 def test_equality(): c1 = ReadOnlyCell(None, None, 10, None) c2 = ReadOnlyCell(None, None, 10, None) assert c1 is not c2 assert c1 == c2 c3 = ReadOnlyCell(None, None, 5, None) assert c3 != c1 def test_is_date(): c1 = ReadOnlyCell(None, None, None, None, 'd') assert c1.is_date is True ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/cell/tests/test_text.py0000644000000000000000000001057100000000000016630 0ustar00# coding=utf8 # Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml @pytest.fixture def InlineFont(): from ..text import InlineFont return InlineFont class TestInlineFont: def test_ctor(self, InlineFont): font = InlineFont() xml = tostring(font.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, InlineFont): src = """ """ node = fromstring(src) font = InlineFont.from_tree(node) assert font == InlineFont() @pytest.fixture def RichText(): from ..text import RichText return RichText class TestRichText: def test_ctor(self, RichText): text = RichText() xml = tostring(text.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, RichText): src = """ """ node = fromstring(src) text = RichText.from_tree(node) assert text == RichText() @pytest.fixture def Text(): from ..text import Text return Text class TestText: def test_ctor(self, Text): text = Text() text.plain = "comment" xml = tostring(text.to_tree()) expected = """ comment """ diff = compare_xml(xml, expected) assert diff is None, diff @pytest.mark.parametrize("src, expected", [ ("""ID""", "ID"), (""" 11 de September de 2014 """, "11 de September de 2014" ), ] ) def test_from_xml(self, Text, src, expected): node = fromstring(src) text = Text.from_tree(node) assert text.content == expected def test_empty_element(self, Text): src = """ Replaced Data """ node = fromstring(src) text = Text.from_tree(node) assert text.content == "Replaced Data" @pytest.fixture def PhoneticText(): from ..text import PhoneticText return PhoneticText class TestPhoneticText: def test_ctor(self, PhoneticText): text = PhoneticText(sb=9, eb=10, t=u'\u3088') xml = tostring(text.to_tree()) expected = b""" """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, PhoneticText): src = b""" """ node = fromstring(src) text = PhoneticText.from_tree(node) assert text == PhoneticText(sb=9, eb=10, t=u'\u3088') @pytest.fixture def PhoneticProperties(): from ..text import PhoneticProperties return PhoneticProperties class TestPhoneticProperties: def test_ctor(self, PhoneticProperties): props = PhoneticProperties(fontId=0, type="Hiragana") xml = tostring(props.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, PhoneticProperties): src = """ """ node = fromstring(src) props = PhoneticProperties.from_tree(node) assert props == PhoneticProperties(fontId=0, type="noConversion") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/cell/tests/test_writer.py0000644000000000000000000001540000000000000017154 0ustar00# Copyright (c) 2010-2021 openpyxl import datetime import decimal from io import BytesIO import pytest from openpyxl.xml.functions import fromstring, tostring, xmlfile from openpyxl.reader.excel import load_workbook from openpyxl import Workbook from openpyxl.tests.helper import compare_xml from openpyxl.xml.constants import SHEET_MAIN_NS, REL_NS from openpyxl.utils.datetime import CALENDAR_MAC_1904, CALENDAR_WINDOWS_1900 from openpyxl import LXML @pytest.fixture def worksheet(): from openpyxl import Workbook wb = Workbook() return wb.active @pytest.fixture def etree_write_cell(): from .._writer import etree_write_cell return etree_write_cell @pytest.fixture def lxml_write_cell(): from .._writer import lxml_write_cell return lxml_write_cell @pytest.fixture(params=['etree', 'lxml']) def write_cell_implementation(request, etree_write_cell, lxml_write_cell): if request.param == "lxml" and LXML: return lxml_write_cell return etree_write_cell @pytest.mark.parametrize("value, expected", [ (9781231231230, """9781231231230"""), (decimal.Decimal('3.14'), """3.14"""), (1234567890, """1234567890"""), ("=sum(1+1)", """sum(1+1)"""), (True, """1"""), ("Hello", """Hello"""), ("", """"""), (None, """"""), ]) def test_write_cell(worksheet, write_cell_implementation, value, expected): write_cell = write_cell_implementation ws = worksheet cell = ws['A1'] cell.value = value out = BytesIO() with xmlfile(out) as xf: write_cell(xf, ws, cell, cell.has_style) xml = out.getvalue() diff = compare_xml(xml, expected) assert diff is None, diff @pytest.mark.parametrize("value, iso_dates, expected,", [ (datetime.date(2011, 12, 25), False, """40902"""), (datetime.date(2011, 12, 25), True, """2011-12-25"""), (datetime.datetime(2011, 12, 25, 14, 23, 55), False, """40902.59994212963"""), (datetime.datetime(2011, 12, 25, 14, 23, 55), True, """2011-12-25T14:23:55"""), (datetime.time(14, 15, 25), False, """0.5940393518518519"""), (datetime.time(14, 15, 25), True, """14:15:25"""), (datetime.timedelta(1, 3, 15), False, """1.000034722395833"""), (datetime.timedelta(1, 3, 15), True, """1.000034722395833"""), ] ) def test_write_date(worksheet, write_cell_implementation, value, expected, iso_dates): write_cell = write_cell_implementation ws = worksheet cell = ws['A1'] cell.value = value cell.parent.parent.iso_dates = iso_dates out = BytesIO() with xmlfile(out) as xf: write_cell(xf, ws, cell, cell.has_style) xml = out.getvalue() diff = compare_xml(xml, expected) assert diff is None, diff @pytest.mark.parametrize("value, iso_dates", [ (datetime.datetime(2021, 3, 19, 23, tzinfo=datetime.timezone.utc), True), (datetime.datetime(2021, 3, 19, 23, tzinfo=datetime.timezone.utc), False), (datetime.time(23, 58, tzinfo=datetime.timezone.utc), True), (datetime.time(23, 58, tzinfo=datetime.timezone.utc), False), ] ) def test_write_invalid_date(worksheet, write_cell_implementation, value, iso_dates): write_cell = write_cell_implementation ws = worksheet cell = ws['A1'] cell.value = value cell.parent.parent.iso_dates = iso_dates out = BytesIO() with pytest.raises(TypeError): with xmlfile(out) as xf: write_cell(xf, ws, cell, cell.has_style) @pytest.mark.parametrize("value, expected, epoch", [ (datetime.date(2011, 12, 25), """40902""", CALENDAR_WINDOWS_1900), (datetime.date(2011, 12, 25), """39440""", CALENDAR_MAC_1904), ] ) def test_write_epoch(worksheet, write_cell_implementation, value, expected, epoch): write_cell = write_cell_implementation ws = worksheet ws.parent.epoch = epoch cell = ws['A1'] cell.value = value out = BytesIO() with xmlfile(out) as xf: write_cell(xf, ws, cell, cell.has_style) xml = out.getvalue() diff = compare_xml(xml, expected) assert diff is None, diff def test_write_hyperlink(worksheet, write_cell_implementation): write_cell = write_cell_implementation ws = worksheet cell = ws['A1'] cell.value = "test" cell.hyperlink = "http://www.test.com" out = BytesIO() with xmlfile(out) as xf: write_cell(xf, ws, cell, cell.has_style) assert len(worksheet._hyperlinks) == 1 @pytest.mark.parametrize("value, result, attrs", [ ("test", "test", {'r': 'A1', 't': 'inlineStr'}), ("=SUM(A1:A2)", "=SUM(A1:A2)", {'r': 'A1'}), (datetime.date(2018, 8, 25), 43337, {'r':'A1', 't':'n'}), ] ) def test_attributes(worksheet, value, result, attrs): from .._writer import _set_attributes ws = worksheet cell = ws['A1'] cell.value = value assert(_set_attributes(cell)) == (result, attrs) def test_whitespace(worksheet, write_cell_implementation): write_cell = write_cell_implementation ws = worksheet cell = ws['A1'] cell.value = " whitespace " out = BytesIO() with xmlfile(out) as xf: write_cell(xf, ws, cell) expected = """ whitespace """ xml = out.getvalue() diff = compare_xml(xml, expected) assert diff is None, diff ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/cell/text.py0000644000000000000000000001041700000000000014426 0ustar00# Copyright (c) 2010-2021 openpyxl """ Richtext definition """ from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import ( Alias, Typed, Integer, Set, NoneSet, Bool, String, Sequence, ) from openpyxl.descriptors.nested import ( NestedBool, NestedInteger, NestedString, NestedText, ) from openpyxl.styles.fonts import Font class PhoneticProperties(Serialisable): tagname = "phoneticPr" fontId = Integer() type = NoneSet(values=(['halfwidthKatakana', 'fullwidthKatakana', 'Hiragana', 'noConversion'])) alignment = NoneSet(values=(['noControl', 'left', 'center', 'distributed'])) def __init__(self, fontId=None, type=None, alignment=None, ): self.fontId = fontId self.type = type self.alignment = alignment class PhoneticText(Serialisable): tagname = "rPh" sb = Integer() eb = Integer() t = NestedText(expected_type=str) text = Alias('t') def __init__(self, sb=None, eb=None, t=None, ): self.sb = sb self.eb = eb self.t = t class InlineFont(Font): """ Font for inline text because, yes what you need are different objects with the same elements but different constraints. """ tagname = "RPrElt" rFont = NestedString(allow_none=True) charset = Font.charset family = Font.family b =Font.b i = Font.i strike = Font.strike outline = Font.outline shadow = Font.shadow condense = Font.condense extend = Font.extend color = Font.color sz = Font.sz u = Font.u vertAlign = Font.vertAlign scheme = Font.scheme __elements__ = ('rFont', 'charset', 'family', 'b', 'i', 'strike', 'outline', 'shadow', 'condense', 'extend', 'color', 'sz', 'u', 'vertAlign', 'scheme') def __init__(self, rFont=None, charset=None, family=None, b=None, i=None, strike=None, outline=None, shadow=None, condense=None, extend=None, color=None, sz=None, u=None, vertAlign=None, scheme=None, ): self.rFont = rFont self.charset = charset self.family = family self.b = b self.i = i self.strike = strike self.outline = outline self.shadow = shadow self.condense = condense self.extend = extend self.color = color self.sz = sz self.u = u self.vertAlign = vertAlign self.scheme = scheme class RichText(Serialisable): tagname = "RElt" rPr = Typed(expected_type=InlineFont, allow_none=True) font = Alias("rPr") t = NestedText(expected_type=str, allow_none=True) text = Alias("t") __elements__ = ('rPr', 't') def __init__(self, rPr=None, t=None, ): self.rPr = rPr self.t = t class Text(Serialisable): tagname = "text" t = NestedText(allow_none=True, expected_type=str) plain = Alias("t") r = Sequence(expected_type=RichText, allow_none=True) formatted = Alias("r") rPh = Sequence(expected_type=PhoneticText, allow_none=True) phonetic = Alias("rPh") phoneticPr = Typed(expected_type=PhoneticProperties, allow_none=True) PhoneticProperties = Alias("phoneticPr") __elements__ = ('t', 'r', 'rPh', 'phoneticPr') def __init__(self, t=None, r=(), rPh=(), phoneticPr=None, ): self.t = t self.r = r self.rPh = rPh self.phoneticPr = phoneticPr @property def content(self): """ Text stripped of all formatting """ snippets = [] if self.plain is not None: snippets.append(self.plain) for block in self.formatted: if block.t is not None: snippets.append(block.t) return u"".join(snippets) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/_3d.py0000644000000000000000000000604000000000000014266 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors import Typed, Alias from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors.nested import ( NestedBool, NestedInteger, NestedMinMax, ) from openpyxl.descriptors.excel import ExtensionList from .marker import PictureOptions from .shapes import GraphicalProperties class View3D(Serialisable): tagname = "view3D" rotX = NestedMinMax(min=-90, max=90, allow_none=True) x_rotation = Alias('rotX') hPercent = NestedMinMax(min=5, max=500, allow_none=True) height_percent = Alias('hPercent') rotY = NestedInteger(min=-90, max=90, allow_none=True) y_rotation = Alias('rotY') depthPercent = NestedInteger(allow_none=True) rAngAx = NestedBool(allow_none=True) right_angle_axes = Alias('rAngAx') perspective = NestedInteger(allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('rotX', 'hPercent', 'rotY', 'depthPercent', 'rAngAx', 'perspective',) def __init__(self, rotX=15, hPercent=None, rotY=20, depthPercent=None, rAngAx=True, perspective=None, extLst=None, ): self.rotX = rotX self.hPercent = hPercent self.rotY = rotY self.depthPercent = depthPercent self.rAngAx = rAngAx self.perspective = perspective class Surface(Serialisable): tagname = "surface" thickness = NestedInteger(allow_none=True) spPr = Typed(expected_type=GraphicalProperties, allow_none=True) graphicalProperties = Alias('spPr') pictureOptions = Typed(expected_type=PictureOptions, allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('thickness', 'spPr', 'pictureOptions',) def __init__(self, thickness=None, spPr=None, pictureOptions=None, extLst=None, ): self.thickness = thickness self.spPr = spPr self.pictureOptions = pictureOptions class _3DBase(Serialisable): """ Base class for 3D charts """ tagname = "ChartBase" view3D = Typed(expected_type=View3D, allow_none=True) floor = Typed(expected_type=Surface, allow_none=True) sideWall = Typed(expected_type=Surface, allow_none=True) backWall = Typed(expected_type=Surface, allow_none=True) def __init__(self, view3D=None, floor=None, sideWall=None, backWall=None, ): if view3D is None: view3D = View3D() self.view3D = view3D if floor is None: floor = Surface() self.floor = floor if sideWall is None: sideWall = Surface() self.sideWall = sideWall if backWall is None: backWall = Surface() self.backWall = backWall super(_3DBase, self).__init__() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/__init__.py0000644000000000000000000000106400000000000015361 0ustar00# Copyright (c) 2010-2021 openpyxl from .area_chart import AreaChart, AreaChart3D from .bar_chart import BarChart, BarChart3D from .bubble_chart import BubbleChart from .line_chart import LineChart, LineChart3D from .pie_chart import ( PieChart, PieChart3D, DoughnutChart, ProjectedPieChart ) from .radar_chart import RadarChart from .scatter_chart import ScatterChart from .stock_chart import StockChart from .surface_chart import SurfaceChart, SurfaceChart3D from .series_factory import SeriesFactory as Series from .reference import Reference ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/_chart.py0000644000000000000000000001271700000000000015071 0ustar00# Copyright (c) 2010-2021 openpyxl from collections import OrderedDict from operator import attrgetter from openpyxl.descriptors import ( Typed, Integer, Alias, MinMax, Bool, Set, ) from openpyxl.descriptors.sequence import ValueSequence from openpyxl.descriptors.serialisable import Serialisable from ._3d import _3DBase from .data_source import AxDataSource, NumRef from .layout import Layout from .legend import Legend from .reference import Reference from .series_factory import SeriesFactory from .series import attribute_mapping from .shapes import GraphicalProperties from .title import TitleDescriptor class AxId(Serialisable): val = Integer() def __init__(self, val): self.val = val def PlotArea(): from .chartspace import PlotArea return PlotArea() class ChartBase(Serialisable): """ Base class for all charts """ legend = Typed(expected_type=Legend, allow_none=True) layout = Typed(expected_type=Layout, allow_none=True) roundedCorners = Bool(allow_none=True) axId = ValueSequence(expected_type=int) visible_cells_only = Bool(allow_none=True) display_blanks = Set(values=['span', 'gap', 'zero']) _series_type = "" ser = () series = Alias('ser') title = TitleDescriptor() anchor = "E15" # default anchor position width = 15 # in cm, approx 5 rows height = 7.5 # in cm, approx 14 rows _id = 1 _path = "/xl/charts/chart{0}.xml" style = MinMax(allow_none=True, min=1, max=48) mime_type = "application/vnd.openxmlformats-officedocument.drawingml.chart+xml" graphical_properties = Typed(expected_type=GraphicalProperties, allow_none=True) __elements__ = () def __init__(self, axId=(), **kw): self._charts = [self] self.title = None self.layout = None self.roundedCorners = None self.legend = Legend() self.graphical_properties = None self.style = None self.plot_area = PlotArea() self.axId = axId self.display_blanks = 'gap' self.pivotSource = None self.pivotFormats = () self.visible_cells_only = True self.idx_base = 0 super(ChartBase, self).__init__() def __hash__(self): """ Just need to check for identity """ return id(self) def __iadd__(self, other): """ Combine the chart with another one """ if not isinstance(other, ChartBase): raise TypeError("Only other charts can be added") self._charts.append(other) return self def to_tree(self, namespace=None, tagname=None, idx=None): self.axId = [id for id in self._axes] if self.ser is not None: for s in self.ser: s.__elements__ = attribute_mapping[self._series_type] return super(ChartBase, self).to_tree(tagname, idx) def _reindex(self): """ Normalise and rebase series: sort by order and then rebase order """ # sort data series in order and rebase ds = sorted(self.series, key=attrgetter("order")) for idx, s in enumerate(ds): s.order = idx self.series = ds def _write(self): from .chartspace import ChartSpace, ChartContainer self.plot_area.layout = self.layout idx_base = self.idx_base for chart in self._charts: if chart not in self.plot_area._charts: chart.idx_base = idx_base idx_base += len(chart.series) self.plot_area._charts = self._charts container = ChartContainer(plotArea=self.plot_area, legend=self.legend, title=self.title) if isinstance(chart, _3DBase): container.view3D = chart.view3D container.floor = chart.floor container.sideWall = chart.sideWall container.backWall = chart.backWall container.plotVisOnly = self.visible_cells_only container.dispBlanksAs = self.display_blanks container.pivotFmts = self.pivotFormats cs = ChartSpace(chart=container) cs.style = self.style cs.roundedCorners = self.roundedCorners cs.pivotSource = self.pivotSource return cs.to_tree() @property def _axes(self): x = getattr(self, "x_axis", None) y = getattr(self, "y_axis", None) z = getattr(self, "z_axis", None) return OrderedDict([(axis.axId, axis) for axis in (x, y, z) if axis]) def set_categories(self, labels): """ Set the categories / x-axis values """ if not isinstance(labels, Reference): labels = Reference(range_string=labels) for s in self.ser: s.cat = AxDataSource(numRef=NumRef(f=labels)) def add_data(self, data, from_rows=False, titles_from_data=False): """ Add a range of data in a single pass. The default is to treat each column as a data series. """ if not isinstance(data, Reference): data = Reference(range_string=data) if from_rows: values = data.rows else: values = data.cols for ref in values: series = SeriesFactory(ref, title_from_data=titles_from_data) self.series.append(series) def append(self, value): """Append a data series to the chart""" l = self.series[:] l.append(value) self.series = l @property def path(self): return self._path.format(self._id) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/area_chart.py0000644000000000000000000000555500000000000015724 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import ( Typed, Set, Bool, Integer, Sequence, Alias, ) from openpyxl.descriptors.excel import ExtensionList from openpyxl.descriptors.nested import ( NestedMinMax, NestedSet, NestedBool, ) from ._chart import ChartBase from .descriptors import NestedGapAmount from .axis import TextAxis, NumericAxis, SeriesAxis, ChartLines from .label import DataLabelList from .series import Series class _AreaChartBase(ChartBase): grouping = NestedSet(values=(['percentStacked', 'standard', 'stacked'])) varyColors = NestedBool(nested=True, allow_none=True) ser = Sequence(expected_type=Series, allow_none=True) dLbls = Typed(expected_type=DataLabelList, allow_none=True) dataLabels = Alias("dLbls") dropLines = Typed(expected_type=ChartLines, allow_none=True) _series_type = "area" __elements__ = ('grouping', 'varyColors', 'ser', 'dLbls', 'dropLines') def __init__(self, grouping="standard", varyColors=None, ser=(), dLbls=None, dropLines=None, ): self.grouping = grouping self.varyColors = varyColors self.ser = ser self.dLbls = dLbls self.dropLines = dropLines super(_AreaChartBase, self).__init__() class AreaChart(_AreaChartBase): tagname = "areaChart" grouping = _AreaChartBase.grouping varyColors = _AreaChartBase.varyColors ser = _AreaChartBase.ser dLbls = _AreaChartBase.dLbls dropLines = _AreaChartBase.dropLines # chart properties actually used by containing classes x_axis = Typed(expected_type=TextAxis) y_axis = Typed(expected_type=NumericAxis) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = _AreaChartBase.__elements__ + ('axId',) def __init__(self, axId=None, extLst=None, **kw ): self.x_axis = TextAxis() self.y_axis = NumericAxis() super(AreaChart, self).__init__(**kw) class AreaChart3D(AreaChart): tagname = "area3DChart" grouping = _AreaChartBase.grouping varyColors = _AreaChartBase.varyColors ser = _AreaChartBase.ser dLbls = _AreaChartBase.dLbls dropLines = _AreaChartBase.dropLines gapDepth = NestedGapAmount() x_axis = Typed(expected_type=TextAxis) y_axis = Typed(expected_type=NumericAxis) z_axis = Typed(expected_type=SeriesAxis, allow_none=True) __elements__ = AreaChart.__elements__ + ('gapDepth', ) def __init__(self, gapDepth=None, **kw): self.gapDepth = gapDepth super(AreaChart3D, self).__init__(**kw) self.x_axis = TextAxis() self.y_axis = NumericAxis() self.z_axis = SeriesAxis() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/axis.py0000644000000000000000000003056100000000000014572 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import ( Typed, Float, NoneSet, Bool, Integer, MinMax, NoneSet, Set, String, Alias, ) from openpyxl.descriptors.excel import ( ExtensionList, Percentage, _explicit_none, ) from openpyxl.descriptors.nested import ( NestedValue, NestedSet, NestedBool, NestedNoneSet, NestedFloat, NestedInteger, NestedMinMax, ) from openpyxl.xml.constants import CHART_NS from .descriptors import NumberFormatDescriptor from .layout import Layout from .text import Text, RichText from .shapes import GraphicalProperties from .title import Title, TitleDescriptor class ChartLines(Serialisable): tagname = "chartLines" spPr = Typed(expected_type=GraphicalProperties, allow_none=True) graphicalProperties = Alias('spPr') def __init__(self, spPr=None): self.spPr = spPr class Scaling(Serialisable): tagname = "scaling" logBase = NestedFloat(allow_none=True) orientation = NestedSet(values=(['maxMin', 'minMax'])) max = NestedFloat(allow_none=True) min = NestedFloat(allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('logBase', 'orientation', 'max', 'min',) def __init__(self, logBase=None, orientation="minMax", max=None, min=None, extLst=None, ): self.logBase = logBase self.orientation = orientation self.max = max self.min = min class _BaseAxis(Serialisable): axId = NestedInteger(expected_type=int) scaling = Typed(expected_type=Scaling) delete = NestedBool(allow_none=True) axPos = NestedSet(values=(['b', 'l', 'r', 't'])) majorGridlines = Typed(expected_type=ChartLines, allow_none=True) minorGridlines = Typed(expected_type=ChartLines, allow_none=True) title = TitleDescriptor() numFmt = NumberFormatDescriptor() number_format = Alias("numFmt") majorTickMark = NestedNoneSet(values=(['cross', 'in', 'out']), to_tree=_explicit_none) minorTickMark = NestedNoneSet(values=(['cross', 'in', 'out']), to_tree=_explicit_none) tickLblPos = NestedNoneSet(values=(['high', 'low', 'nextTo'])) spPr = Typed(expected_type=GraphicalProperties, allow_none=True) graphicalProperties = Alias('spPr') txPr = Typed(expected_type=RichText, allow_none=True) textProperties = Alias('txPr') crossAx = NestedInteger(expected_type=int) # references other axis crosses = NestedNoneSet(values=(['autoZero', 'max', 'min'])) crossesAt = NestedFloat(allow_none=True) # crosses & crossesAt are mutually exclusive __elements__ = ('axId', 'scaling', 'delete', 'axPos', 'majorGridlines', 'minorGridlines', 'title', 'numFmt', 'majorTickMark', 'minorTickMark', 'tickLblPos', 'spPr', 'txPr', 'crossAx', 'crosses', 'crossesAt') def __init__(self, axId=None, scaling=None, delete=None, axPos='l', majorGridlines=None, minorGridlines=None, title=None, numFmt=None, majorTickMark=None, minorTickMark=None, tickLblPos=None, spPr=None, txPr= None, crossAx=None, crosses=None, crossesAt=None, ): self.axId = axId if scaling is None: scaling = Scaling() self.scaling = scaling self.delete = delete self.axPos = axPos self.majorGridlines = majorGridlines self.minorGridlines = minorGridlines self.title = title self.numFmt = numFmt self.majorTickMark = majorTickMark self.minorTickMark = minorTickMark self.tickLblPos = tickLblPos self.spPr = spPr self.txPr = txPr self.crossAx = crossAx self.crosses = crosses self.crossesAt = crossesAt class DisplayUnitsLabel(Serialisable): tagname = "dispUnitsLbl" layout = Typed(expected_type=Layout, allow_none=True) tx = Typed(expected_type=Text, allow_none=True) text = Alias("tx") spPr = Typed(expected_type=GraphicalProperties, allow_none=True) graphicalProperties = Alias("spPr") txPr = Typed(expected_type=RichText, allow_none=True) textPropertes = Alias("txPr") __elements__ = ('layout', 'tx', 'spPr', 'txPr') def __init__(self, layout=None, tx=None, spPr=None, txPr=None, ): self.layout = layout self.tx = tx self.spPr = spPr self.txPr = txPr class DisplayUnitsLabelList(Serialisable): tagname = "dispUnits" custUnit = NestedFloat(allow_none=True) builtInUnit = NestedNoneSet(values=(['hundreds', 'thousands', 'tenThousands', 'hundredThousands', 'millions', 'tenMillions', 'hundredMillions', 'billions', 'trillions'])) dispUnitsLbl = Typed(expected_type=DisplayUnitsLabel, allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('custUnit', 'builtInUnit', 'dispUnitsLbl',) def __init__(self, custUnit=None, builtInUnit=None, dispUnitsLbl=None, extLst=None, ): self.custUnit = custUnit self.builtInUnit = builtInUnit self.dispUnitsLbl = dispUnitsLbl class NumericAxis(_BaseAxis): tagname = "valAx" axId = _BaseAxis.axId scaling = _BaseAxis.scaling delete = _BaseAxis.delete axPos = _BaseAxis.axPos majorGridlines = _BaseAxis.majorGridlines minorGridlines = _BaseAxis.minorGridlines title = _BaseAxis.title numFmt = _BaseAxis.numFmt majorTickMark = _BaseAxis.majorTickMark minorTickMark = _BaseAxis.minorTickMark tickLblPos = _BaseAxis.tickLblPos spPr = _BaseAxis.spPr txPr = _BaseAxis.txPr crossAx = _BaseAxis.crossAx crosses = _BaseAxis.crosses crossesAt = _BaseAxis.crossesAt crossBetween = NestedNoneSet(values=(['between', 'midCat'])) majorUnit = NestedFloat(allow_none=True) minorUnit = NestedFloat(allow_none=True) dispUnits = Typed(expected_type=DisplayUnitsLabelList, allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = _BaseAxis.__elements__ + ('crossBetween', 'majorUnit', 'minorUnit', 'dispUnits',) def __init__(self, crossBetween=None, majorUnit=None, minorUnit=None, dispUnits=None, extLst=None, **kw ): self.crossBetween = crossBetween self.majorUnit = majorUnit self.minorUnit = minorUnit self.dispUnits = dispUnits kw.setdefault('majorGridlines', ChartLines()) kw.setdefault('axId', 100) kw.setdefault('crossAx', 10) super(NumericAxis, self).__init__(**kw) @classmethod def from_tree(cls, node): """ Special case value axes with no gridlines """ self = super(NumericAxis, cls).from_tree(node) gridlines = node.find("{%s}majorGridlines" % CHART_NS) if gridlines is None: self.majorGridlines = None return self class TextAxis(_BaseAxis): tagname = "catAx" axId = _BaseAxis.axId scaling = _BaseAxis.scaling delete = _BaseAxis.delete axPos = _BaseAxis.axPos majorGridlines = _BaseAxis.majorGridlines minorGridlines = _BaseAxis.minorGridlines title = _BaseAxis.title numFmt = _BaseAxis.numFmt majorTickMark = _BaseAxis.majorTickMark minorTickMark = _BaseAxis.minorTickMark tickLblPos = _BaseAxis.tickLblPos spPr = _BaseAxis.spPr txPr = _BaseAxis.txPr crossAx = _BaseAxis.crossAx crosses = _BaseAxis.crosses crossesAt = _BaseAxis.crossesAt auto = NestedBool(allow_none=True) lblAlgn = NestedNoneSet(values=(['ctr', 'l', 'r'])) lblOffset = NestedMinMax(min=0, max=1000) tickLblSkip = NestedInteger(allow_none=True) tickMarkSkip = NestedInteger(allow_none=True) noMultiLvlLbl = NestedBool(allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = _BaseAxis.__elements__ + ('auto', 'lblAlgn', 'lblOffset', 'tickLblSkip', 'tickMarkSkip', 'noMultiLvlLbl') def __init__(self, auto=None, lblAlgn=None, lblOffset=100, tickLblSkip=None, tickMarkSkip=None, noMultiLvlLbl=None, extLst=None, **kw ): self.auto = auto self.lblAlgn = lblAlgn self.lblOffset = lblOffset self.tickLblSkip = tickLblSkip self.tickMarkSkip = tickMarkSkip self.noMultiLvlLbl = noMultiLvlLbl kw.setdefault('axId', 10) kw.setdefault('crossAx', 100) super(TextAxis, self).__init__(**kw) class DateAxis(TextAxis): tagname = "dateAx" axId = _BaseAxis.axId scaling = _BaseAxis.scaling delete = _BaseAxis.delete axPos = _BaseAxis.axPos majorGridlines = _BaseAxis.majorGridlines minorGridlines = _BaseAxis.minorGridlines title = _BaseAxis.title numFmt = _BaseAxis.numFmt majorTickMark = _BaseAxis.majorTickMark minorTickMark = _BaseAxis.minorTickMark tickLblPos = _BaseAxis.tickLblPos spPr = _BaseAxis.spPr txPr = _BaseAxis.txPr crossAx = _BaseAxis.crossAx crosses = _BaseAxis.crosses crossesAt = _BaseAxis.crossesAt auto = NestedBool(allow_none=True) lblOffset = NestedInteger(allow_none=True) baseTimeUnit = NestedNoneSet(values=(['days', 'months', 'years'])) majorUnit = NestedFloat(allow_none=True) majorTimeUnit = NestedNoneSet(values=(['days', 'months', 'years'])) minorUnit = NestedFloat(allow_none=True) minorTimeUnit = NestedNoneSet(values=(['days', 'months', 'years'])) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = _BaseAxis.__elements__ + ('auto', 'lblOffset', 'baseTimeUnit', 'majorUnit', 'majorTimeUnit', 'minorUnit', 'minorTimeUnit') def __init__(self, auto=None, lblOffset=None, baseTimeUnit=None, majorUnit=None, majorTimeUnit=None, minorUnit=None, minorTimeUnit=None, extLst=None, **kw ): self.auto = auto self.lblOffset = lblOffset self.baseTimeUnit = baseTimeUnit self.majorUnit = majorUnit self.majorTimeUnit = majorTimeUnit self.minorUnit = minorUnit self.minorTimeUnit = minorTimeUnit kw.setdefault('axId', 500) kw.setdefault('lblOffset', lblOffset) super(DateAxis, self).__init__(**kw) class SeriesAxis(_BaseAxis): tagname = "serAx" axId = _BaseAxis.axId scaling = _BaseAxis.scaling delete = _BaseAxis.delete axPos = _BaseAxis.axPos majorGridlines = _BaseAxis.majorGridlines minorGridlines = _BaseAxis.minorGridlines title = _BaseAxis.title numFmt = _BaseAxis.numFmt majorTickMark = _BaseAxis.majorTickMark minorTickMark = _BaseAxis.minorTickMark tickLblPos = _BaseAxis.tickLblPos spPr = _BaseAxis.spPr txPr = _BaseAxis.txPr crossAx = _BaseAxis.crossAx crosses = _BaseAxis.crosses crossesAt = _BaseAxis.crossesAt tickLblSkip = NestedInteger(allow_none=True) tickMarkSkip = NestedInteger(allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = _BaseAxis.__elements__ + ('tickLblSkip', 'tickMarkSkip') def __init__(self, tickLblSkip=None, tickMarkSkip=None, extLst=None, **kw ): self.tickLblSkip = tickLblSkip self.tickMarkSkip = tickMarkSkip kw.setdefault('axId', 1000) kw.setdefault('crossAx', 10) super(SeriesAxis, self).__init__(**kw) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/bar_chart.py0000644000000000000000000001011700000000000015546 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import ( Typed, Bool, Integer, Sequence, Alias, ) from openpyxl.descriptors.excel import ExtensionList from openpyxl.descriptors.nested import ( NestedNoneSet, NestedSet, NestedBool, NestedInteger, NestedMinMax, ) from .descriptors import ( NestedGapAmount, NestedOverlap, ) from ._chart import ChartBase from ._3d import _3DBase from .axis import TextAxis, NumericAxis, SeriesAxis, ChartLines from .shapes import GraphicalProperties from .series import Series from .legend import Legend from .label import DataLabelList class _BarChartBase(ChartBase): barDir = NestedSet(values=(['bar', 'col'])) type = Alias("barDir") grouping = NestedSet(values=(['percentStacked', 'clustered', 'standard', 'stacked'])) varyColors = NestedBool(nested=True, allow_none=True) ser = Sequence(expected_type=Series, allow_none=True) dLbls = Typed(expected_type=DataLabelList, allow_none=True) dataLabels = Alias("dLbls") __elements__ = ('barDir', 'grouping', 'varyColors', 'ser', 'dLbls') _series_type = "bar" def __init__(self, barDir="col", grouping="clustered", varyColors=None, ser=(), dLbls=None, **kw ): self.barDir = barDir self.grouping = grouping self.varyColors = varyColors self.ser = ser self.dLbls = dLbls super(_BarChartBase, self).__init__(**kw) class BarChart(_BarChartBase): tagname = "barChart" barDir = _BarChartBase.barDir grouping = _BarChartBase.grouping varyColors = _BarChartBase.varyColors ser = _BarChartBase.ser dLbls = _BarChartBase.dLbls gapWidth = NestedGapAmount() overlap = NestedOverlap() serLines = Typed(expected_type=ChartLines, allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) # chart properties actually used by containing classes x_axis = Typed(expected_type=TextAxis) y_axis = Typed(expected_type=NumericAxis) __elements__ = _BarChartBase.__elements__ + ('gapWidth', 'overlap', 'serLines', 'axId') def __init__(self, gapWidth=150, overlap=None, serLines=None, extLst=None, **kw ): self.gapWidth = gapWidth self.overlap = overlap self.serLines = serLines self.x_axis = TextAxis() self.y_axis = NumericAxis() self.legend = Legend() super(BarChart, self).__init__(**kw) class BarChart3D(_BarChartBase, _3DBase): tagname = "bar3DChart" barDir = _BarChartBase.barDir grouping = _BarChartBase.grouping varyColors = _BarChartBase.varyColors ser = _BarChartBase.ser dLbls = _BarChartBase.dLbls view3D = _3DBase.view3D floor = _3DBase.floor sideWall = _3DBase.sideWall backWall = _3DBase.backWall gapWidth = NestedGapAmount() gapDepth = NestedGapAmount() shape = NestedNoneSet(values=(['cone', 'coneToMax', 'box', 'cylinder', 'pyramid', 'pyramidToMax'])) serLines = Typed(expected_type=ChartLines, allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) x_axis = Typed(expected_type=TextAxis) y_axis = Typed(expected_type=NumericAxis) z_axis = Typed(expected_type=SeriesAxis, allow_none=True) __elements__ = _BarChartBase.__elements__ + ('gapWidth', 'gapDepth', 'shape', 'serLines', 'axId') def __init__(self, gapWidth=150, gapDepth=150, shape=None, serLines=None, extLst=None, **kw ): self.gapWidth = gapWidth self.gapDepth = gapDepth self.shape = shape self.serLines = serLines self.x_axis = TextAxis() self.y_axis = NumericAxis() self.z_axis = SeriesAxis() super(BarChart3D, self).__init__(**kw) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/bubble_chart.py0000644000000000000000000000374500000000000016246 0ustar00#Autogenerated schema from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import ( Typed, Set, MinMax, Bool, Integer, Alias, Sequence, ) from openpyxl.descriptors.excel import ExtensionList from openpyxl.descriptors.nested import ( NestedNoneSet, NestedMinMax, NestedBool, ) from ._chart import ChartBase from .axis import TextAxis, NumericAxis from .series import XYSeries from .label import DataLabelList class BubbleChart(ChartBase): tagname = "bubbleChart" varyColors = NestedBool(allow_none=True) ser = Sequence(expected_type=XYSeries, allow_none=True) dLbls = Typed(expected_type=DataLabelList, allow_none=True) dataLabels = Alias("dLbls") bubble3D = NestedBool(allow_none=True) bubbleScale = NestedMinMax(min=0, max=300, allow_none=True) showNegBubbles = NestedBool(allow_none=True) sizeRepresents = NestedNoneSet(values=(['area', 'w'])) extLst = Typed(expected_type=ExtensionList, allow_none=True) x_axis = Typed(expected_type=NumericAxis) y_axis = Typed(expected_type=NumericAxis) _series_type = "bubble" __elements__ = ('varyColors', 'ser', 'dLbls', 'bubble3D', 'bubbleScale', 'showNegBubbles', 'sizeRepresents', 'axId') def __init__(self, varyColors=None, ser=(), dLbls=None, bubble3D=None, bubbleScale=None, showNegBubbles=None, sizeRepresents=None, extLst=None, **kw ): self.varyColors = varyColors self.ser = ser self.dLbls = dLbls self.bubble3D = bubble3D self.bubbleScale = bubbleScale self.showNegBubbles = showNegBubbles self.sizeRepresents = sizeRepresents self.x_axis = NumericAxis(axId=10, crossAx=20) self.y_axis = NumericAxis(axId=20, crossAx=10) super(BubbleChart, self).__init__(**kw) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/chartspace.py0000644000000000000000000001375200000000000015746 0ustar00from __future__ import absolute_import # Copyright (c) 2010-2021 openpyxl """ Enclosing chart object. The various chart types are actually child objects. Will probably need to call this indirectly """ from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import ( Typed, String, Alias, ) from openpyxl.descriptors.excel import ( ExtensionList, Relation ) from openpyxl.descriptors.nested import ( NestedBool, NestedNoneSet, NestedString, NestedMinMax, ) from openpyxl.descriptors.sequence import NestedSequence from openpyxl.xml.constants import CHART_NS from openpyxl.drawing.colors import ColorMapping from .text import RichText from .shapes import GraphicalProperties from .legend import Legend from ._3d import _3DBase from .plotarea import PlotArea from .title import Title from .pivot import ( PivotFormat, PivotSource, ) from .print_settings import PrintSettings class ChartContainer(Serialisable): tagname = "chart" title = Typed(expected_type=Title, allow_none=True) autoTitleDeleted = NestedBool(allow_none=True) pivotFmts = NestedSequence(expected_type=PivotFormat) view3D = _3DBase.view3D floor = _3DBase.floor sideWall = _3DBase.sideWall backWall = _3DBase.backWall plotArea = Typed(expected_type=PlotArea, ) legend = Typed(expected_type=Legend, allow_none=True) plotVisOnly = NestedBool() dispBlanksAs = NestedNoneSet(values=(['span', 'gap', 'zero'])) showDLblsOverMax = NestedBool(allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('title', 'autoTitleDeleted', 'pivotFmts', 'view3D', 'floor', 'sideWall', 'backWall', 'plotArea', 'legend', 'plotVisOnly', 'dispBlanksAs', 'showDLblsOverMax') def __init__(self, title=None, autoTitleDeleted=None, pivotFmts=(), view3D=None, floor=None, sideWall=None, backWall=None, plotArea=None, legend=None, plotVisOnly=True, dispBlanksAs="gap", showDLblsOverMax=None, extLst=None, ): self.title = title self.autoTitleDeleted = autoTitleDeleted self.pivotFmts = pivotFmts self.view3D = view3D self.floor = floor self.sideWall = sideWall self.backWall = backWall if plotArea is None: plotArea = PlotArea() self.plotArea = plotArea self.legend = legend self.plotVisOnly = plotVisOnly self.dispBlanksAs = dispBlanksAs self.showDLblsOverMax = showDLblsOverMax class Protection(Serialisable): tagname = "protection" chartObject = NestedBool(allow_none=True) data = NestedBool(allow_none=True) formatting = NestedBool(allow_none=True) selection = NestedBool(allow_none=True) userInterface = NestedBool(allow_none=True) __elements__ = ("chartObject", "data", "formatting", "selection", "userInterface") def __init__(self, chartObject=None, data=None, formatting=None, selection=None, userInterface=None, ): self.chartObject = chartObject self.data = data self.formatting = formatting self.selection = selection self.userInterface = userInterface class ExternalData(Serialisable): tagname = "externalData" autoUpdate = NestedBool(allow_none=True) id = String() # Needs namespace def __init__(self, autoUpdate=None, id=None ): self.autoUpdate = autoUpdate self.id = id class ChartSpace(Serialisable): tagname = "chartSpace" date1904 = NestedBool(allow_none=True) lang = NestedString(allow_none=True) roundedCorners = NestedBool(allow_none=True) style = NestedMinMax(allow_none=True, min=1, max=48) clrMapOvr = Typed(expected_type=ColorMapping, allow_none=True) pivotSource = Typed(expected_type=PivotSource, allow_none=True) protection = Typed(expected_type=Protection, allow_none=True) chart = Typed(expected_type=ChartContainer) spPr = Typed(expected_type=GraphicalProperties, allow_none=True) graphicalProperties = Alias("spPr") txPr = Typed(expected_type=RichText, allow_none=True) textProperties = Alias("txPr") externalData = Typed(expected_type=ExternalData, allow_none=True) printSettings = Typed(expected_type=PrintSettings, allow_none=True) userShapes = Relation() extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('date1904', 'lang', 'roundedCorners', 'style', 'clrMapOvr', 'pivotSource', 'protection', 'chart', 'spPr', 'txPr', 'externalData', 'printSettings', 'userShapes') def __init__(self, date1904=None, lang=None, roundedCorners=None, style=None, clrMapOvr=None, pivotSource=None, protection=None, chart=None, spPr=None, txPr=None, externalData=None, printSettings=None, userShapes=None, extLst=None, ): self.date1904 = date1904 self.lang = lang self.roundedCorners = roundedCorners self.style = style self.clrMapOvr = clrMapOvr self.pivotSource = pivotSource self.protection = protection self.chart = chart self.spPr = spPr self.txPr = txPr self.externalData = externalData self.printSettings = printSettings self.userShapes = userShapes def to_tree(self, tagname=None, idx=None, namespace=None): tree = super(ChartSpace, self).to_tree() tree.set("xmlns", CHART_NS) return tree ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/data_source.py0000644000000000000000000001326100000000000016115 0ustar00""" Collection of utility primitives for charts. """ from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import ( Bool, Typed, Alias, String, Integer, Sequence, ) from openpyxl.descriptors.excel import ExtensionList from openpyxl.descriptors.nested import ( NestedString, NestedText, NestedInteger, ) class NumFmt(Serialisable): formatCode = String() sourceLinked = Bool() def __init__(self, formatCode=None, sourceLinked=False ): self.formatCode = formatCode self.sourceLinked = sourceLinked class NumberValueDescriptor(NestedText): """ Data should be numerical but isn't always :-/ """ allow_none = True def __set__(self, instance, value): if value == "#N/A": self.expected_type = str else: self.expected_type = float super(NumberValueDescriptor, self).__set__(instance, value) class NumVal(Serialisable): idx = Integer() formatCode = NestedText(allow_none=True, expected_type=str) v = NumberValueDescriptor() def __init__(self, idx=None, formatCode=None, v=None, ): self.idx = idx self.formatCode = formatCode self.v = v class NumData(Serialisable): formatCode = NestedText(expected_type=str, allow_none=True) ptCount = NestedInteger(allow_none=True) pt = Sequence(expected_type=NumVal) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('formatCode', 'ptCount', 'pt') def __init__(self, formatCode=None, ptCount=None, pt=(), extLst=None, ): self.formatCode = formatCode self.ptCount = ptCount self.pt = pt class NumRef(Serialisable): f = NestedText(expected_type=str) ref = Alias('f') numCache = Typed(expected_type=NumData, allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('f', 'numCache') def __init__(self, f=None, numCache=None, extLst=None, ): self.f = f self.numCache = numCache class StrVal(Serialisable): tagname = "strVal" idx = Integer() v = NestedText(expected_type=str) def __init__(self, idx=0, v=None, ): self.idx = idx self.v = v class StrData(Serialisable): tagname = "strData" ptCount = NestedInteger(allow_none=True) pt = Sequence(expected_type=StrVal) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('ptCount', 'pt') def __init__(self, ptCount=None, pt=(), extLst=None, ): self.ptCount = ptCount self.pt = pt class StrRef(Serialisable): tagname = "strRef" f = NestedText(expected_type=str, allow_none=True) strCache = Typed(expected_type=StrData, allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('f', 'strCache') def __init__(self, f=None, strCache=None, extLst=None, ): self.f = f self.strCache = strCache class NumDataSource(Serialisable): numRef = Typed(expected_type=NumRef, allow_none=True) numLit = Typed(expected_type=NumData, allow_none=True) def __init__(self, numRef=None, numLit=None, ): self.numRef = numRef self.numLit = numLit class Level(Serialisable): tagname = "lvl" pt = Sequence(expected_type=StrVal) __elements__ = ('pt',) def __init__(self, pt=(), ): self.pt = pt class MultiLevelStrData(Serialisable): tagname = "multiLvlStrData" ptCount = Integer(allow_none=True) lvl = Sequence(expected_type=Level) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('ptCount', 'lvl',) def __init__(self, ptCount=None, lvl=(), extLst=None, ): self.ptCount = ptCount self.lvl = lvl class MultiLevelStrRef(Serialisable): tagname = "multiLvlStrRef" f = NestedText(expected_type=str) multiLvlStrCache = Typed(expected_type=MultiLevelStrData, allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('multiLvlStrCache', 'f') def __init__(self, f=None, multiLvlStrCache=None, extLst=None, ): self.f = f self.multiLvlStrCache = multiLvlStrCache class AxDataSource(Serialisable): tagname = "cat" numRef = Typed(expected_type=NumRef, allow_none=True) numLit = Typed(expected_type=NumData, allow_none=True) strRef = Typed(expected_type=StrRef, allow_none=True) strLit = Typed(expected_type=StrData, allow_none=True) multiLvlStrRef = Typed(expected_type=MultiLevelStrRef, allow_none=True) def __init__(self, numRef=None, numLit=None, strRef=None, strLit=None, multiLvlStrRef=None, ): if not any([numLit, numRef, strRef, strLit, multiLvlStrRef]): raise TypeError("A data source must be provided") self.numRef = numRef self.numLit = numLit self.strRef = strRef self.strLit = strLit self.multiLvlStrRef = multiLvlStrRef ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/descriptors.py0000644000000000000000000000137400000000000016167 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors.nested import ( NestedMinMax ) from openpyxl.descriptors import Typed from .data_source import NumFmt """ Utility descriptors for the chart module. For convenience but also clarity. """ class NestedGapAmount(NestedMinMax): allow_none = True min = 0 max = 500 class NestedOverlap(NestedMinMax): allow_none = True min = -100 max = 100 class NumberFormatDescriptor(Typed): """ Allow direct assignment of format code """ expected_type = NumFmt allow_none = True def __set__(self, instance, value): if isinstance(value, str): value = NumFmt(value) super(NumberFormatDescriptor, self).__set__(instance, value) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/error_bar.py0000644000000000000000000000345000000000000015600 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import ( Typed, Float, Set, Alias ) from openpyxl.descriptors.excel import ExtensionList from openpyxl.descriptors.nested import ( NestedNoneSet, NestedSet, NestedBool, NestedFloat, ) from .data_source import NumDataSource from .shapes import GraphicalProperties class ErrorBars(Serialisable): tagname = "errBars" errDir = NestedNoneSet(values=(['x', 'y'])) direction = Alias("errDir") errBarType = NestedSet(values=(['both', 'minus', 'plus'])) style = Alias("errBarType") errValType = NestedSet(values=(['cust', 'fixedVal', 'percentage', 'stdDev', 'stdErr'])) size = Alias("errValType") noEndCap = NestedBool(nested=True, allow_none=True) plus = Typed(expected_type=NumDataSource, allow_none=True) minus = Typed(expected_type=NumDataSource, allow_none=True) val = NestedFloat(allow_none=True) spPr = Typed(expected_type=GraphicalProperties, allow_none=True) graphicalProperties = Alias("spPr") extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('errDir','errBarType', 'errValType', 'noEndCap','minus', 'plus', 'val', 'spPr') def __init__(self, errDir=None, errBarType="both", errValType="fixedVal", noEndCap=None, plus=None, minus=None, val=None, spPr=None, extLst=None, ): self.errDir = errDir self.errBarType = errBarType self.errValType = errValType self.noEndCap = noEndCap self.plus = plus self.minus = minus self.val = val self.spPr = spPr ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/label.py0000644000000000000000000001010700000000000014677 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import ( Sequence, Alias, Typed ) from openpyxl.descriptors.excel import ExtensionList from openpyxl.descriptors.nested import ( NestedNoneSet, NestedBool, NestedString, NestedInteger, ) from .shapes import GraphicalProperties from .text import RichText class _DataLabelBase(Serialisable): numFmt = NestedString(allow_none=True, attribute="formatCode") spPr = Typed(expected_type=GraphicalProperties, allow_none=True) graphicalProperties = Alias('spPr') txPr = Typed(expected_type=RichText, allow_none=True) textProperties = Alias('txPr') dLblPos = NestedNoneSet(values=['bestFit', 'b', 'ctr', 'inBase', 'inEnd', 'l', 'outEnd', 'r', 't']) position = Alias('dLblPos') showLegendKey = NestedBool(allow_none=True) showVal = NestedBool(allow_none=True) showCatName = NestedBool(allow_none=True) showSerName = NestedBool(allow_none=True) showPercent = NestedBool(allow_none=True) showBubbleSize = NestedBool(allow_none=True) showLeaderLines = NestedBool(allow_none=True) separator = NestedString(allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ("numFmt", "spPr", "txPr", "dLblPos", "showLegendKey", "showVal", "showCatName", "showSerName", "showPercent", "showBubbleSize", "showLeaderLines", "separator") def __init__(self, numFmt=None, spPr=None, txPr=None, dLblPos=None, showLegendKey=None, showVal=None, showCatName=None, showSerName=None, showPercent=None, showBubbleSize=None, showLeaderLines=None, separator=None, extLst=None, ): self.numFmt = numFmt self.spPr = spPr self.txPr = txPr self.dLblPos = dLblPos self.showLegendKey = showLegendKey self.showVal = showVal self.showCatName = showCatName self.showSerName = showSerName self.showPercent = showPercent self.showBubbleSize = showBubbleSize self.showLeaderLines = showLeaderLines self.separator = separator class DataLabel(_DataLabelBase): tagname = "dLbl" idx = NestedInteger() numFmt = _DataLabelBase.numFmt spPr = _DataLabelBase.spPr txPr = _DataLabelBase.txPr dLblPos = _DataLabelBase.dLblPos showLegendKey = _DataLabelBase.showLegendKey showVal = _DataLabelBase.showVal showCatName = _DataLabelBase.showCatName showSerName = _DataLabelBase.showSerName showPercent = _DataLabelBase.showPercent showBubbleSize = _DataLabelBase.showBubbleSize showLeaderLines = _DataLabelBase.showLeaderLines separator = _DataLabelBase.separator extLst = _DataLabelBase.extLst __elements__ = ("idx",) + _DataLabelBase.__elements__ def __init__(self, idx=0, **kw ): self.idx = idx super(DataLabel, self).__init__(**kw) class DataLabelList(_DataLabelBase): tagname = "dLbls" dLbl = Sequence(expected_type=DataLabel, allow_none=True) delete = NestedBool(allow_none=True) numFmt = _DataLabelBase.numFmt spPr = _DataLabelBase.spPr txPr = _DataLabelBase.txPr dLblPos = _DataLabelBase.dLblPos showLegendKey = _DataLabelBase.showLegendKey showVal = _DataLabelBase.showVal showCatName = _DataLabelBase.showCatName showSerName = _DataLabelBase.showSerName showPercent = _DataLabelBase.showPercent showBubbleSize = _DataLabelBase.showBubbleSize showLeaderLines = _DataLabelBase.showLeaderLines separator = _DataLabelBase.separator extLst = _DataLabelBase.extLst __elements__ = ("delete", "dLbl",) + _DataLabelBase.__elements__ def __init__(self, dLbl=(), delete=None, **kw): self.dLbl = dLbl self.delete = delete super(DataLabelList, self).__init__(**kw) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/layout.py0000644000000000000000000000377000000000000015145 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import ( NoneSet, Float, Typed, Alias, ) from openpyxl.descriptors.excel import ExtensionList from openpyxl.descriptors.nested import ( NestedNoneSet, NestedSet, NestedMinMax, ) class ManualLayout(Serialisable): tagname = "manualLayout" layoutTarget = NestedNoneSet(values=(['inner', 'outer'])) xMode = NestedNoneSet(values=(['edge', 'factor'])) yMode = NestedNoneSet(values=(['edge', 'factor'])) wMode = NestedSet(values=(['edge', 'factor'])) hMode = NestedSet(values=(['edge', 'factor'])) x = NestedMinMax(min=-1, max=1, allow_none=True) y = NestedMinMax(min=-1, max=1, allow_none=True) w = NestedMinMax(min=0, max=1, allow_none=True) width = Alias('w') h = NestedMinMax(min=0, max=1, allow_none=True) height = Alias('h') extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('layoutTarget', 'xMode', 'yMode', 'wMode', 'hMode', 'x', 'y', 'w', 'h') def __init__(self, layoutTarget=None, xMode=None, yMode=None, wMode="factor", hMode="factor", x=None, y=None, w=None, h=None, extLst=None, ): self.layoutTarget = layoutTarget self.xMode = xMode self.yMode = yMode self.wMode = wMode self.hMode = hMode self.x = x self.y = y self.w = w self.h = h class Layout(Serialisable): tagname = "layout" manualLayout = Typed(expected_type=ManualLayout, allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('manualLayout',) def __init__(self, manualLayout=None, extLst=None, ): self.manualLayout = manualLayout ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/legend.py0000644000000000000000000000377000000000000015066 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import ( Typed, Integer, Alias, Sequence, ) from openpyxl.descriptors.excel import ExtensionList from openpyxl.descriptors.nested import ( NestedBool, NestedSet, NestedInteger ) from .layout import Layout from .shapes import GraphicalProperties from .text import RichText class LegendEntry(Serialisable): tagname = "legendEntry" idx = NestedInteger() delete = NestedBool() txPr = Typed(expected_type=RichText, allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('idx', 'delete', 'txPr') def __init__(self, idx=0, delete=False, txPr=None, extLst=None, ): self.idx = idx self.delete = delete self.txPr = txPr class Legend(Serialisable): tagname = "legend" legendPos = NestedSet(values=(['b', 'tr', 'l', 'r', 't'])) position = Alias('legendPos') legendEntry = Sequence(expected_type=LegendEntry) layout = Typed(expected_type=Layout, allow_none=True) overlay = NestedBool(allow_none=True) spPr = Typed(expected_type=GraphicalProperties, allow_none=True) graphicalProperties = Alias('spPr') txPr = Typed(expected_type=RichText, allow_none=True) textProperties = Alias('txPr') extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('legendPos', 'legendEntry', 'layout', 'overlay', 'spPr', 'txPr',) def __init__(self, legendPos="r", legendEntry=(), layout=None, overlay=None, spPr=None, txPr=None, extLst=None, ): self.legendPos = legendPos self.legendEntry = legendEntry self.layout = layout self.overlay = overlay self.spPr = spPr self.txPr = txPr ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/line_chart.py0000644000000000000000000000762200000000000015740 0ustar00#Autogenerated schema from openpyxl.descriptors import ( Typed, Sequence, Alias, ) from openpyxl.descriptors.excel import ExtensionList from openpyxl.descriptors.nested import ( NestedSet, NestedBool, ) from ._chart import ChartBase from .updown_bars import UpDownBars from .descriptors import NestedGapAmount from .axis import TextAxis, NumericAxis, SeriesAxis, ChartLines, _BaseAxis from .label import DataLabelList from .series import Series class _LineChartBase(ChartBase): grouping = NestedSet(values=(['percentStacked', 'standard', 'stacked'])) varyColors = NestedBool(allow_none=True) ser = Sequence(expected_type=Series, allow_none=True) dLbls = Typed(expected_type=DataLabelList, allow_none=True) dataLabels = Alias("dLbls") dropLines = Typed(expected_type=ChartLines, allow_none=True) _series_type = "line" __elements__ = ('grouping', 'varyColors', 'ser', 'dLbls', 'dropLines') def __init__(self, grouping="standard", varyColors=None, ser=(), dLbls=None, dropLines=None, **kw ): self.grouping = grouping self.varyColors = varyColors self.ser = ser self.dLbls = dLbls self.dropLines = dropLines super(_LineChartBase, self).__init__(**kw) class LineChart(_LineChartBase): tagname = "lineChart" grouping = _LineChartBase.grouping varyColors = _LineChartBase.varyColors ser = _LineChartBase.ser dLbls = _LineChartBase.dLbls dropLines =_LineChartBase.dropLines hiLowLines = Typed(expected_type=ChartLines, allow_none=True) upDownBars = Typed(expected_type=UpDownBars, allow_none=True) marker = NestedBool(allow_none=True) smooth = NestedBool(allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) x_axis = Typed(expected_type=_BaseAxis) y_axis = Typed(expected_type=NumericAxis) __elements__ = _LineChartBase.__elements__ + ('hiLowLines', 'upDownBars', 'marker', 'smooth', 'axId') def __init__(self, hiLowLines=None, upDownBars=None, marker=None, smooth=None, extLst=None, **kw ): self.hiLowLines = hiLowLines self.upDownBars = upDownBars self.marker = marker self.smooth = smooth self.x_axis = TextAxis() self.y_axis = NumericAxis() super(LineChart, self).__init__(**kw) class LineChart3D(_LineChartBase): tagname = "line3DChart" grouping = _LineChartBase.grouping varyColors = _LineChartBase.varyColors ser = _LineChartBase.ser dLbls = _LineChartBase.dLbls dropLines =_LineChartBase.dropLines gapDepth = NestedGapAmount() hiLowLines = Typed(expected_type=ChartLines, allow_none=True) upDownBars = Typed(expected_type=UpDownBars, allow_none=True) marker = NestedBool(allow_none=True) smooth = NestedBool(allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) x_axis = Typed(expected_type=TextAxis) y_axis = Typed(expected_type=NumericAxis) z_axis = Typed(expected_type=SeriesAxis) __elements__ = _LineChartBase.__elements__ + ('gapDepth', 'hiLowLines', 'upDownBars', 'marker', 'smooth', 'axId') def __init__(self, gapDepth=None, hiLowLines=None, upDownBars=None, marker=None, smooth=None, **kw ): self.gapDepth = gapDepth self.hiLowLines = hiLowLines self.upDownBars = upDownBars self.marker = marker self.smooth = smooth self.x_axis = TextAxis() self.y_axis = NumericAxis() self.z_axis = SeriesAxis() super(LineChart3D, self).__init__(**kw) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/marker.py0000644000000000000000000000505000000000000015102 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import ( Typed, Alias, ) from openpyxl.descriptors.excel import( ExtensionList, _explicit_none, ) from openpyxl.descriptors.nested import ( NestedBool, NestedInteger, NestedMinMax, NestedNoneSet, ) from .layout import Layout from .picture import PictureOptions from .shapes import * from .text import * from .error_bar import * class Marker(Serialisable): tagname = "marker" symbol = NestedNoneSet(values=(['circle', 'dash', 'diamond', 'dot', 'picture', 'plus', 'square', 'star', 'triangle', 'x', 'auto']), to_tree=_explicit_none) size = NestedMinMax(min=2, max=72, allow_none=True) spPr = Typed(expected_type=GraphicalProperties, allow_none=True) graphicalProperties = Alias('spPr') extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('symbol', 'size', 'spPr') def __init__(self, symbol=None, size=None, spPr=None, extLst=None, ): self.symbol = symbol self.size = size if spPr is None: spPr = GraphicalProperties() self.spPr = spPr class DataPoint(Serialisable): tagname = "dPt" idx = NestedInteger() invertIfNegative = NestedBool(allow_none=True) marker = Typed(expected_type=Marker, allow_none=True) bubble3D = NestedBool(allow_none=True) explosion = NestedInteger(allow_none=True) spPr = Typed(expected_type=GraphicalProperties, allow_none=True) graphicalProperties = Alias('spPr') pictureOptions = Typed(expected_type=PictureOptions, allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('idx', 'invertIfNegative', 'marker', 'bubble3D', 'explosion', 'spPr', 'pictureOptions') def __init__(self, idx=None, invertIfNegative=None, marker=None, bubble3D=None, explosion=None, spPr=None, pictureOptions=None, extLst=None, ): self.idx = idx self.invertIfNegative = invertIfNegative self.marker = marker self.bubble3D = bubble3D self.explosion = explosion if spPr is None: spPr = GraphicalProperties() self.spPr = spPr self.pictureOptions = pictureOptions ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/picture.py0000644000000000000000000000220400000000000015272 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors.nested import ( NestedBool, NestedFloat, NestedMinMax, NestedNoneSet, ) class PictureOptions(Serialisable): tagname = "pictureOptions" applyToFront = NestedBool(allow_none=True, nested=True) applyToSides = NestedBool(allow_none=True, nested=True) applyToEnd = NestedBool(allow_none=True, nested=True) pictureFormat = NestedNoneSet(values=(['stretch', 'stack', 'stackScale']), nested=True) pictureStackUnit = NestedFloat(allow_none=True, nested=True) __elements__ = ('applyToFront', 'applyToSides', 'applyToEnd', 'pictureFormat', 'pictureStackUnit') def __init__(self, applyToFront=None, applyToSides=None, applyToEnd=None, pictureFormat=None, pictureStackUnit=None, ): self.applyToFront = applyToFront self.applyToSides = applyToSides self.applyToEnd = applyToEnd self.pictureFormat = pictureFormat self.pictureStackUnit = pictureStackUnit ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/pie_chart.py0000644000000000000000000001140400000000000015557 0ustar00#Autogenerated schema from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import ( Typed, Bool, MinMax, Integer, NoneSet, Float, Alias, Sequence, ) from openpyxl.descriptors.excel import ExtensionList, Percentage from openpyxl.descriptors.nested import ( NestedBool, NestedMinMax, NestedInteger, NestedFloat, NestedNoneSet, NestedSet, ) from openpyxl.descriptors.sequence import ValueSequence from ._chart import ChartBase from .axis import ChartLines from .descriptors import NestedGapAmount from .series import Series from .label import DataLabelList class _PieChartBase(ChartBase): varyColors = NestedBool(allow_none=True) ser = Sequence(expected_type=Series, allow_none=True) dLbls = Typed(expected_type=DataLabelList, allow_none=True) dataLabels = Alias("dLbls") _series_type = "pie" __elements__ = ('varyColors', 'ser', 'dLbls') def __init__(self, varyColors=True, ser=(), dLbls=None, ): self.varyColors = varyColors self.ser = ser self.dLbls = dLbls super(_PieChartBase, self).__init__() class PieChart(_PieChartBase): tagname = "pieChart" varyColors = _PieChartBase.varyColors ser = _PieChartBase.ser dLbls = _PieChartBase.dLbls firstSliceAng = NestedMinMax(min=0, max=360) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = _PieChartBase.__elements__ + ('firstSliceAng', ) def __init__(self, firstSliceAng=0, extLst=None, **kw ): self.firstSliceAng = firstSliceAng super(PieChart, self).__init__(**kw) class PieChart3D(_PieChartBase): tagname = "pie3DChart" varyColors = _PieChartBase.varyColors ser = _PieChartBase.ser dLbls = _PieChartBase.dLbls extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = _PieChartBase.__elements__ class DoughnutChart(_PieChartBase): tagname = "doughnutChart" varyColors = _PieChartBase.varyColors ser = _PieChartBase.ser dLbls = _PieChartBase.dLbls firstSliceAng = NestedMinMax(min=0, max=360) holeSize = NestedMinMax(min=1, max=90, allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = _PieChartBase.__elements__ + ('firstSliceAng', 'holeSize') def __init__(self, firstSliceAng=0, holeSize=10, extLst=None, **kw ): self.firstSliceAng = firstSliceAng self.holeSize = holeSize super(DoughnutChart, self).__init__(**kw) class CustomSplit(Serialisable): tagname = "custSplit" secondPiePt = ValueSequence(expected_type=int) __elements__ = ('secondPiePt',) def __init__(self, secondPiePt=(), ): self.secondPiePt = secondPiePt class ProjectedPieChart(_PieChartBase): """ From the spec 21.2.2.126 This element contains the pie of pie or bar of pie series on this chart. Only the first series shall be displayed. The splitType element shall determine whether the splitPos and custSplit elements apply. """ tagname = "ofPieChart" varyColors = _PieChartBase.varyColors ser = _PieChartBase.ser dLbls = _PieChartBase.dLbls ofPieType = NestedSet(values=(['pie', 'bar'])) type = Alias('ofPieType') gapWidth = NestedGapAmount() splitType = NestedNoneSet(values=(['auto', 'cust', 'percent', 'pos', 'val'])) splitPos = NestedFloat(allow_none=True) custSplit = Typed(expected_type=CustomSplit, allow_none=True) secondPieSize = NestedMinMax(min=5, max=200, allow_none=True) serLines = Typed(expected_type=ChartLines, allow_none=True) join_lines = Alias('serLines') extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = _PieChartBase.__elements__ + ('ofPieType', 'gapWidth', 'splitType', 'splitPos', 'custSplit', 'secondPieSize', 'serLines') def __init__(self, ofPieType="pie", gapWidth=None, splitType="auto", splitPos=None, custSplit=None, secondPieSize=75, serLines=None, extLst=None, **kw ): self.ofPieType = ofPieType self.gapWidth = gapWidth self.splitType = splitType self.splitPos = splitPos self.custSplit = custSplit self.secondPieSize = secondPieSize if serLines is None: self.serLines = ChartLines() super(ProjectedPieChart, self).__init__(**kw) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/pivot.py0000644000000000000000000000336300000000000014767 0ustar00from __future__ import absolute_import # Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import ( Alias, Typed, ) from openpyxl.descriptors.nested import NestedInteger, NestedText from openpyxl.descriptors.excel import ExtensionList from .label import DataLabel from .marker import Marker from .shapes import GraphicalProperties from .text import RichText class PivotSource(Serialisable): tagname = "pivotSource" name = NestedText(expected_type=str) fmtId = NestedInteger(expected_type=int) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('name', 'fmtId') def __init__(self, name=None, fmtId=None, extLst=None, ): self.name = name self.fmtId = fmtId class PivotFormat(Serialisable): tagname = "pivotFmt" idx = NestedInteger(nested=True) spPr = Typed(expected_type=GraphicalProperties, allow_none=True) graphicalProperties = Alias("spPr") txPr = Typed(expected_type=RichText, allow_none=True) TextBody = Alias("txPr") marker = Typed(expected_type=Marker, allow_none=True) dLbl = Typed(expected_type=DataLabel, allow_none=True) DataLabel = Alias("dLbl") extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('idx', 'spPr', 'txPr', 'marker', 'dLbl') def __init__(self, idx=0, spPr=None, txPr=None, marker=None, dLbl=None, extLst=None, ): self.idx = idx self.spPr = spPr self.txPr = txPr self.marker = marker self.dLbl = dLbl ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/plotarea.py0000644000000000000000000001331000000000000015426 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import ( Typed, Alias, ) from openpyxl.descriptors.excel import ( ExtensionList, ) from openpyxl.descriptors.sequence import ( MultiSequence, MultiSequencePart, ) from openpyxl.descriptors.nested import ( NestedBool, ) from ._3d import _3DBase from .area_chart import AreaChart, AreaChart3D from .bar_chart import BarChart, BarChart3D from .bubble_chart import BubbleChart from .line_chart import LineChart, LineChart3D from .pie_chart import PieChart, PieChart3D, ProjectedPieChart, DoughnutChart from .radar_chart import RadarChart from .scatter_chart import ScatterChart from .stock_chart import StockChart from .surface_chart import SurfaceChart, SurfaceChart3D from .layout import Layout from .shapes import GraphicalProperties from .text import RichText from .axis import ( NumericAxis, TextAxis, SeriesAxis, DateAxis, ) class DataTable(Serialisable): tagname = "dTable" showHorzBorder = NestedBool(allow_none=True) showVertBorder = NestedBool(allow_none=True) showOutline = NestedBool(allow_none=True) showKeys = NestedBool(allow_none=True) spPr = Typed(expected_type=GraphicalProperties, allow_none=True) graphicalProperties = Alias('spPr') txPr = Typed(expected_type=RichText, allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('showHorzBorder', 'showVertBorder', 'showOutline', 'showKeys', 'spPr', 'txPr') def __init__(self, showHorzBorder=None, showVertBorder=None, showOutline=None, showKeys=None, spPr=None, txPr=None, extLst=None, ): self.showHorzBorder = showHorzBorder self.showVertBorder = showVertBorder self.showOutline = showOutline self.showKeys = showKeys self.spPr = spPr self.txPr = txPr class PlotArea(Serialisable): tagname = "plotArea" layout = Typed(expected_type=Layout, allow_none=True) dTable = Typed(expected_type=DataTable, allow_none=True) spPr = Typed(expected_type=GraphicalProperties, allow_none=True) graphicalProperties = Alias("spPr") extLst = Typed(expected_type=ExtensionList, allow_none=True) # at least one chart _charts = MultiSequence() areaChart = MultiSequencePart(expected_type=AreaChart, store="_charts") area3DChart = MultiSequencePart(expected_type=AreaChart3D, store="_charts") lineChart = MultiSequencePart(expected_type=LineChart, store="_charts") line3DChart = MultiSequencePart(expected_type=LineChart3D, store="_charts") stockChart = MultiSequencePart(expected_type=StockChart, store="_charts") radarChart = MultiSequencePart(expected_type=RadarChart, store="_charts") scatterChart = MultiSequencePart(expected_type=ScatterChart, store="_charts") pieChart = MultiSequencePart(expected_type=PieChart, store="_charts") pie3DChart = MultiSequencePart(expected_type=PieChart3D, store="_charts") doughnutChart = MultiSequencePart(expected_type=DoughnutChart, store="_charts") barChart = MultiSequencePart(expected_type=BarChart, store="_charts") bar3DChart = MultiSequencePart(expected_type=BarChart3D, store="_charts") ofPieChart = MultiSequencePart(expected_type=ProjectedPieChart, store="_charts") surfaceChart = MultiSequencePart(expected_type=SurfaceChart, store="_charts") surface3DChart = MultiSequencePart(expected_type=SurfaceChart3D, store="_charts") bubbleChart = MultiSequencePart(expected_type=BubbleChart, store="_charts") # axes _axes = MultiSequence() valAx = MultiSequencePart(expected_type=NumericAxis, store="_axes") catAx = MultiSequencePart(expected_type=TextAxis, store="_axes") dateAx = MultiSequencePart(expected_type=DateAxis, store="_axes") serAx = MultiSequencePart(expected_type=SeriesAxis, store="_axes") __elements__ = ('layout', '_charts', '_axes', 'dTable', 'spPr') def __init__(self, layout=None, dTable=None, spPr=None, _charts=(), _axes=(), extLst=None, ): self.layout = layout self.dTable = dTable self.spPr = spPr self._charts = _charts self._axes = _axes def to_tree(self, tagname=None, idx=None, namespace=None): axIds = {ax.axId for ax in self._axes} for chart in self._charts: for id, axis in chart._axes.items(): if id not in axIds: setattr(self, axis.tagname, axis) axIds.add(id) return super(PlotArea, self).to_tree(tagname) @classmethod def from_tree(cls, node): self = super(PlotArea, cls).from_tree(node) axes = dict((axis.axId, axis) for axis in self._axes) for chart in self._charts: if isinstance(chart, (ScatterChart, BubbleChart)): x, y = (axes[axId] for axId in chart.axId) chart.x_axis = x chart.y_axis = y continue for axId in chart.axId: axis = axes.get(axId) if axis is None and isinstance(chart, _3DBase): # Series Axis can be optional chart.z_axis = None continue if axis.tagname in ("catAx", "dateAx"): chart.x_axis = axis elif axis.tagname == "valAx": chart.y_axis = axis elif axis.tagname == "serAx": chart.z_axis = axis return self ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/print_settings.py0000644000000000000000000000265600000000000016706 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import ( Float, Typed, Alias, ) from openpyxl.worksheet.page import PrintPageSetup from openpyxl.worksheet.header_footer import HeaderFooter class PageMargins(Serialisable): """ Identical to openpyxl.worksheet.page.Pagemargins but element names are different :-/ """ tagname = "pageMargins" l = Float() left = Alias('l') r = Float() right = Alias('r') t = Float() top = Alias('t') b = Float() bottom = Alias('b') header = Float() footer = Float() def __init__(self, l=0.75, r=0.75, t=1, b=1, header=0.5, footer=0.5): self.l = l self.r = r self.t = t self.b = b self.header = header self.footer = footer class PrintSettings(Serialisable): tagname = "printSettings" headerFooter = Typed(expected_type=HeaderFooter, allow_none=True) pageMargins = Typed(expected_type=PageMargins, allow_none=True) pageSetup = Typed(expected_type=PrintPageSetup, allow_none=True) __elements__ = ("headerFooter", "pageMargins", "pageMargins") def __init__(self, headerFooter=None, pageMargins=None, pageSetup=None, ): self.headerFooter = headerFooter self.pageMargins = pageMargins self.pageSetup = pageSetup ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/radar_chart.py0000644000000000000000000000300100000000000016065 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import ( Sequence, Typed, Alias, ) from openpyxl.descriptors.excel import ExtensionList from openpyxl.descriptors.nested import ( NestedBool, NestedInteger, NestedSet ) from ._chart import ChartBase from .axis import TextAxis, NumericAxis from .series import Series from .label import DataLabelList class RadarChart(ChartBase): tagname = "radarChart" radarStyle = NestedSet(values=(['standard', 'marker', 'filled'])) type = Alias("radarStyle") varyColors = NestedBool(nested=True, allow_none=True) ser = Sequence(expected_type=Series, allow_none=True) dLbls = Typed(expected_type=DataLabelList, allow_none=True) dataLabels = Alias("dLbls") extLst = Typed(expected_type=ExtensionList, allow_none=True) _series_type = "radar" x_axis = Typed(expected_type=TextAxis) y_axis = Typed(expected_type=NumericAxis) __elements__ = ('radarStyle', 'varyColors', 'ser', 'dLbls', 'axId') def __init__(self, radarStyle="standard", varyColors=None, ser=(), dLbls=None, extLst=None, **kw ): self.radarStyle = radarStyle self.varyColors = varyColors self.ser = ser self.dLbls = dLbls self.x_axis = TextAxis() self.y_axis = NumericAxis() super(RadarChart, self).__init__(**kw) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/reader.py0000644000000000000000000000131700000000000015065 0ustar00# Copyright (c) 2010-2021 openpyxl """ Read a chart """ def read_chart(chartspace): cs = chartspace plot = cs.chart.plotArea chart = plot._charts[0] chart._charts = plot._charts chart.title = cs.chart.title chart.display_blanks = cs.chart.dispBlanksAs chart.visible_cells_only = cs.chart.plotVisOnly chart.layout = plot.layout chart.legend = cs.chart.legend # 3d attributes chart.floor = cs.chart.floor chart.sideWall = cs.chart.sideWall chart.backWall = cs.chart.backWall chart.pivotSource = cs.pivotSource chart.pivotFormats = cs.chart.pivotFmts chart.idx_base = min((s.idx for s in chart.series), default=0) chart._reindex() return chart ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/reference.py0000644000000000000000000000603200000000000015560 0ustar00# Copyright (c) 2010-2021 openpyxl from itertools import chain from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import ( MinMax, Typed, String, Strict, ) from openpyxl.worksheet.worksheet import Worksheet from openpyxl.utils import ( get_column_letter, range_to_tuple, quote_sheetname ) class DummyWorksheet: def __init__(self, title): self.title = title class Reference(Strict): """ Normalise cell range references """ min_row = MinMax(min=1, max=1000000, expected_type=int) max_row = MinMax(min=1, max=1000000, expected_type=int) min_col = MinMax(min=1, max=16384, expected_type=int) max_col = MinMax(min=1, max=16384, expected_type=int) range_string = String(allow_none=True) def __init__(self, worksheet=None, min_col=None, min_row=None, max_col=None, max_row=None, range_string=None ): if range_string is not None: sheetname, boundaries = range_to_tuple(range_string) min_col, min_row, max_col, max_row = boundaries worksheet = DummyWorksheet(sheetname) self.worksheet = worksheet self.min_col = min_col self.min_row = min_row if max_col is None: max_col = min_col self.max_col = max_col if max_row is None: max_row = min_row self.max_row = max_row def __repr__(self): return str(self) def __str__(self): fmt = u"{0}!${1}${2}:${3}${4}" if (self.min_col == self.max_col and self.min_row == self.max_row): fmt = u"{0}!${1}${2}" return fmt.format(self.sheetname, get_column_letter(self.min_col), self.min_row, get_column_letter(self.max_col), self.max_row ) __str__ = __str__ def __len__(self): if self.min_row == self.max_row: return 1 + self.max_col - self.min_col return 1 + self.max_row - self.min_row def __eq__(self, other): return str(self) == str(other) @property def rows(self): """ Return all rows in the range """ for row in range(self.min_row, self.max_row+1): yield Reference(self.worksheet, self.min_col, row, self.max_col, row) @property def cols(self): """ Return all columns in the range """ for col in range(self.min_col, self.max_col+1): yield Reference(self.worksheet, col, self.min_row, col, self.max_row) def pop(self): """ Return and remove the first cell """ cell = "{0}{1}".format(get_column_letter(self.min_col), self.min_row) if self.min_row == self.max_row: self.min_col += 1 else: self.min_row += 1 return cell @property def sheetname(self): return quote_sheetname(self.worksheet.title) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/scatter_chart.py0000644000000000000000000000302700000000000016451 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import ( Typed, Sequence, Alias ) from openpyxl.descriptors.excel import ExtensionList from openpyxl.descriptors.nested import ( NestedNoneSet, NestedBool, ) from ._chart import ChartBase from .axis import NumericAxis from .series import XYSeries from .label import DataLabelList class ScatterChart(ChartBase): tagname = "scatterChart" scatterStyle = NestedNoneSet(values=(['line', 'lineMarker', 'marker', 'smooth', 'smoothMarker'])) varyColors = NestedBool(allow_none=True) ser = Sequence(expected_type=XYSeries, allow_none=True) dLbls = Typed(expected_type=DataLabelList, allow_none=True) dataLabels = Alias("dLbls") extLst = Typed(expected_type=ExtensionList, allow_none=True) x_axis = Typed(expected_type=NumericAxis) y_axis = Typed(expected_type=NumericAxis) _series_type = "scatter" __elements__ = ('scatterStyle', 'varyColors', 'ser', 'dLbls', 'axId',) def __init__(self, scatterStyle=None, varyColors=None, ser=(), dLbls=None, extLst=None, **kw ): self.scatterStyle = scatterStyle self.varyColors = varyColors self.ser = ser self.dLbls = dLbls self.x_axis = NumericAxis(axId=10, crossAx=20) self.y_axis = NumericAxis(axId=20, crossAx=10) super(ScatterChart, self).__init__(**kw) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/series.py0000644000000000000000000001342400000000000015117 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import ( Typed, String, Integer, Bool, Alias, Sequence, ) from openpyxl.descriptors.excel import ExtensionList from openpyxl.descriptors.nested import ( NestedInteger, NestedBool, NestedNoneSet, NestedText, ) from .shapes import GraphicalProperties from .data_source import ( AxDataSource, NumDataSource, NumRef, StrRef, ) from .error_bar import ErrorBars from .label import DataLabelList from .marker import DataPoint, PictureOptions, Marker from .trendline import Trendline attribute_mapping = { 'area': ('idx', 'order', 'tx', 'spPr', 'pictureOptions', 'dPt', 'dLbls', 'errBars', 'trendline', 'cat', 'val',), 'bar':('idx', 'order','tx', 'spPr', 'invertIfNegative', 'pictureOptions', 'dPt', 'dLbls', 'trendline', 'errBars', 'cat', 'val', 'shape'), 'bubble':('idx','order', 'tx', 'spPr', 'invertIfNegative', 'dPt', 'dLbls', 'trendline', 'errBars', 'xVal', 'yVal', 'bubbleSize', 'bubble3D'), 'line':('idx', 'order', 'tx', 'spPr', 'marker', 'dPt', 'dLbls', 'trendline', 'errBars', 'cat', 'val', 'smooth'), 'pie':('idx', 'order', 'tx', 'spPr', 'explosion', 'dPt', 'dLbls', 'cat', 'val'), 'radar':('idx', 'order', 'tx', 'spPr', 'marker', 'dPt', 'dLbls', 'cat', 'val'), 'scatter':('idx', 'order', 'tx', 'spPr', 'marker', 'dPt', 'dLbls', 'trendline', 'errBars', 'xVal', 'yVal', 'smooth'), 'surface':('idx', 'order', 'tx', 'spPr', 'cat', 'val'), } class SeriesLabel(Serialisable): tagname = "tx" strRef = Typed(expected_type=StrRef, allow_none=True) v = NestedText(expected_type=str, allow_none=True) value = Alias('v') __elements__ = ('strRef', 'v') def __init__(self, strRef=None, v=None): self.strRef = strRef self.v = v class Series(Serialisable): """ Generic series object. Should not be instantiated directly. User the chart.Series factory instead. """ tagname = "ser" idx = NestedInteger() order = NestedInteger() tx = Typed(expected_type=SeriesLabel, allow_none=True) title = Alias('tx') spPr = Typed(expected_type=GraphicalProperties, allow_none=True) graphicalProperties = Alias('spPr') # area chart pictureOptions = Typed(expected_type=PictureOptions, allow_none=True) dPt = Sequence(expected_type=DataPoint, allow_none=True) data_points = Alias("dPt") dLbls = Typed(expected_type=DataLabelList, allow_none=True) labels = Alias("dLbls") trendline = Typed(expected_type=Trendline, allow_none=True) errBars = Typed(expected_type=ErrorBars, allow_none=True) cat = Typed(expected_type=AxDataSource, allow_none=True) identifiers = Alias("cat") val = Typed(expected_type=NumDataSource, allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) #bar chart invertIfNegative = NestedBool(allow_none=True) shape = NestedNoneSet(values=(['cone', 'coneToMax', 'box', 'cylinder', 'pyramid', 'pyramidToMax'])) #bubble chart xVal = Typed(expected_type=AxDataSource, allow_none=True) yVal = Typed(expected_type=NumDataSource, allow_none=True) bubbleSize = Typed(expected_type=NumDataSource, allow_none=True) zVal = Alias("bubbleSize") bubble3D = NestedBool(allow_none=True) #line chart marker = Typed(expected_type=Marker, allow_none=True) smooth = NestedBool(allow_none=True) #pie chart explosion = NestedInteger(allow_none=True) __elements__ = () def __init__(self, idx=0, order=0, tx=None, spPr=None, pictureOptions=None, dPt=(), dLbls=None, trendline=None, errBars=None, cat=None, val=None, invertIfNegative=None, shape=None, xVal=None, yVal=None, bubbleSize=None, bubble3D=None, marker=None, smooth=None, explosion=None, extLst=None, ): self.idx = idx self.order = order self.tx = tx if spPr is None: spPr = GraphicalProperties() self.spPr = spPr self.pictureOptions = pictureOptions self.dPt = dPt self.dLbls = dLbls self.trendline = trendline self.errBars = errBars self.cat = cat self.val = val self.invertIfNegative = invertIfNegative self.shape = shape self.xVal = xVal self.yVal = yVal self.bubbleSize = bubbleSize self.bubble3D = bubble3D if marker is None: marker = Marker() self.marker = marker self.smooth = smooth self.explosion = explosion def to_tree(self, tagname=None, idx=None): """The index can need rebasing""" if idx is not None: if self.order == self.idx: self.order = idx # rebase the order if the index has been rebased self.idx = idx return super(Series, self).to_tree(tagname) class XYSeries(Series): """Dedicated series for charts that have x and y series""" idx = Series.idx order = Series.order tx = Series.tx spPr = Series.spPr dPt = Series.dPt dLbls = Series.dLbls trendline = Series.trendline errBars = Series.errBars xVal = Series.xVal yVal = Series.yVal invertIfNegative = Series.invertIfNegative bubbleSize = Series.bubbleSize bubble3D = Series.bubble3D marker = Series.marker smooth = Series.smooth ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/series_factory.py0000644000000000000000000000253000000000000016642 0ustar00# Copyright (c) 2010-2021 openpyxl from .data_source import NumDataSource, NumRef, AxDataSource from .reference import Reference from .series import Series, XYSeries, SeriesLabel, StrRef from openpyxl.utils import rows_from_range, quote_sheetname def SeriesFactory(values, xvalues=None, zvalues=None, title=None, title_from_data=False): """ Convenience Factory for creating chart data series. """ if not isinstance(values, Reference): values = Reference(range_string=values) if title_from_data: cell = values.pop() title = u"{0}!{1}".format(values.sheetname, cell) title = SeriesLabel(strRef=StrRef(title)) elif title is not None: title = SeriesLabel(v=title) source = NumDataSource(numRef=NumRef(f=values)) if xvalues is not None: if not isinstance(xvalues, Reference): xvalues = Reference(range_string=xvalues) series = XYSeries() series.yVal = source series.xVal = AxDataSource(numRef=NumRef(f=xvalues)) if zvalues is not None: if not isinstance(zvalues, Reference): zvalues = Reference(range_string=zvalues) series.zVal = NumDataSource(NumRef(f=zvalues)) else: series = Series() series.val = source if title is not None: series.title = title return series ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/shapes.py0000644000000000000000000000537700000000000015120 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import ( Typed, Alias ) from openpyxl.descriptors.nested import ( EmptyTag ) from openpyxl.drawing.colors import ColorChoiceDescriptor from openpyxl.drawing.fill import * from openpyxl.drawing.line import LineProperties from openpyxl.drawing.geometry import ( Shape3D, Scene3D, Transform2D, CustomGeometry2D, PresetGeometry2D, ) class GraphicalProperties(Serialisable): """ Somewhat vaguely 21.2.2.197 says this: This element specifies the formatting for the parent chart element. The custGeom, prstGeom, scene3d, and xfrm elements are not supported. The bwMode attribute is not supported. This doesn't leave much. And the element is used in different places. """ tagname = "spPr" bwMode = NoneSet(values=(['clr', 'auto', 'gray', 'ltGray', 'invGray', 'grayWhite', 'blackGray', 'blackWhite', 'black', 'white', 'hidden'] ) ) xfrm = Typed(expected_type=Transform2D, allow_none=True) transform = Alias('xfrm') custGeom = Typed(expected_type=CustomGeometry2D, allow_none=True) # either or prstGeom = Typed(expected_type=PresetGeometry2D, allow_none=True) # fills one of noFill = EmptyTag(namespace=DRAWING_NS) solidFill = ColorChoiceDescriptor() gradFill = Typed(expected_type=GradientFillProperties, allow_none=True) pattFill = Typed(expected_type=PatternFillProperties, allow_none=True) ln = Typed(expected_type=LineProperties, allow_none=True) line = Alias('ln') scene3d = Typed(expected_type=Scene3D, allow_none=True) sp3d = Typed(expected_type=Shape3D, allow_none=True) shape3D = Alias('sp3d') extLst = Typed(expected_type=OfficeArtExtensionList, allow_none=True) __elements__ = ('xfrm', 'prstGeom', 'noFill', 'solidFill', 'gradFill', 'pattFill', 'ln', 'scene3d', 'sp3d') def __init__(self, bwMode=None, xfrm=None, noFill=None, solidFill=None, gradFill=None, pattFill=None, ln=None, scene3d=None, custGeom=None, prstGeom=None, sp3d=None, extLst=None, ): self.bwMode = bwMode self.xfrm = xfrm self.noFill = noFill self.solidFill = solidFill self.gradFill = gradFill self.pattFill = pattFill if ln is None: ln = LineProperties() self.ln = ln self.custGeom = custGeom self.prstGeom = prstGeom self.scene3d = scene3d self.sp3d = sp3d ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/stock_chart.py0000644000000000000000000000312400000000000016125 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import ( Typed, Sequence, Alias, ) from openpyxl.descriptors.excel import ExtensionList from ._chart import ChartBase from .axis import TextAxis, NumericAxis, ChartLines from .updown_bars import UpDownBars from .label import DataLabelList from .series import Series class StockChart(ChartBase): tagname = "stockChart" ser = Sequence(expected_type=Series) #min 3, max4 dLbls = Typed(expected_type=DataLabelList, allow_none=True) dataLabels = Alias('dLbls') dropLines = Typed(expected_type=ChartLines, allow_none=True) hiLowLines = Typed(expected_type=ChartLines, allow_none=True) upDownBars = Typed(expected_type=UpDownBars, allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) x_axis = Typed(expected_type=TextAxis) y_axis = Typed(expected_type=NumericAxis) _series_type = "line" __elements__ = ('ser', 'dLbls', 'dropLines', 'hiLowLines', 'upDownBars', 'axId') def __init__(self, ser=(), dLbls=None, dropLines=None, hiLowLines=None, upDownBars=None, extLst=None, **kw ): self.ser = ser self.dLbls = dLbls self.dropLines = dropLines self.hiLowLines = hiLowLines self.upDownBars = upDownBars self.x_axis = TextAxis() self.y_axis = NumericAxis() super(StockChart, self).__init__(**kw) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/surface_chart.py0000644000000000000000000000561300000000000016437 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import ( Typed, Integer, Bool, Alias, Sequence, ) from openpyxl.descriptors.excel import ExtensionList from openpyxl.descriptors.nested import ( NestedInteger, NestedBool, ) from ._chart import ChartBase from ._3d import _3DBase from .axis import TextAxis, NumericAxis, SeriesAxis from .shapes import GraphicalProperties from .series import Series class BandFormat(Serialisable): tagname = "bandFmt" idx = NestedInteger() spPr = Typed(expected_type=GraphicalProperties, allow_none=True) graphicalProperties = Alias("spPr") __elements__ = ('idx', 'spPr') def __init__(self, idx=0, spPr=None, ): self.idx = idx self.spPr = spPr class BandFormatList(Serialisable): tagname = "bandFmts" bandFmt = Sequence(expected_type=BandFormat, allow_none=True) __elements__ = ('bandFmt',) def __init__(self, bandFmt=(), ): self.bandFmt = bandFmt class _SurfaceChartBase(ChartBase): wireframe = NestedBool(allow_none=True) ser = Sequence(expected_type=Series, allow_none=True) bandFmts = Typed(expected_type=BandFormatList, allow_none=True) _series_type = "surface" __elements__ = ('wireframe', 'ser', 'bandFmts') def __init__(self, wireframe=None, ser=(), bandFmts=None, **kw ): self.wireframe = wireframe self.ser = ser self.bandFmts = bandFmts super(_SurfaceChartBase, self).__init__(**kw) class SurfaceChart3D(_SurfaceChartBase, _3DBase): tagname = "surface3DChart" wireframe = _SurfaceChartBase.wireframe ser = _SurfaceChartBase.ser bandFmts = _SurfaceChartBase.bandFmts extLst = Typed(expected_type=ExtensionList, allow_none=True) x_axis = Typed(expected_type=TextAxis) y_axis = Typed(expected_type=NumericAxis) z_axis = Typed(expected_type=SeriesAxis) __elements__ = _SurfaceChartBase.__elements__ + ('axId',) def __init__(self, **kw): self.x_axis = TextAxis() self.y_axis = NumericAxis() self.z_axis = SeriesAxis() super(SurfaceChart3D, self).__init__(**kw) class SurfaceChart(SurfaceChart3D): tagname = "surfaceChart" wireframe = _SurfaceChartBase.wireframe ser = _SurfaceChartBase.ser bandFmts = _SurfaceChartBase.bandFmts extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = SurfaceChart3D.__elements__ def __init__(self, **kw): super(SurfaceChart, self).__init__(**kw) self.y_axis.delete = True self.view3D.x_rotation = 90 self.view3D.y_rotation = 0 self.view3D.perspective = False self.view3D.right_angle_axes = False ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/__init__.py0000644000000000000000000000000000000000000016510 0ustar00././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/conftest.py0000644000000000000000000000044200000000000016610 0ustar00# Fixtures (pre-configured objects) for tests import pytest @pytest.fixture def datadir(): """DATADIR as a LocalPath""" import os from py._path.local import LocalPath here = os.path.split(__file__)[0] DATADIR = os.path.join(here, "data") return LocalPath(DATADIR) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/data/3D_bar_chart.xml0000644000000000000000000000437300000000000020326 0ustar00 Sheet1!$B$1 Sheet1!$A$2:$A$4 Sheet1!$B$2:$B$4 Sheet1!$C$1 Sheet1!$A$2:$A$4 Sheet1!$C$2:$C$4 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/data/3D_plotarea.xml0000644000000000000000000000542000000000000020202 0ustar00 Splines!$D$76 Splines!$C$78:$C$82 Splines!$D$77:$D$81 Splines!$E$76 Splines!$C$78:$C$82 Splines!$E$77:$E$81 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/data/bubblechart_plot_area.xml0000644000000000000000000006567500000000000022372 0ustar00 Data!$O$3 Data!$D$3 Data!$J$3 Data!$F$3 Data!$O$4 Data!$D$4 Data!$J$4 Data!$F$4 Data!$O$5 Data!$D$5 Data!$J$5 Data!$F$5 Data!$O$6 Data!$D$6 Data!$J$6 Data!$F$6 Data!$O$7 Data!$D$7 Data!$J$7 Data!$F$7 Data!$O$8 Data!$D$8 Data!$J$8 Data!$F$8 Data!$O$9 Data!$D$9 Data!$J$9 Data!$F$9 Data!$O$10 Data!$D$10 Data!$J$10 Data!$F$10 Data!$O$11 Data!$D$11 Data!$J$11 Data!$F$11 Data!$O$12 Data!$D$12 Data!$J$12 Data!$F$12 Data!$O$13 Data!$D$13 Data!$J$13 Data!$F$13 Data!$O$14 Data!$D$14 Data!$J$14 Data!$F$14 <tx> <rich> <a:bodyPr/> <a:lstStyle/> <a:p> <a:pPr> <a:defRPr sz="1000" b="1" i="0" u="none" strike="noStrike" baseline="0"> <a:solidFill> <a:srgbClr val="000000"/> </a:solidFill> <a:latin typeface="Calibri"/> <a:ea typeface="Calibri"/> <a:cs typeface="Calibri"/> </a:defRPr> </a:pPr> <a:r> <a:rPr lang="en-US"/> <a:t>Group</a:t> </a:r> </a:p> </rich> </tx> <layout> <manualLayout> <xMode val="edge"/> <yMode val="edge"/> <x val="0.48046927492216868"/> <y val="0.8207804507195221"/> </manualLayout> </layout> <overlay val="0"/> <spPr> <a:noFill/> <a:ln w="25400"> <a:noFill/> </a:ln> </spPr> <tx> <rich> <a:bodyPr/> <a:lstStyle/> <a:p> <a:pPr> <a:defRPr sz="1000" b="1" i="0" u="none" strike="noStrike" baseline="0"> <a:solidFill> <a:srgbClr val="000000"/> </a:solidFill> <a:latin typeface="Calibri"/> <a:ea typeface="Calibri"/> <a:cs typeface="Calibri"/> </a:defRPr> </a:pPr> <a:r> <a:rPr lang="en-US"/> <a:t>Blah (%) *</a:t> </a:r> </a:p> </rich> </tx> <layout> <manualLayout> <xMode val="edge"/> <yMode val="edge"/> <x val="2.3437479845920227E-2"/> <y val="0.33506554439315772"/> </manualLayout> </layout> <overlay val="0"/> <spPr> <a:noFill/> <a:ln w="25400"> <a:noFill/> </a:ln> </spPr> ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/data/chart1.xml0000644000000000000000000010471200000000000017233 0ustar00 [files.xlsx]PIVOT!PivotTable1 Website Performance onLoad!$A$2 Bob onLoad!$B$1:$M$1 d\-mmm\-yy 42186.0 42200.0 42217.0 42231.0 42248.0 42262.0 42292.0 42309.0 42323.0 42339.0 42353.0 onLoad!$B$2:$L$2 General 9436.0 14389.0 12502.0 13691.0 9337.0 12471.0 13671.0 14200.0 12755.0 20353.0 12489.0 onLoad!$A$3 Alice onLoad!$B$1:$M$1 d\-mmm\-yy 42186.0 42200.0 42217.0 42231.0 42248.0 42262.0 42292.0 42309.0 42323.0 42339.0 42353.0 onLoad!$B$3:$L$3 General 4382.0 4628.0 5439.0 6077.0 6849.0 5164.0 5611.0 10239.0 5391.0 4200.0 6908.0 onLoad!$A$4 Eve onLoad!$B$1:$M$1 d\-mmm\-yy 42186.0 42200.0 42217.0 42231.0 42248.0 42262.0 42292.0 42309.0 42323.0 42339.0 42353.0 onLoad!$B$4:$L$4 General 9404.0 9277.0 8842.0 9193.0 12849.0 9408.0 6985.0 8376.0 6589.0 5326.0 9380.0 onLoad!$A$5 Charles onLoad!$B$1:$M$1 d\-mmm\-yy 42186.0 42200.0 42217.0 42231.0 42248.0 42262.0 42292.0 42309.0 42323.0 42339.0 42353.0 onLoad!$B$5:$L$5 General 8669.0 12775.0 18881.0 13008.0 11672.0 9092.0 9427.0 11328.0 8308.0 11606.0 8685.0 onLoad!$A$6 Sam onLoad!$B$1:$M$1 d\-mmm\-yy 42186.0 42200.0 42217.0 42231.0 42248.0 42262.0 42292.0 42309.0 42323.0 42339.0 42353.0 onLoad!$B$6:$L$6 General 3126.0 3451.0 2007.0 6498.0 4327.0 3840.0 3420.0 4437.0 3700.0 4167.0 4065.0 onLoad!$A$7 June onLoad!$B$1:$M$1 d\-mmm\-yy 42186.0 42200.0 42217.0 42231.0 42248.0 42262.0 42292.0 42309.0 42323.0 42339.0 42353.0 onLoad!$B$7:$L$7 General 12337.0 13909.0 12156.0 11869.0 11810.0 14288.0 12644.0 12912.0 12048.0 13620.0 14090.0 onLoad!$A$8 Roger onLoad!$B$1:$M$1 d\-mmm\-yy 42186.0 42200.0 42217.0 42231.0 42248.0 42262.0 42292.0 42309.0 42323.0 42339.0 42353.0 onLoad!$B$8:$L$8 General 10492.0 7541.0 6503.0 57700.0 9235.0 10934.0 12223.0 9639.0 42414.0 11192.0 onLoad!$A$9 Helen onLoad!$B$1:$M$1 d\-mmm\-yy 42186.0 42200.0 42217.0 42231.0 42248.0 42262.0 42292.0 42309.0 42323.0 42339.0 42353.0 onLoad!$B$9:$L$9 General 19456.0 16247.0 18118.0 17689.0 15583.0 16092.0 16477.0 18264.0 16444.0 16336.0 15730.0 onLoad!$A$10 Dave onLoad!$B$1:$M$1 d\-mmm\-yy 42186.0 42200.0 42217.0 42231.0 42248.0 42262.0 42292.0 42309.0 42323.0 42339.0 42353.0 onLoad!$B$10:$L$10 General 8456.0 9263.0 9469.0 7756.0 8322.0 10372.0 8305.0 10749.0 10780.0 16264.0 11250.0 onLoad!$A$11 Charlotte onLoad!$B$1:$M$1 d\-mmm\-yy 42186.0 42200.0 42217.0 42231.0 42248.0 42262.0 42292.0 42309.0 42323.0 42339.0 42353.0 onLoad!$B$11:$L$11 General 10411.0 9473.0 9610.0 12045.0 7571.0 9756.0 9004.0 9871.0 15782.0 20767.0 8120.0 Time in seconds ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/data/plotarea.xml0000644000000000000000000000756600000000000017671 0ustar00 OXM!$F$10 OXM!$B$11:$B$29 OXM!$F$11:$F$29 OXM!$G$10 OXM!$B$11:$B$29 OXM!$G$11:$G$29 <tx> <rich> <a:bodyPr rot="-5400000" vert="horz"/> <a:lstStyle/> <a:p> <a:pPr> <a:defRPr/> </a:pPr> <a:r> <a:rPr lang="en-US"/> <a:t>Panel Sales</a:t> </a:r> </a:p> </rich> </tx> <layout/> <overlay val="0"/> <tx> <rich> <a:bodyPr rot="-5400000" vert="horz"/> <a:lstStyle/> <a:p> <a:pPr> <a:defRPr/> </a:pPr> <a:r> <a:rPr lang="en-US"/> <a:t>Revenue ($MM)</a:t> </a:r> </a:p> </rich> </tx> <layout/> <overlay val="0"/> ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/data/scatterchart_plot_area.xml0000644000000000000000000001062600000000000022566 0ustar00 C_File_Calculations!$K$56 C_File_Calculations!$C$58:$C$64 C_File_Calculations!$K$58:$K$64 <tx> <rich> <a:bodyPr/> <a:lstStyle/> <a:p> <a:pPr> <a:defRPr/> </a:pPr> <a:r> <a:rPr lang="en-CA"/> <a:t>Concentration (mg/L)</a:t> </a:r> </a:p> </rich> </tx> <layout/> <overlay val="0"/> <tx> <rich> <a:bodyPr rot="-5400000" vert="horz"/> <a:lstStyle/> <a:p> <a:pPr> <a:defRPr/> </a:pPr> <a:r> <a:rPr lang="en-CA" baseline="0"/> <a:t> Absorbance (AU)</a:t> </a:r> <a:endParaRPr lang="en-CA"/> </a:p> </rich> </tx> <layout/> <overlay val="0"/> ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_3d.py0000644000000000000000000000517400000000000016337 0ustar00from __future__ import absolute_import # Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import tostring, fromstring from openpyxl.tests.helper import compare_xml @pytest.fixture def View3D(): from .._3d import View3D return View3D class TestView3D: def test_ctor(self, View3D): view = View3D() xml = tostring(view.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, View3D): src = """ """ node = fromstring(src) view = View3D.from_tree(node) assert view == View3D(rotX=15, rotY=20, rAngAx=False, perspective=30) @pytest.fixture def Surface(): from .._3d import Surface return Surface class TestSurface: def test_ctor(self, Surface): surface = Surface(thickness=0) xml = tostring(surface.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, Surface): src = """ """ node = fromstring(src) surface = Surface.from_tree(node) assert surface == Surface(thickness=0) @pytest.fixture def _3DBase(): from .._3d import _3DBase return _3DBase class TestSurface: def test_ctor(self, _3DBase): base = _3DBase() xml = tostring(base.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, _3DBase): src = """ """ node = fromstring(src) base = _3DBase.from_tree(node) assert base == _3DBase() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_area_chart.py0000644000000000000000000001102200000000000020107 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml from .. import Series @pytest.fixture def AreaChart(): from ..area_chart import AreaChart return AreaChart class TestAreaChart: def test_ctor(self, AreaChart): chart = AreaChart() xml = tostring(chart.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, AreaChart): src = """ """ node = fromstring(src) chart = AreaChart.from_tree(node) assert chart == AreaChart(grouping="percentStacked", varyColors=True) def test_write(self, AreaChart): s1 = Series(values="Sheet1!$A$1:$A$12") s2 = Series(values="Sheet1!$B$1:$B$12") chart = AreaChart(ser=[s1, s2]) xml = tostring(chart._write()) expected = """ 'Sheet1'!$A$1:$A$12 'Sheet1'!$B$1:$B$12 """ diff = compare_xml(xml, expected) assert diff is None, diff @pytest.fixture def AreaChart3D(): from ..area_chart import AreaChart3D return AreaChart3D class TestAreaChart3D: def test_ctor(self, AreaChart3D): chart = AreaChart3D() xml = tostring(chart.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, AreaChart3D): src = """ """ node = fromstring(src) chart = AreaChart3D.from_tree(node) assert chart == AreaChart3D(gapDepth=150) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_axis.py0000644000000000000000000002214500000000000016772 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import tostring, fromstring from openpyxl.tests.helper import compare_xml @pytest.fixture def Scaling(): from ..axis import Scaling return Scaling class TestScale: def test_ctor(self, Scaling): scale = Scaling() xml = tostring(scale.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, Scaling): xml = """ """ node = fromstring(xml) scale = Scaling.from_tree(node) assert scale == Scaling(logBase=10) @pytest.fixture def _BaseAxis(): from ..axis import _BaseAxis return _BaseAxis class TestAxis: def test_ctor(self, _BaseAxis, Scaling): axis = _BaseAxis(axId=10, crossAx=100) xml = tostring(axis.to_tree(tagname="baseAxis")) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff @pytest.fixture def TextAxis(): from ..axis import TextAxis return TextAxis class TestTextAxis: def test_ctor(self, TextAxis): axis = TextAxis(axId=10, crossAx=100) xml = tostring(axis.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, TextAxis): src = """ """ node = fromstring(src) axis = TextAxis.from_tree(node) assert axis.scaling.orientation == "minMax" assert axis.auto is True assert axis.majorTickMark == "out" assert axis.minorTickMark is None assert axis.crossesAt == 30 @pytest.fixture def NumericAxis(): from ..axis import NumericAxis return NumericAxis class TestValAx: def test_ctor(self, NumericAxis): axis = NumericAxis(axId=100, crossAx=10) xml = tostring(axis.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, NumericAxis): src = """ """ node = fromstring(src) axis = NumericAxis.from_tree(node) assert axis.delete is False assert axis.crossAx == 2065276984 assert axis.crossBetween == "between" assert axis.scaling.logBase == 10 @pytest.fixture def DateAxis(): from ..axis import DateAxis return DateAxis class TestDateAx: def test_ctor(self, DateAxis): axis = DateAxis(axId=500, crossAx=10) xml = tostring(axis.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, DateAxis): from openpyxl.chart.data_source import NumFmt src = """ """ node = fromstring(src) axis = DateAxis.from_tree(node) assert axis == DateAxis(axId=20, crossAx=10, axPos="b", delete=False, numFmt=NumFmt("d-mmm", True), majorTickMark="out", crosses="autoZero", tickLblPos="nextTo", auto=True, lblOffset=100, baseTimeUnit="months") @pytest.fixture def SeriesAxis(): from ..axis import SeriesAxis return SeriesAxis class TestSeriesAxis: def test_ctor(self, SeriesAxis): axis = SeriesAxis(axId=1000, crossAx=10) xml = tostring(axis.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, SeriesAxis): src = """ """ node = fromstring(src) axis = SeriesAxis.from_tree(node) assert axis == SeriesAxis() @pytest.fixture def DisplayUnitsLabel(): from ..axis import DisplayUnitsLabel return DisplayUnitsLabel class TestDispUnitsLabel: def test_ctor(self, DisplayUnitsLabel): axis = DisplayUnitsLabel() xml = tostring(axis.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, DisplayUnitsLabel): src = """ """ node = fromstring(src) axis = DisplayUnitsLabel.from_tree(node) assert axis == DisplayUnitsLabel() @pytest.fixture def DisplayUnitsLabelList(): from ..axis import DisplayUnitsLabelList return DisplayUnitsLabelList class TestDisplayUnitList: def test_ctor(self, DisplayUnitsLabelList): axis = DisplayUnitsLabelList() xml = tostring(axis.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, DisplayUnitsLabelList): src = """ """ node = fromstring(src) axis = DisplayUnitsLabelList.from_tree(node) assert axis == DisplayUnitsLabelList() @pytest.fixture def ChartLines(): from ..axis import ChartLines return ChartLines class TestChartLines: def test_ctor(self, ChartLines): axis = ChartLines() xml = tostring(axis.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, ChartLines): src = """ """ node = fromstring(src) axis = ChartLines.from_tree(node) assert axis == ChartLines() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_bar_chart.py0000644000000000000000000001233600000000000017754 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import tostring, fromstring from openpyxl.tests.helper import compare_xml @pytest.fixture def BarChart(): from ..bar_chart import BarChart return BarChart class TestBarChart: def test_ctor(self, BarChart): bc = BarChart() xml = tostring(bc.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_tree(self, BarChart): src = """ """ node = fromstring(src) bc = BarChart.from_tree(node) assert bc == BarChart(varyColors=False,axId=(10, 100)) assert bc.axId == [10, 100] assert bc.grouping == "clustered" def test_write(self, BarChart): chart = BarChart() xml = tostring(chart._write()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_series(self, BarChart): from .. import Series s1 = Series(values="Sheet1!$A$1:$A$10") s2 = Series(values="Sheet1!$B$1:$B$10") bc = BarChart(ser=[s1, s2]) xml = tostring(bc.to_tree()) expected = """ 'Sheet1'!$A$1:$A$10 'Sheet1'!$B$1:$B$10 """ diff = compare_xml(xml, expected) assert diff is None, diff @pytest.fixture def BarChart3D(): from ..bar_chart import BarChart3D return BarChart3D class TestBarChart3D: def test_ctor(self, BarChart3D): bc = BarChart3D() assert hasattr(bc.view3D, 'rotX') xml = tostring(bc.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, BarChart3D): src = """ """ node = fromstring(src) bc = BarChart3D.from_tree(node) assert bc.axId == [10, 100, 0] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_bubble_chart.py0000644000000000000000000000162500000000000020442 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml @pytest.fixture def BubbleChart(): from ..bubble_chart import BubbleChart return BubbleChart class TestBubbleChart: def test_ctor(self, BubbleChart): bubble_chart = BubbleChart() xml = tostring(bubble_chart.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, BubbleChart): src = """ """ node = fromstring(src) bubble_chart = BubbleChart.from_tree(node) assert bubble_chart.axId == [10, 20] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_chart.py0000644000000000000000000001362100000000000017126 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import tostring from openpyxl.tests.helper import compare_xml from ..chartspace import PlotArea from ..pivot import PivotSource, PivotFormat from ..series import Series @pytest.fixture def ChartBase(): from .._chart import ChartBase return ChartBase class TestChartBase: def test_ctor(self, ChartBase): chart = ChartBase() with pytest.raises(NotImplementedError): xml = tostring(chart.to_tree()) def test_iadd(self, ChartBase): chart1 = ChartBase() chart2 = ChartBase() chart1 += chart2 assert chart1._charts == [chart1, chart2] def test_invalid_add(self, ChartBase): chart = ChartBase() s = Series() with pytest.raises(TypeError): chart += s def test_set_catgories(self, ChartBase): from ..series import Series s1 = Series() s1.__elements__ = ('cat',) chart = ChartBase() chart.ser = [s1] chart.set_categories("Sheet!A1:A4") xml = tostring(s1.to_tree()) expected = """ 'Sheet'!$A$1:$A$4 """ diff = compare_xml(xml, expected) assert diff is None, diff def test_add_data_cols(self, ChartBase): chart = ChartBase() chart.ser = [] chart.add_data("Sheet!A1:E4") assert len(chart.ser) == 5 assert chart.ser[0].val.numRef.f == "'Sheet'!$A$1:$A$4" assert chart.ser[-1].val.numRef.f == "'Sheet'!$E$1:$E$4" def test_add_data_rows(self, ChartBase): chart = ChartBase() chart.ser = [] chart.add_data("Sheet!A1:E4", from_rows=True) assert len(chart.ser) == 4 assert chart.ser[0].val.numRef.f == "'Sheet'!$A$1:$E$1" assert chart.ser[-1].val.numRef.f == "'Sheet'!$A$4:$E$4" def test_hash_function(self, ChartBase): chart = ChartBase() assert hash(chart) == hash(id(chart)) def test_path(self, ChartBase): chart = ChartBase() assert chart.path == "/xl/charts/chart1.xml" def test_plot_area(self, ChartBase): chart = ChartBase() assert type(chart.plot_area) is PlotArea def test_save_twice(self, ChartBase): ChartBase.tagname = "DummyChart" chart = ChartBase() chart._write() chart._write() area = chart.plot_area assert len(area._charts) == 1 assert area._axes == [] def test_axIds(self, ChartBase): chart = ChartBase() assert chart.axId == [] def test_plot_visible_cells(self, ChartBase): chart = ChartBase() assert chart.visible_cells_only is True def test_plot_visible_cells(self, ChartBase): chart = ChartBase() chart.visible_cells_only = False tree = chart._write() expected = """ """ xml = tostring(tree) diff = compare_xml(xml, expected) assert diff is None, diff def test_pivot_source(self, ChartBase): chart = ChartBase() chart.pivotSource = PivotSource(name="some pivot", fmtId=5) expected = """ some pivot """ tree = chart._write() xml = tostring(tree) diff = compare_xml(xml, expected) assert diff is None, diff def test_pivot_format(self, ChartBase): chart = ChartBase() fmt = PivotFormat() chart.pivotFormats = [fmt] expected = """ """ tree = chart._write() xml = tostring(tree) diff = compare_xml(xml, expected) assert diff is None, diff def test_reindex(self, ChartBase): chart = ChartBase() chart.ser = [] chart.add_data("Sheet!D1:D4") chart.add_data("Sheet!B1:B4") chart.add_data("Sheet!C1:C4") chart.add_data("Sheet!A1:A4") orders = [40, 20, 34, 11] for o, s in zip(orders, chart.series): s.order = o ordered = [s.order for s in chart.series] assert ordered == [40, 20, 34, 11] chart._reindex() reordered = [s.order for s in chart.series] assert reordered == [0, 1, 2, 3] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_chartspace.py0000644000000000000000000000613200000000000020141 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml @pytest.fixture def ChartContainer(): from ..chartspace import ChartContainer return ChartContainer class TestChartContainer: def test_ctor(self, ChartContainer): container = ChartContainer() xml = tostring(container.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, ChartContainer): src = """ """ node = fromstring(src) container = ChartContainer.from_tree(node) assert container == ChartContainer() @pytest.fixture def Protection(): from ..chartspace import Protection return Protection class TestProtection: def test_ctor(self, Protection): prot = Protection() xml = tostring(prot.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, Protection): src = """ """ node = fromstring(src) prot = Protection.from_tree(node) assert prot == Protection(chartObject=True) @pytest.fixture def ExternalData(): from ..chartspace import ExternalData return ExternalData class TestExternalData: def test_ctor(self, ExternalData): data = ExternalData(id='rId1') xml = tostring(data.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, ExternalData): src = """ """ node = fromstring(src) data = ExternalData.from_tree(node) assert data == ExternalData(id="rId1") @pytest.fixture def ChartSpace(): from ..chartspace import ChartSpace return ChartSpace class TestChartSpace: def test_ctor(self, ChartSpace, ChartContainer): cs = ChartSpace(chart=ChartContainer()) xml = tostring(cs.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, ChartSpace, ChartContainer): src = """ """ node = fromstring(src) cs = ChartSpace.from_tree(node) assert cs == ChartSpace(chart=ChartContainer()) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_data_source.py0000644000000000000000000001432400000000000020317 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import tostring, fromstring from openpyxl.tests.helper import compare_xml @pytest.fixture def NumRef(): from ..data_source import NumRef return NumRef class TestNumRef: def test_from_xml(self, NumRef): src = """ Blatt1!$A$1:$A$12 """ node = fromstring(src) num = NumRef.from_tree(node) assert num.ref == "Blatt1!$A$1:$A$12" def test_to_xml(self, NumRef): num = NumRef(f="Blatt1!$A$1:$A$12") xml = tostring(num.to_tree("numRef")) expected = """ Blatt1!$A$1:$A$12 """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_tree_degree_sign(self, NumRef): src = b""" Hoja1!$A$2:$B$2 0\xc2\xb0 3 14 """ node = fromstring(src) numRef = NumRef.from_tree(node) assert numRef.numCache.formatCode == u"0\xb0" @pytest.fixture def StrRef(): from ..data_source import StrRef return StrRef class TestStrRef: def test_ctor(self, StrRef): data_source = StrRef(f="Sheet1!A1") xml = tostring(data_source.to_tree()) expected = """ Sheet1!A1 """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, StrRef): src = """ 'Render Start'!$A$2 """ node = fromstring(src) data_source = StrRef.from_tree(node) assert data_source == StrRef(f="'Render Start'!$A$2") @pytest.fixture def StrVal(): from ..data_source import StrVal return StrVal class TestStrVal: def test_ctor(self, StrVal): val = StrVal(v="something") xml = tostring(val.to_tree()) expected = """ something """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, StrVal): src = """ else """ node = fromstring(src) val = StrVal.from_tree(node) assert val == StrVal(idx=4, v="else") @pytest.fixture def StrData(): from ..data_source import StrData return StrData class TestStrData: def test_ctor(self, StrData): data_source = StrData(ptCount=1) xml = tostring(data_source.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, StrData): src = """ """ node = fromstring(src) data_source = StrData.from_tree(node) assert data_source == StrData(ptCount=4) @pytest.fixture def Level(): from ..data_source import Level return Level class TestLevel: def test_ctor(self, Level): level = Level() xml = tostring(level.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, Level): src = """ """ node = fromstring(src) level = Level.from_tree(node) assert level == Level() @pytest.fixture def MultiLevelStrData(): from ..data_source import MultiLevelStrData return MultiLevelStrData class TestMultiLevelStrData: def test_ctor(self, MultiLevelStrData): multidata = MultiLevelStrData() xml = tostring(multidata.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, MultiLevelStrData): src = """ """ node = fromstring(src) multidata = MultiLevelStrData.from_tree(node) assert multidata == MultiLevelStrData() @pytest.fixture def MultiLevelStrRef(): from ..data_source import MultiLevelStrRef return MultiLevelStrRef class TestMultiLevelStrRef: def test_ctor(self, MultiLevelStrRef): multiref = MultiLevelStrRef(f="Sheet1!$A$1:$B$10") xml = tostring(multiref.to_tree()) expected = """ Sheet1!$A$1:$B$10 """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, MultiLevelStrRef): src = """ Sheet1!$A$1:$B$10 """ node = fromstring(src) multiref = MultiLevelStrRef.from_tree(node) assert multiref == MultiLevelStrRef(f="Sheet1!$A$1:$B$10") @pytest.fixture def AxDataSource(): from ..data_source import AxDataSource return AxDataSource class TestAxDataSource: def test_ctor(self, AxDataSource, StrRef): dummy = StrRef(f="") ax = AxDataSource(strRef=dummy) xml = tostring(ax.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_no_source(self, AxDataSource): with pytest.raises(TypeError): ax = AxDataSource() def test_from_xml(self, AxDataSource, StrRef): src = """ """ node = fromstring(src) dummy = StrRef() ax = AxDataSource.from_tree(node) assert ax == AxDataSource(strRef=dummy) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_error_bar.py0000644000000000000000000000201400000000000017774 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml @pytest.fixture def ErrorBars(): from ..error_bar import ErrorBars return ErrorBars class TestErrorBar: def test_ctor(self, ErrorBars): bar = ErrorBars() xml = tostring(bar.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, ErrorBars): src = """ """ node = fromstring(src) bar = ErrorBars.from_tree(node) assert bar == ErrorBars(noEndCap=True, errDir='x', val=10) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_label.py0000644000000000000000000000347100000000000017106 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import tostring, fromstring from openpyxl.tests.helper import compare_xml @pytest.fixture def DataLabelList(): from ..label import DataLabelList return DataLabelList class TestDataLabeList: def test_ctor(self, DataLabelList): labels = DataLabelList(numFmt="0.0%") xml = tostring(labels.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, DataLabelList): src = """ """ node = fromstring(src) dl = DataLabelList.from_tree(node) assert dl.showLegendKey is False assert dl.showVal is False assert dl.showCatName is False assert dl.showSerName is False assert dl.showPercent is False assert dl.showBubbleSize is False @pytest.fixture def DataLabel(): from ..label import DataLabel return DataLabel class TestDataLabel: def test_ctor(self, DataLabel): label = DataLabel() xml = tostring(label.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, DataLabel): src = """ """ node = fromstring(src) label = DataLabel.from_tree(node) assert label == DataLabel(idx=6) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_layout.py0000644000000000000000000000400400000000000017335 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml @pytest.fixture def ManualLayout(): from ..layout import ManualLayout return ManualLayout class TestManualLayout: def test_ctor(self, ManualLayout): layout = ManualLayout( layoutTarget="inner", xMode="edge", yMode="factor", wMode="factor", hMode="edge", x=.1, y=.5, w=.5, h=.1 ) xml = tostring(layout.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, ManualLayout): src = """ """ node = fromstring(src) layout = ManualLayout.from_tree(node) assert layout == ManualLayout(layoutTarget="inner", xMode="edge", yMode="factor", wMode="factor", hMode="edge", x=.1, y=.5, w=.5, h=.1 ) class TestLayout: def test_ctor(self): from ..layout import Layout layout = Layout() xml = tostring(layout.to_tree()) diff = compare_xml(xml, "") assert diff is None, diff ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_legend.py0000644000000000000000000000273500000000000017267 0ustar00 # Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml @pytest.fixture def Legend(): from ..legend import Legend return Legend class TestLegend: def test_ctor(self, Legend): legend = Legend() xml = tostring(legend.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, Legend): src = """ """ node = fromstring(src) legend = Legend.from_tree(node) assert legend == Legend() @pytest.fixture def LegendEntry(): from ..legend import LegendEntry return LegendEntry class TestLegendEntry: def test_ctor(self, LegendEntry): legend = LegendEntry(idx=0, delete=True) xml = tostring(legend.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, LegendEntry): src = """ """ node = fromstring(src) legend = LegendEntry.from_tree(node) assert legend == LegendEntry() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_line_chart.py0000644000000000000000000000367100000000000020141 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml @pytest.fixture def LineChart(): from ..line_chart import LineChart return LineChart class TestLineChart: def test_ctor(self, LineChart): chart = LineChart() xml = tostring(chart.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, LineChart): src = """ """ node = fromstring(src) chart = LineChart.from_tree(node) assert chart.axId == [10, 100] assert chart.grouping == "stacked" def test_axes(self, LineChart): chart = LineChart() assert set(chart._axes) == set([10, 100]) @pytest.fixture def LineChart3D(): from ..line_chart import LineChart3D return LineChart3D class TestLineChart3D: def test_ctor(self, LineChart3D): line_chart = LineChart3D() xml = tostring(line_chart.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, LineChart3D): src = """ """ node = fromstring(src) line_chart = LineChart3D.from_tree(node) assert line_chart == LineChart3D() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_marker.py0000644000000000000000000000375300000000000017313 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml @pytest.fixture def Marker(): from ..marker import Marker return Marker class TestMarker: def test_ctor(self, Marker): marker = Marker(symbol=None, size=5) xml = tostring(marker.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, Marker): src = """ """ node = fromstring(src) marker = Marker.from_tree(node) assert marker == Marker(symbol="square", size=5) @pytest.fixture def DataPoint(): from ..marker import DataPoint return DataPoint class TestDataPoint: def test_ctor(self, DataPoint): dp = DataPoint(idx=9) xml = tostring(dp.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, DataPoint): src = """ """ node = fromstring(src) dp = DataPoint.from_tree(node) assert dp.idx == 9 assert dp.bubble3D is False ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_picture.py0000644000000000000000000000140500000000000017475 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml @pytest.fixture def PictureOptions(): from ..picture import PictureOptions return PictureOptions class TestPictureOptions: def test_ctor(self, PictureOptions): picture = PictureOptions() xml = tostring(picture.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, PictureOptions): src = """ """ node = fromstring(src) picture = PictureOptions.from_tree(node) assert picture == PictureOptions() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_pie_chart.py0000644000000000000000000001054100000000000017761 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml @pytest.fixture def PieChart(): from ..pie_chart import PieChart return PieChart class TestPieChart: def test_ctor(self, PieChart): chart = PieChart() xml = tostring(chart.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, PieChart): src = """ """ node = fromstring(src) chart = PieChart.from_tree(node) assert dict(chart) == {} assert chart.varyColors is True assert chart.firstSliceAng == 60 @pytest.fixture def PieChart3D(): from ..pie_chart import PieChart3D return PieChart3D class TestPieChart3D: def test_ctor(self, PieChart3D): chart = PieChart3D() xml = tostring(chart.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff @pytest.fixture def DoughnutChart(): from ..pie_chart import DoughnutChart return DoughnutChart class TestDoughnutChart: def test_ctor(self, DoughnutChart): chart = DoughnutChart() xml = tostring(chart.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, DoughnutChart): src = """ """ node = fromstring(src) chart = DoughnutChart.from_tree(node) assert dict(chart) == {} assert chart.firstSliceAng == 0 assert chart.holeSize == 50 @pytest.fixture def ProjectedPieChart(): from ..pie_chart import ProjectedPieChart return ProjectedPieChart class TestProjectedPieChart: def test_ctor(self, ProjectedPieChart): chart = ProjectedPieChart() xml = tostring(chart.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, ProjectedPieChart): src = """ """ node = fromstring(src) chart = ProjectedPieChart.from_tree(node) assert dict(chart) == {} assert chart.gapWidth == 150 assert chart.secondPieSize == 75 @pytest.fixture def CustomSplit(): from ..pie_chart import CustomSplit return CustomSplit class TestCustomSplit: def test_ctor(self, CustomSplit): pie_chart = CustomSplit([1, 2, 3]) xml = tostring(pie_chart.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, CustomSplit): src = """ """ node = fromstring(src) pie_chart = CustomSplit.from_tree(node) assert pie_chart == CustomSplit([1, 2]) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_pivot.py0000644000000000000000000000331700000000000017167 0ustar00from __future__ import absolute_import # Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml @pytest.fixture def PivotSource(): from ..pivot import PivotSource return PivotSource class TestPivotSource: def test_ctor(self, PivotSource): fut = PivotSource(name="[template.xlsx]PIVOT!PivotTable6", fmtId=0) xml = tostring(fut.to_tree()) expected = """ [template.xlsx]PIVOT!PivotTable6 """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, PivotSource): src = """ [template.xlsx]PIVOT!PivotTable6 """ node = fromstring(src) fut = PivotSource.from_tree(node) assert fut == PivotSource(name="[template.xlsx]PIVOT!PivotTable6", fmtId=0) @pytest.fixture def PivotFormat(): from ..pivot import PivotFormat return PivotFormat class TestPivotFormat: def test_ctor(self, PivotFormat): fmt = PivotFormat() xml = tostring(fmt.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, PivotFormat): src = """ """ node = fromstring(src) fmt = PivotFormat.from_tree(node) assert fmt == PivotFormat() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_plotarea.py0000644000000000000000000001324300000000000017634 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml from ..line_chart import LineChart from ..bar_chart import BarChart @pytest.fixture def PlotArea(): from ..plotarea import PlotArea return PlotArea class TestPlotArea: def test_ctor(self, PlotArea): plot = PlotArea() xml = tostring(plot.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, PlotArea): src = """ """ node = fromstring(src) plot = PlotArea.from_tree(node) assert plot == PlotArea() def test_multi_chart(self, PlotArea): plot = PlotArea() plot.lineChart = LineChart() plot.barChart = BarChart() plot.lineChart = LineChart() expected = """ """ xml = tostring(plot.to_tree()) diff = compare_xml(xml, expected) assert diff is None, diff def test_read_multi_chart(self, PlotArea, datadir): datadir.chdir() with open("plotarea.xml", "rb") as src: tree = fromstring(src.read()) plot = PlotArea.from_tree(tree) assert len(plot._charts) == 2 def test_read_multi_axes(self, PlotArea, datadir): datadir.chdir() with open("plotarea.xml", "rb") as src: tree = fromstring(src.read()) plot = PlotArea.from_tree(tree) assert [ax.tagname for ax in plot._axes] == ["catAx", "valAx", "valAx", "catAx"] assert plot._charts[0].x_axis == plot._axes[0] assert plot._charts[0].y_axis == plot._axes[1] assert plot._charts[1].x_axis == plot._axes[3] assert plot._charts[1].y_axis == plot._axes[2] def test_read_scatter_chart(self, PlotArea, datadir): datadir.chdir() with open("scatterchart_plot_area.xml", "rb") as src: tree = fromstring(src.read()) plot = PlotArea.from_tree(tree) chart = plot._charts[0] assert chart.axId == [211326240, 211330000] assert chart.x_axis.axId == 211326240 assert chart.y_axis.axId == 211330000 def test_read_bubble_chart(self, PlotArea, datadir): datadir.chdir() with open("bubblechart_plot_area.xml", "rb") as src: tree = fromstring(src.read()) plot = PlotArea.from_tree(tree) chart = plot._charts[0] assert chart.axId == [196911488, 196913408] assert chart.x_axis.axId == 196911488 assert chart.y_axis.axId == 196913408 def test_read_surface_chart_3d(self, PlotArea, datadir): datadir.chdir() with open("3D_plotarea.xml", "rb") as src: tree = fromstring(src.read()) plot = PlotArea.from_tree(tree) chart = plot._charts[0] assert chart.axId == [10, 100, 1000] assert chart.tagname == "surface3DChart" def test_read_bar_chart_3d(self, PlotArea, datadir): datadir.chdir() with open("3D_bar_chart.xml", "rb") as src: tree = fromstring(src.read()) plot = PlotArea.from_tree(tree) chart = plot._charts[0] assert chart.axId == [203780744, 203656728, 0] assert chart.tagname == "bar3DChart" assert chart.z_axis.crossAx == 203780744 def test_read_bar_chart_3d_no_series_axis(self, PlotArea, datadir): datadir.chdir() with open("3D_bar_chart.xml", "rb") as src: tree = fromstring(src.read()) s = tree.find("serAx") tree.remove(s) plot = PlotArea.from_tree(tree) chart = plot._charts[0] assert chart.axId == [203780744, 203656728, 0] assert chart.tagname == "bar3DChart" assert chart.z_axis is None @pytest.fixture def DataTable(): from ..plotarea import DataTable return DataTable class TestDataTable: def test_ctor(self, DataTable): table = DataTable() xml = tostring(table.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, DataTable): src = """ """ node = fromstring(src) table = DataTable.from_tree(node) assert table == DataTable() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_print.py0000644000000000000000000000267300000000000017166 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml @pytest.fixture def PrintSettings(): from ..print_settings import PrintSettings return PrintSettings class TestPrintSettings: def test_ctor(self, PrintSettings): chartspace = PrintSettings() xml = tostring(chartspace.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, PrintSettings): src = """ """ node = fromstring(src) chartspace = PrintSettings.from_tree(node) assert chartspace == PrintSettings() @pytest.fixture def PageMargins(): from ..print_settings import PageMargins return PageMargins class TestPageMargins: def test_ctor(self, PageMargins): pm = PageMargins() xml = tostring(pm.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, PageMargins): src = """ """ node = fromstring(src) pm = PageMargins.from_tree(node) assert pm == PageMargins() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_radar_chart.py0000644000000000000000000000211000000000000020266 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml @pytest.fixture def RadarChart(): from ..radar_chart import RadarChart return RadarChart class TestRadarChart: def test_ctor(self, RadarChart): chart = RadarChart() xml = tostring(chart.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, RadarChart): src = """ """ node = fromstring(src) chart = RadarChart.from_tree(node) assert dict(chart) == {} assert chart.type == "marker" assert chart.axId == [2107159976, 2107207992] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_reader.py0000644000000000000000000000247500000000000017274 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.xml.functions import fromstring from .. bar_chart import BarChart from .. line_chart import LineChart from .. axis import NumericAxis, DateAxis from .. chartspace import ChartSpace, ChartContainer def test_read(datadir): datadir.chdir() from .. reader import read_chart with open("chart1.xml") as src: xml = src.read() tree = fromstring(xml) cs = ChartSpace.from_tree(tree) chart = read_chart(cs) assert isinstance(chart, LineChart) assert chart.title.tx.rich.p[0].r[0].t == "Website Performance" assert chart.display_blanks == "span" assert isinstance(chart.y_axis, NumericAxis) assert chart.y_axis.title.tx.rich.p[0].r[0].t == "Time in seconds" assert isinstance(chart.x_axis, DateAxis) assert chart.x_axis.title is None assert len(chart.series) == 10 assert chart.pivotSource.name == "[files.xlsx]PIVOT!PivotTable1" assert len(chart.pivotFormats) == 1 assert chart.idx_base == 0 def test_read_chart_with_no_series(): container = ChartContainer() cs = ChartSpace(chart=container) cs.chart.plotArea.barChart = BarChart() from ..reader import read_chart chart = read_chart(cs) assert isinstance(chart, BarChart) assert len(chart.series) == 0 assert chart.idx_base == 0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_reference.py0000644000000000000000000000500600000000000017761 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest @pytest.fixture def Reference(): from ..reference import Reference return Reference @pytest.fixture def Worksheet(): class DummyWorksheet: def __init__(self, title="dummy"): self.title = title return DummyWorksheet class TestReference: def test_ctor(self, Reference, Worksheet): ref = Reference( worksheet=Worksheet(), min_col=1, min_row=1, max_col=10, max_row=12 ) assert str(ref) == "'dummy'!$A$1:$J$12" def test_single_cell(self, Reference, Worksheet): ref = Reference(Worksheet(), min_col=1, min_row=1) assert str(ref) == "'dummy'!$A$1" def test_from_string(self, Reference): ref = Reference(range_string="'Sheet1'!$A$1:$A$10") assert (ref.min_col, ref.min_row, ref.max_col, ref.max_row) == (1,1, 1,10) assert str(ref) == "'Sheet1'!$A$1:$A$10" def test_cols(self, Reference): ref = Reference(range_string="Sheet!A1:B2") assert list(ref.cols) == [ Reference(range_string="Sheet!A1:A2"), Reference(range_string="Sheet!B1:B2") ] def test_rows(self, Reference): ref = Reference(range_string="Sheet!A1:B2") assert list(ref.rows) == [ Reference(range_string="Sheet!A1:B1"), Reference(range_string="Sheet!A2:B2") ] @pytest.mark.parametrize("range_string, cell, min_col, min_row", [ ("Sheet1!A1:A10", 'A1', 1, 2), ("Sheet!A1:E1", 'A1', 2, 1), ] ) def test_pop(self, Reference, range_string, cell, min_col, min_row): ref = Reference(range_string=range_string) assert cell == ref.pop() assert (ref.min_col, ref.min_row) == (min_col, min_row) @pytest.mark.parametrize("range_string, length", [ ("Sheet1!A1:A10", 10), ("Sheet!A1:E1", 5), ] ) def test_length(self, Reference, range_string, length): ref = Reference(range_string=range_string) assert len(ref) == length def test_repr(self, Reference): ref = Reference(range_string=b"'D\xc3\xbcsseldorf'!A1:A10".decode("utf8")) assert str(ref) == b"'D\xc3\xbcsseldorf'!$A$1:$A$10".decode("utf8") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_scatter_chart.py0000644000000000000000000000163200000000000020652 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml @pytest.fixture def ScatterChart(): from ..scatter_chart import ScatterChart return ScatterChart class TestScatterChart: def test_ctor(self, ScatterChart): chart = ScatterChart() xml = tostring(chart.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, ScatterChart): src = """ """ node = fromstring(src) chart = ScatterChart.from_tree(node) assert chart.axId == [10, 20] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_series.py0000644000000000000000000002122400000000000017315 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import tostring, fromstring from openpyxl.tests.helper import compare_xml class TestBarSer: def test_from_tree(self): from ..series import Series, attribute_mapping src = """ Blatt1!$A$1:$A$12 """ node = fromstring(src) ser = Series.from_tree(node) assert ser.idx == 0 assert ser.order == 0 assert ser.val.numRef.ref == 'Blatt1!$A$1:$A$12' ser.__elements__ = attribute_mapping['bar'] xml = tostring(ser.to_tree()) diff = compare_xml(xml, src) assert diff is None, diff class TestAreaSer: def test_from_tree(self): from ..series import Series, attribute_mapping src = """ Blatt1!$A$1:$A$12 """ node = fromstring(src) ser = Series.from_tree(node) assert ser.idx == 0 assert ser.order == 0 assert ser.val.numRef.ref == 'Blatt1!$A$1:$A$12' ser.__elements__ = attribute_mapping['area'] xml = tostring(ser.to_tree()) diff = compare_xml(xml, src) assert diff is None, diff class TestBubbleSer: def test_from_tree(self): from ..series import Series, attribute_mapping src = """ Blatt1!$A$1:$A$12 Blatt1!$B$1:$B$12 General 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 """ node = fromstring(src) ser = Series.from_tree(node) assert ser.idx == 0 assert ser.order == 0 assert ser.xVal.numRef.ref == 'Blatt1!$A$1:$A$12' assert ser.yVal.numRef.ref == 'Blatt1!$B$1:$B$12' assert ser.bubbleSize.numLit.ptCount == 12 assert ser.bubbleSize.numLit.pt[0].v == 1.1 ser.__elements__ = attribute_mapping['bubble'] xml = tostring(ser.to_tree()) diff = compare_xml(xml, src) assert diff is None, diff class TestPieSer: def test_from_tree(self): from ..series import Series, attribute_mapping src = """ Blatt1!$A$1:$A$12 """ node = fromstring(src) ser = Series.from_tree(node) assert ser.idx == 0 assert ser.order == 0 assert ser.val.numRef.ref == 'Blatt1!$A$1:$A$12' ser.__elements__ = attribute_mapping['pie'] xml = tostring(ser.to_tree()) diff = compare_xml(xml, src) assert diff is None, diff class TestRadarSer: def test_from_tree(self): from ..series import Series, attribute_mapping src = """ Blatt1!$A$1:$A$12 """ node = fromstring(src) ser = Series.from_tree(node) assert ser.idx == 0 assert ser.order == 0 assert ser.val.numRef.ref == 'Blatt1!$A$1:$A$12' ser.__elements__ = attribute_mapping['radar'] xml = tostring(ser.to_tree()) diff = compare_xml(xml, src) assert diff is None, diff class TestScatterSer: def test_from_tree(self): from ..series import Series, attribute_mapping src = """ Blatt1!$A$1:$A$12 Blatt1!$B$1:$B$12 """ node = fromstring(src) ser = Series.from_tree(node) assert ser.idx == 0 assert ser.order == 0 assert ser.xVal.numRef.ref == 'Blatt1!$A$1:$A$12' assert ser.yVal.numRef.ref == 'Blatt1!$B$1:$B$12' ser.__elements__ = attribute_mapping['scatter'] xml = tostring(ser.to_tree()) diff = compare_xml(xml, src) assert diff is None, diff class TestSurfaceSer: def test_from_tree(self): from ..series import Series, attribute_mapping src = """ Blatt1!$A$1:$A$12 """ node = fromstring(src) ser = Series.from_tree(node) assert ser.idx == 0 assert ser.order == 0 assert ser.val.numRef.ref == 'Blatt1!$A$1:$A$12' ser.__elements__ = attribute_mapping['surface'] xml = tostring(ser.to_tree()) diff = compare_xml(xml, src) assert diff is None, diff @pytest.fixture def SeriesLabel(): from ..series import SeriesLabel return SeriesLabel class TestSeriesLabel: def test_ctor(self, SeriesLabel): label = SeriesLabel(v="Label") xml = tostring(label.to_tree()) expected = """ Label """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, SeriesLabel): src = """ Label """ node = fromstring(src) label = SeriesLabel.from_tree(node) assert label == SeriesLabel(v="Label") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_series_factory.py0000644000000000000000000000723600000000000021053 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import tostring from openpyxl.tests.helper import compare_xml @pytest.fixture def Series(): from ..series_factory import SeriesFactory return SeriesFactory class TestSeriesFactory: def test_ctor(self, Series): series = Series(values="Sheet1!$A$1:$A$10") series.__elements__ = ('idx', 'order', 'val') xml = tostring(series.to_tree()) expected = """ 'Sheet1'!$A$1:$A$10 """ diff = compare_xml(xml, expected) assert diff is None, diff def test_manual_idx(self, Series): series = Series(values="Sheet1!$A$1:$A$10") series.__elements__ = ('idx', 'order', 'val') xml = tostring(series.to_tree(idx=5)) expected = """ 'Sheet1'!$A$1:$A$10 """ diff = compare_xml(xml, expected) assert diff is None, diff def test_manual_order(self, Series): series = Series(values="Sheet1!$A$1:$A$10") series.order = 2 series.__elements__ = ('idx', 'order', 'val') xml = tostring(series.to_tree(idx=5)) expected = """ 'Sheet1'!$A$1:$A$10 """ diff = compare_xml(xml, expected) assert diff is None, diff def test_title(self, Series): series = Series("Sheet1!A1:A10", title="First Series") series.__elements__ = ('idx', 'order', 'tx') xml = tostring(series.to_tree(idx=0)) expected = """ First Series """ diff = compare_xml(xml, expected) assert diff is None, diff def test_title_from_data(self, Series): series = Series("Sheet1!A1:A10", title_from_data=True) series.__elements__ = ('tx', 'val') xml = tostring(series.to_tree(idx=0)) expected = """ 'Sheet1'!A1 'Sheet1'!$A$2:$A$10 """ diff = compare_xml(xml, expected) assert diff is None, diff def test_xy(self, Series): from ..series import XYSeries series = Series("Sheet!A1:A10", xvalues="Sheet!B1:B10") assert isinstance(series, XYSeries) def test_zvalues(self, Series): series = Series("Sheet!A2:A5", xvalues="Sheet!B2:B5", zvalues="Sheet!C2:C5") series.__elements__ = ('xVal', 'yVal', 'bubbleSize') xml = tostring(series.to_tree()) expected = """ 'Sheet'!$B$2:$B$5 'Sheet'!$A$2:$A$5 'Sheet'!$C$2:$C$5 """ diff = compare_xml(xml, expected) assert diff is None, diff ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_shapes.py0000644000000000000000000000250600000000000017310 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml @pytest.fixture def GraphicalProperties(): from ..shapes import GraphicalProperties return GraphicalProperties class TestShapeProperties: def test_ctor(self, GraphicalProperties): shapes = GraphicalProperties() xml = tostring(shapes.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, GraphicalProperties): src = """ """ node = fromstring(src) shapes = GraphicalProperties.from_tree(node) assert dict(shapes) == {} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_stock_chart.py0000644000000000000000000000436700000000000020340 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml @pytest.fixture def StockChart(): from ..stock_chart import StockChart return StockChart class TestStockChart: def test_ctor(self, StockChart): from openpyxl.chart.series import Series chart = StockChart(ser=[Series(), Series(), Series()]) xml = tostring(chart.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, StockChart): src = """ """ node = fromstring(src) chart = StockChart.from_tree(node) assert chart.axId == [10, 100] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_surface_chart.py0000644000000000000000000000740700000000000020643 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml @pytest.fixture def SurfaceChart(): from ..surface_chart import SurfaceChart return SurfaceChart class TestSurfaceChart: def test_ctor(self, SurfaceChart): chart = SurfaceChart() xml = tostring(chart.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, SurfaceChart): src = """ """ node = fromstring(src) chart = SurfaceChart.from_tree(node) assert chart.axId == [2086876920, 2078923400, 2079274408] @pytest.fixture def SurfaceChart3D(): from ..surface_chart import SurfaceChart3D return SurfaceChart3D class TestSurfaceChart3D: def test_ctor(self, SurfaceChart3D): chart = SurfaceChart3D() xml = tostring(chart.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, SurfaceChart3D): src = """ Blatt1!$A$1:$A$12 Blatt1!$B$1:$B$12 """ node = fromstring(src) chart = SurfaceChart3D.from_tree(node) assert len(chart.ser) == 2 assert chart.axId == [2082935272, 2082938248, 2082941288] @pytest.fixture def BandFormat(): from ..surface_chart import BandFormat return BandFormat class TestBandFormat: def test_ctor(self, BandFormat): fmt = BandFormat() xml = tostring(fmt.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, BandFormat): src = """ """ node = fromstring(src) fmt = BandFormat.from_tree(node) assert fmt == BandFormat(idx=4) @pytest.fixture def BandFormatList(): from ..surface_chart import BandFormatList return BandFormatList class TestBandFormatList: def test_ctor(self, BandFormatList): fmt = BandFormatList() xml = tostring(fmt.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, BandFormatList): src = """ """ node = fromstring(src) fmt = BandFormatList.from_tree(node) assert fmt == BandFormatList() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_text.py0000644000000000000000000000403700000000000017012 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml @pytest.fixture def RichText(): from ..text import RichText return RichText class TestRichText: def test_ctor(self, RichText): text = RichText() xml = tostring(text.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, RichText): src = """ """ node = fromstring(src) text = RichText.from_tree(node) assert text == RichText() @pytest.fixture def Text(): from ..text import Text return Text from ..title import title_maker from ..data_source import StrRef class TestText: def test_ctor(self, Text): tx = Text() tx.strRef = StrRef(f="Sheet1!$A$1") xml = tostring(tx.to_tree()) expected = """ Sheet1!$A$1 """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, Text): src = """ Sheet1!$A$1 """ node = fromstring(src) tx = Text.from_tree(node) assert tx == Text(strRef=StrRef(f="Sheet1!$A$1")) def test_only_one(self, Text): title = title_maker("Chart title") tx = Text() tx.strRef = StrRef(f="Sheet1!$A$1") tx.rich = title.tx.rich expected = """ Sheet1!$A$1 """ xml = tostring(tx.to_tree()) diff = compare_xml(xml, expected) assert diff is None, diff ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_title.py0000644000000000000000000000353000000000000017144 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml @pytest.fixture def Title(): from ..title import Title return Title class TestTitle: def test_ctor(self, Title): title = Title() xml = tostring(title.to_tree()) expected = """ <tx> <rich> <a:bodyPr></a:bodyPr> <a:p> <a:r> <a:t /> </a:r> </a:p> </rich> </tx> """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, Title): src = """ """ node = fromstring(src) title = Title.from_tree(node) assert title == Title() def test_title_maker(): """ Create a title element from a string preserving line breaks. """ from ..title import title_maker text = "Two-line\nText" title = title_maker(text) xml = tostring(title.to_tree()) expected = """ <title xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"> <tx> <rich> <a:bodyPr /> <a:p> <a:pPr> <a:defRPr /> </a:pPr> <a:r> <a:t>Two-line</a:t> </a:r> </a:p> <a:p> <a:pPr> <a:defRPr /> </a:pPr> <a:r> <a:t>Text</a:t> </a:r> </a:p> </rich> </tx> """ diff = compare_xml(xml, expected) assert diff is None, diff ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_trendline.py0000644000000000000000000000275100000000000020013 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml @pytest.fixture def TrendlineLabel(): from ..trendline import TrendlineLabel return TrendlineLabel class TestTrendlineLabel: def test_ctor(self, TrendlineLabel): trendline = TrendlineLabel() xml = tostring(trendline.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, TrendlineLabel): src = """ """ node = fromstring(src) trendline = TrendlineLabel.from_tree(node) assert trendline == TrendlineLabel() @pytest.fixture def Trendline(): from ..trendline import Trendline return Trendline class TestTrendline: def test_ctor(self, Trendline): trendline = Trendline() xml = tostring(trendline.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, Trendline): src = """ """ node = fromstring(src) trendline = Trendline.from_tree(node) assert trendline == Trendline(trendlineType="log") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/tests/test_updown_bars.py0000644000000000000000000000150600000000000020347 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml @pytest.fixture def UpDownBars(): from ..updown_bars import UpDownBars return UpDownBars class TestUpDownBars: def test_ctor(self, UpDownBars): bars = UpDownBars(gapWidth=150) xml = tostring(bars.to_tree()) expected = """ """ diff = compare_xml(xml, expected) assert diff is None, diff def test_from_xml(self, UpDownBars): src = """ """ node = fromstring(src) bars = UpDownBars.from_tree(node) assert bars == UpDownBars(gapWidth=156) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/text.py0000644000000000000000000000350100000000000014604 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import ( Typed, Alias, Sequence, ) from openpyxl.drawing.text import ( RichTextProperties, ListStyle, Paragraph, ) from .data_source import StrRef class RichText(Serialisable): """ From the specification: 21.2.2.216 This element specifies text formatting. The lstStyle element is not supported. """ tagname = "rich" bodyPr = Typed(expected_type=RichTextProperties) properties = Alias("bodyPr") lstStyle = Typed(expected_type=ListStyle, allow_none=True) p = Sequence(expected_type=Paragraph) paragraphs = Alias('p') __elements__ = ("bodyPr", "lstStyle", "p") def __init__(self, bodyPr=None, lstStyle=None, p=None, ): if bodyPr is None: bodyPr = RichTextProperties() self.bodyPr = bodyPr self.lstStyle = lstStyle if p is None: p = [Paragraph()] self.p = p class Text(Serialisable): """ The value can be either a cell reference or a text element If both are present then the reference will be used. """ tagname = "tx" strRef = Typed(expected_type=StrRef, allow_none=True) rich = Typed(expected_type=RichText, allow_none=True) __elements__ = ("strRef", "rich") def __init__(self, strRef=None, rich=None ): self.strRef = strRef if rich is None: rich = RichText() self.rich = rich def to_tree(self, tagname=None, idx=None, namespace=None): if self.strRef and self.rich: self.rich = None # can only have one return super(Text, self).to_tree(tagname, idx, namespace) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/title.py0000644000000000000000000000366500000000000014754 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import ( Typed, Alias, ) from openpyxl.descriptors.excel import ExtensionList from openpyxl.descriptors.nested import NestedBool from .text import Text, RichText from .layout import Layout from .shapes import GraphicalProperties from openpyxl.drawing.text import ( Paragraph, RegularTextRun, LineBreak, ParagraphProperties, CharacterProperties, ) class Title(Serialisable): tagname = "title" tx = Typed(expected_type=Text, allow_none=True) text = Alias('tx') layout = Typed(expected_type=Layout, allow_none=True) overlay = NestedBool(allow_none=True) spPr = Typed(expected_type=GraphicalProperties, allow_none=True) graphicalProperties = Alias('spPr') txPr = Typed(expected_type=RichText, allow_none=True) body = Alias('txPr') extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('tx', 'layout', 'overlay', 'spPr', 'txPr') def __init__(self, tx=None, layout=None, overlay=None, spPr=None, txPr=None, extLst=None, ): if tx is None: tx = Text() self.tx = tx self.layout = layout self.overlay = overlay self.spPr = spPr self.txPr = txPr def title_maker(text): title = Title() paraprops = ParagraphProperties() paraprops.defRPr = CharacterProperties() paras = [Paragraph(r=[RegularTextRun(t=s)], pPr=paraprops) for s in text.split("\n")] title.tx.rich.paragraphs = paras return title class TitleDescriptor(Typed): expected_type = Title allow_none = True def __set__(self, instance, value): if isinstance(value, str): value = title_maker(value) super(TitleDescriptor, self).__set__(instance, value) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/trendline.py0000644000000000000000000000575500000000000015621 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import ( Typed, String, Alias ) from openpyxl.descriptors.excel import ExtensionList from openpyxl.descriptors.nested import ( NestedBool, NestedInteger, NestedFloat, NestedSet ) from .data_source import NumFmt from .shapes import GraphicalProperties from .text import RichText, Text from .layout import Layout class TrendlineLabel(Serialisable): tagname = "trendlineLbl" layout = Typed(expected_type=Layout, allow_none=True) tx = Typed(expected_type=Text, allow_none=True) numFmt = Typed(expected_type=NumFmt, allow_none=True) spPr = Typed(expected_type=GraphicalProperties, allow_none=True) graphicalProperties = Alias("spPr") txPr = Typed(expected_type=RichText, allow_none=True) textProperties = Alias("txPr") extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('layout', 'tx', 'numFmt', 'spPr', 'txPr') def __init__(self, layout=None, tx=None, numFmt=None, spPr=None, txPr=None, extLst=None, ): self.layout = layout self.tx = tx self.numFmt = numFmt self.spPr = spPr self.txPr = txPr class Trendline(Serialisable): tagname = "trendline" name = String(allow_none=True) spPr = Typed(expected_type=GraphicalProperties, allow_none=True) graphicalProperties = Alias('spPr') trendlineType = NestedSet(values=(['exp', 'linear', 'log', 'movingAvg', 'poly', 'power'])) order = NestedInteger(allow_none=True) period = NestedInteger(allow_none=True) forward = NestedFloat(allow_none=True) backward = NestedFloat(allow_none=True) intercept = NestedFloat(allow_none=True) dispRSqr = NestedBool(allow_none=True) dispEq = NestedBool(allow_none=True) trendlineLbl = Typed(expected_type=TrendlineLabel, allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('name', 'spPr', 'trendlineType', 'order', 'period', 'forward', 'backward', 'intercept', 'dispRSqr', 'dispEq', 'trendlineLbl') def __init__(self, name=None, spPr=None, trendlineType='linear', order=None, period=None, forward=None, backward=None, intercept=None, dispRSqr=None, dispEq=None, trendlineLbl=None, extLst=None, ): self.name = name self.spPr = spPr self.trendlineType = trendlineType self.order = order self.period = period self.forward = forward self.backward = backward self.intercept = intercept self.dispRSqr = dispRSqr self.dispEq = dispEq self.trendlineLbl = trendlineLbl ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chart/updown_bars.py0000644000000000000000000000160100000000000016142 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import Typed from openpyxl.descriptors.excel import ExtensionList from .shapes import GraphicalProperties from .axis import ChartLines from .descriptors import NestedGapAmount class UpDownBars(Serialisable): tagname = "upbars" gapWidth = NestedGapAmount() upBars = Typed(expected_type=ChartLines, allow_none=True) downBars = Typed(expected_type=ChartLines, allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('gapWidth', 'upBars', 'downBars') def __init__(self, gapWidth=150, upBars=None, downBars=None, extLst=None, ): self.gapWidth = gapWidth self.upBars = upBars self.downBars = downBars ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chartsheet/__init__.py0000644000000000000000000000010700000000000016407 0ustar00# Copyright (c) 2010-2021 openpyxl from .chartsheet import Chartsheet ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chartsheet/chartsheet.py0000644000000000000000000000771200000000000017013 0ustar00# Copyright (c) 2010-2021 openpyxl from weakref import ref from openpyxl.descriptors import Typed, Set, Alias from openpyxl.descriptors.excel import ExtensionList from openpyxl.descriptors.serialisable import Serialisable from openpyxl.drawing.spreadsheet_drawing import ( AbsoluteAnchor, SpreadsheetDrawing, ) from openpyxl.worksheet.page import ( PageMargins, PrintPageSetup ) from openpyxl.packaging.relationship import Relationship, RelationshipList from openpyxl.worksheet.drawing import Drawing from openpyxl.worksheet.header_footer import HeaderFooter from openpyxl.workbook.child import _WorkbookChild from openpyxl.xml.constants import SHEET_MAIN_NS, REL_NS from .relation import DrawingHF, SheetBackgroundPicture from .properties import ChartsheetProperties from .protection import ChartsheetProtection from .views import ChartsheetViewList from .custom import CustomChartsheetViews from .publish import WebPublishItems class Chartsheet(_WorkbookChild, Serialisable): tagname = "chartsheet" _default_title = "Chart" _rel_type = "chartsheet" _path = "/xl/chartsheets/sheet{0}.xml" mime_type = "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml" sheetPr = Typed(expected_type=ChartsheetProperties, allow_none=True) sheetViews = Typed(expected_type=ChartsheetViewList) sheetProtection = Typed(expected_type=ChartsheetProtection, allow_none=True) customSheetViews = Typed(expected_type=CustomChartsheetViews, allow_none=True) pageMargins = Typed(expected_type=PageMargins, allow_none=True) pageSetup = Typed(expected_type=PrintPageSetup, allow_none=True) drawing = Typed(expected_type=Drawing, allow_none=True) drawingHF = Typed(expected_type=DrawingHF, allow_none=True) picture = Typed(expected_type=SheetBackgroundPicture, allow_none=True) webPublishItems = Typed(expected_type=WebPublishItems, allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) sheet_state = Set(values=('visible', 'hidden', 'veryHidden')) headerFooter = Typed(expected_type=HeaderFooter) HeaderFooter = Alias('headerFooter') __elements__ = ( 'sheetPr', 'sheetViews', 'sheetProtection', 'customSheetViews', 'pageMargins', 'pageSetup', 'headerFooter', 'drawing', 'drawingHF', 'picture', 'webPublishItems') __attrs__ = () def __init__(self, sheetPr=None, sheetViews=None, sheetProtection=None, customSheetViews=None, pageMargins=None, pageSetup=None, headerFooter=None, drawing=None, drawingHF=None, picture=None, webPublishItems=None, extLst=None, parent=None, title="", sheet_state='visible', ): super(Chartsheet, self).__init__(parent, title) self._charts = [] self.sheetPr = sheetPr if sheetViews is None: sheetViews = ChartsheetViewList() self.sheetViews = sheetViews self.sheetProtection = sheetProtection self.customSheetViews = customSheetViews self.pageMargins = pageMargins self.pageSetup = pageSetup if headerFooter is not None: self.headerFooter = headerFooter self.drawing = Drawing("rId1") self.drawingHF = drawingHF self.picture = picture self.webPublishItems = webPublishItems self.sheet_state = sheet_state def add_chart(self, chart): chart.anchor = AbsoluteAnchor() self._charts.append(chart) def to_tree(self): self._drawing = SpreadsheetDrawing() self._drawing.charts = self._charts tree = super(Chartsheet, self).to_tree() if not self.headerFooter: el = tree.find('headerFooter') tree.remove(el) tree.set("xmlns", SHEET_MAIN_NS) return tree ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chartsheet/custom.py0000644000000000000000000000323300000000000016165 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.worksheet.header_footer import HeaderFooter from openpyxl.descriptors import ( Bool, Integer, Set, Typed, Sequence ) from openpyxl.descriptors.excel import Guid from openpyxl.descriptors.serialisable import Serialisable from openpyxl.worksheet.page import ( PageMargins, PrintPageSetup ) class CustomChartsheetView(Serialisable): tagname = "customSheetView" guid = Guid() scale = Integer() state = Set(values=(['visible', 'hidden', 'veryHidden'])) zoomToFit = Bool(allow_none=True) pageMargins = Typed(expected_type=PageMargins, allow_none=True) pageSetup = Typed(expected_type=PrintPageSetup, allow_none=True) headerFooter = Typed(expected_type=HeaderFooter, allow_none=True) __elements__ = ('pageMargins', 'pageSetup', 'headerFooter') def __init__(self, guid=None, scale=None, state='visible', zoomToFit=None, pageMargins=None, pageSetup=None, headerFooter=None, ): self.guid = guid self.scale = scale self.state = state self.zoomToFit = zoomToFit self.pageMargins = pageMargins self.pageSetup = pageSetup self.headerFooter = headerFooter class CustomChartsheetViews(Serialisable): tagname = "customSheetViews" customSheetView = Sequence(expected_type=CustomChartsheetView, allow_none=True) __elements__ = ('customSheetView',) def __init__(self, customSheetView=None, ): self.customSheetView = customSheetView ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chartsheet/properties.py0000644000000000000000000000124700000000000017052 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors import ( Bool, String, Typed ) from openpyxl.descriptors.serialisable import Serialisable from openpyxl.styles import Color class ChartsheetProperties(Serialisable): tagname = "sheetPr" published = Bool(allow_none=True) codeName = String(allow_none=True) tabColor = Typed(expected_type=Color, allow_none=True) __elements__ = ('tabColor',) def __init__(self, published=None, codeName=None, tabColor=None, ): self.published = published self.codeName = codeName self.tabColor = tabColor ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chartsheet/protection.py0000644000000000000000000000236100000000000017042 0ustar00import hashlib from openpyxl.descriptors import (Bool, Integer, String) from openpyxl.descriptors.excel import Base64Binary from openpyxl.descriptors.serialisable import Serialisable from openpyxl.worksheet.protection import ( hash_password, _Protected ) class ChartsheetProtection(Serialisable, _Protected): tagname = "sheetProtection" algorithmName = String(allow_none=True) hashValue = Base64Binary(allow_none=True) saltValue = Base64Binary(allow_none=True) spinCount = Integer(allow_none=True) content = Bool(allow_none=True) objects = Bool(allow_none=True) __attrs__ = ("content", "objects", "password", "hashValue", "spinCount", "saltValue", "algorithmName") def __init__(self, content=None, objects=None, hashValue=None, spinCount=None, saltValue=None, algorithmName=None, password=None, ): self.content = content self.objects = objects self.hashValue = hashValue self.spinCount = spinCount self.saltValue = saltValue self.algorithmName = algorithmName if password is not None: self.password = password ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chartsheet/publish.py0000644000000000000000000000306300000000000016322 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors import ( Bool, Integer, String, Set, Sequence ) from openpyxl.descriptors.serialisable import Serialisable class WebPublishItem(Serialisable): tagname = "webPublishItem" id = Integer() divId = String() sourceType = Set(values=(['sheet', 'printArea', 'autoFilter', 'range', 'chart', 'pivotTable', 'query', 'label'])) sourceRef = String() sourceObject = String(allow_none=True) destinationFile = String() title = String(allow_none=True) autoRepublish = Bool(allow_none=True) def __init__(self, id=None, divId=None, sourceType=None, sourceRef=None, sourceObject=None, destinationFile=None, title=None, autoRepublish=None, ): self.id = id self.divId = divId self.sourceType = sourceType self.sourceRef = sourceRef self.sourceObject = sourceObject self.destinationFile = destinationFile self.title = title self.autoRepublish = autoRepublish class WebPublishItems(Serialisable): tagname = "WebPublishItems" count = Integer(allow_none=True) webPublishItem = Sequence(expected_type=WebPublishItem, ) __elements__ = ('webPublishItem',) def __init__(self, count=None, webPublishItem=None, ): self.count = len(webPublishItem) self.webPublishItem = webPublishItem ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chartsheet/relation.py0000644000000000000000000000525300000000000016474 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors import ( Integer, Alias ) from openpyxl.descriptors.excel import Relation from openpyxl.descriptors.serialisable import Serialisable class SheetBackgroundPicture(Serialisable): tagname = "picture" id = Relation() def __init__(self, id): self.id = id class DrawingHF(Serialisable): id = Relation() lho = Integer(allow_none=True) leftHeaderOddPages = Alias('lho') lhe = Integer(allow_none=True) leftHeaderEvenPages = Alias('lhe') lhf = Integer(allow_none=True) leftHeaderFirstPage = Alias('lhf') cho = Integer(allow_none=True) centerHeaderOddPages = Alias('cho') che = Integer(allow_none=True) centerHeaderEvenPages = Alias('che') chf = Integer(allow_none=True) centerHeaderFirstPage = Alias('chf') rho = Integer(allow_none=True) rightHeaderOddPages = Alias('rho') rhe = Integer(allow_none=True) rightHeaderEvenPages = Alias('rhe') rhf = Integer(allow_none=True) rightHeaderFirstPage = Alias('rhf') lfo = Integer(allow_none=True) leftFooterOddPages = Alias('lfo') lfe = Integer(allow_none=True) leftFooterEvenPages = Alias('lfe') lff = Integer(allow_none=True) leftFooterFirstPage = Alias('lff') cfo = Integer(allow_none=True) centerFooterOddPages = Alias('cfo') cfe = Integer(allow_none=True) centerFooterEvenPages = Alias('cfe') cff = Integer(allow_none=True) centerFooterFirstPage = Alias('cff') rfo = Integer(allow_none=True) rightFooterOddPages = Alias('rfo') rfe = Integer(allow_none=True) rightFooterEvenPages = Alias('rfe') rff = Integer(allow_none=True) rightFooterFirstPage = Alias('rff') def __init__(self, id=None, lho=None, lhe=None, lhf=None, cho=None, che=None, chf=None, rho=None, rhe=None, rhf=None, lfo=None, lfe=None, lff=None, cfo=None, cfe=None, cff=None, rfo=None, rfe=None, rff=None, ): self.id = id self.lho = lho self.lhe = lhe self.lhf = lhf self.cho = cho self.che = che self.chf = chf self.rho = rho self.rhe = rhe self.rhf = rhf self.lfo = lfo self.lfe = lfe self.lff = lff self.cfo = cfo self.cfe = cfe self.cff = cff self.rfo = rfo self.rfe = rfe self.rff = rff ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chartsheet/tests/__init__.py0000644000000000000000000000000000000000000017541 0ustar00././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chartsheet/tests/test_chartsheet.py0000644000000000000000000000606000000000000021207 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.worksheet.drawing import Drawing from openpyxl.worksheet.page import PageMargins from ..views import ChartsheetView, ChartsheetViewList from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml import pytest class DummyWorkbook: def __init__(self): self.sheetnames = [] self._charts = [] @pytest.fixture def Chartsheet(): from ..chartsheet import Chartsheet return Chartsheet class TestChartsheet: def test_ctor(self, Chartsheet): cs = Chartsheet(parent=DummyWorkbook()) assert cs.title == "Chart" def test_read(self, Chartsheet): src = """ """ xml = fromstring(src) chart = Chartsheet.from_tree(xml) assert chart.pageMargins.left == 0.7 assert chart.sheetViews.sheetView[0].tabSelected == True def test_write(self, Chartsheet): sheetview = ChartsheetView(tabSelected=True, zoomScale=80, workbookViewId=0, zoomToFit=True) chartsheetViews = ChartsheetViewList(sheetView=[sheetview]) pageMargins = PageMargins(left=0.7, right=0.7, top=0.75, bottom=0.75, header=0.3, footer=0.3) drawing = Drawing("rId1") item = Chartsheet(sheetViews=chartsheetViews, pageMargins=pageMargins, drawing=drawing) expected = """ """ xml = tostring(item.to_tree()) diff = compare_xml(xml, expected) assert diff is None, diff def test_write_charts(self, Chartsheet): class DummyChart: pass cs = Chartsheet(parent=DummyWorkbook()) cs.add_chart(DummyChart()) expected = """ """ xml = tostring(cs.to_tree()) diff = compare_xml(xml, expected) assert diff is None, diff ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chartsheet/tests/test_custom.py0000644000000000000000000001103000000000000020360 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.worksheet.page import PageMargins from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml @pytest.fixture def CustomChartsheetView(): from ..custom import CustomChartsheetView return CustomChartsheetView class TestCustomChartsheetView: def test_read(self, CustomChartsheetView): src = """ """ xml = fromstring(src) customChartsheetView = CustomChartsheetView.from_tree(xml) assert customChartsheetView.state == 'visible' assert customChartsheetView.scale == 88 assert customChartsheetView.pageMargins.left == 0.23622047244094491 def test_write(self, CustomChartsheetView): pageMargins = PageMargins(left=0.2362204724409449, right=0.2362204724409449, top=0.7480314960629921, bottom=0.7480314960629921, header=0.3149606299212598, footer=0.3149606299212598) customChartsheetView = CustomChartsheetView(guid="{C43F44F8-8CE9-4A07-A9A9-0646C7C6B826}", scale=88, zoomToFit=1, pageMargins=pageMargins) expected = """ """ xml = tostring(customChartsheetView.to_tree()) diff = compare_xml(xml, expected) assert diff is None, diff @pytest.fixture def CustomChartsheetViews(): from ..custom import CustomChartsheetViews return CustomChartsheetViews class TestCustomChartsheetViews: def test_read(self, CustomChartsheetViews): src = """ """ xml = fromstring(src) customChartsheetViews = CustomChartsheetViews.from_tree(xml) assert customChartsheetViews.customSheetView[0].state == 'visible' assert customChartsheetViews.customSheetView[0].scale == 88 assert customChartsheetViews.customSheetView[0].pageMargins.left == 0.23622047244094491 def test_write(self, CustomChartsheetViews): from ..custom import CustomChartsheetView pageMargins = PageMargins(left=0.2362204724409449, right=0.2362204724409449, top=0.7480314960629921, bottom=0.7480314960629921, header=0.3149606299212598, footer=0.3149606299212598) customChartsheetView = CustomChartsheetView(guid="{C43F44F8-8CE9-4A07-A9A9-0646C7C6B826}", scale=88, zoomToFit=1, pageMargins=pageMargins) customChartsheetViews = CustomChartsheetViews(customSheetView=[customChartsheetView]) expected = """ """ xml = tostring(customChartsheetViews.to_tree()) diff = compare_xml(xml, expected) assert diff is None, diff ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chartsheet/tests/test_properties.py0000644000000000000000000000225700000000000021255 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml @pytest.fixture def ChartsheetProperties(): from ..properties import ChartsheetProperties return ChartsheetProperties class TestChartsheetPr: def test_read(self, ChartsheetProperties): src = """ """ xml = fromstring(src) chartsheetPr = ChartsheetProperties.from_tree(xml) assert chartsheetPr.codeName == "Chart1" assert chartsheetPr.tabColor.rgb == "FFDCD8F4" def test_write(self, ChartsheetProperties): from openpyxl.styles import Color chartsheetPr = ChartsheetProperties() chartsheetPr.codeName = "Chart Openpyxl" tabColor = Color(rgb="FFFFFFF4") chartsheetPr.tabColor = tabColor expected = """ """ xml = tostring(chartsheetPr.to_tree()) diff = compare_xml(xml, expected) assert diff is None, diff ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chartsheet/tests/test_protection.py0000644000000000000000000000356700000000000021254 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml @pytest.fixture def ChartsheetProtection(): from ..protection import ChartsheetProtection return ChartsheetProtection class TestChartsheetProtection: def test_read(self, ChartsheetProtection): src = """ """ xml = fromstring(src) chartsheetProtection = ChartsheetProtection.from_tree(xml) assert chartsheetProtection.algorithmName == "SHA-512" assert chartsheetProtection.saltValue == "Bo89+SCcqbFEcOS/6LcjBw==" def test_write(self, ChartsheetProtection): chartsheetProtection = ChartsheetProtection() chartsheetProtection.saltValue = "Bo89+SCcqbFEcOS/6LcjBw==" chartsheetProtection.content = "1" chartsheetProtection.objects = "1" chartsheetProtection.algorithmName = "SHA-512" chartsheetProtection.spinCount = "100000" expected = """ """ xml = tostring(chartsheetProtection.to_tree()) diff = compare_xml(xml, expected) assert diff is None, diff def test_password(self, ChartsheetProtection): prot = ChartsheetProtection() prot.password = "secret" assert prot.password == "DAA7" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chartsheet/tests/test_publish.py0000644000000000000000000000663400000000000020532 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml @pytest.fixture def WebPublishItem(): from ..publish import WebPublishItem return WebPublishItem class TestWebPulishItem: def test_read(self, WebPublishItem): src = r""" """ xml = fromstring(src) webPulishItem = WebPublishItem.from_tree(xml) assert webPulishItem.id == 6433 assert webPulishItem.sourceObject == "Chart 1" def test_write(self, WebPublishItem): webPublish = WebPublishItem(id=6433, divId="Views_6433", sourceType="chart", sourceRef="", sourceObject="Chart 1", destinationFile=r"D:\Publish.mht", title="First Chart", autoRepublish=False) expected = r""" """ xml = tostring(webPublish.to_tree()) diff = compare_xml(xml, expected) assert diff is None, diff @pytest.fixture def WebPublishItems(): from ..publish import WebPublishItems return WebPublishItems class TestWebPublishItems: def test_read(self, WebPublishItems): src = r""" """ xml = fromstring(src) webPublishItems = WebPublishItems.from_tree(xml) assert webPublishItems.count == 1 assert webPublishItems.webPublishItem[0].sourceObject == "Chart 1" def test_write(self, WebPublishItems): from ..publish import WebPublishItem webPublish_6433 = WebPublishItem(id=6433, divId="Views_6433", sourceType="chart", sourceRef="", sourceObject="Chart 1", destinationFile=r"D:\Publish.mht", title="First Chart", autoRepublish=False) webPublish_64487 = WebPublishItem(id=64487, divId="Views_64487", sourceType="chart", sourceRef="Ref_545421", sourceObject="Chart 15", destinationFile=r"D:\Publish_12.mht", title="Second Chart", autoRepublish=True) webPublishItems = WebPublishItems(webPublishItem=[webPublish_6433, webPublish_64487]) expected = r""" """ xml = tostring(webPublishItems.to_tree()) diff = compare_xml(xml, expected) assert diff is None, diff ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chartsheet/tests/test_relation.py0000644000000000000000000000352500000000000020675 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml @pytest.fixture def SheetBackgroundPicture(): from ..chartsheet import SheetBackgroundPicture return SheetBackgroundPicture class TestSheetBackgroundPicture: def test_read(self, SheetBackgroundPicture): src = """ """ xml = fromstring(src) sheetBackgroundPicture = SheetBackgroundPicture.from_tree(xml) assert sheetBackgroundPicture.id == "rId5" def test_write(self, SheetBackgroundPicture): sheetBackgroundPicture = SheetBackgroundPicture(id="rId5") expected = """ """ xml = tostring(sheetBackgroundPicture.to_tree()) diff = compare_xml(xml, expected) assert diff is None, diff @pytest.fixture def DrawingHF(): from ..chartsheet import DrawingHF return DrawingHF class TestDrawingHF: def test_read(self, DrawingHF): src = """ """ xml = fromstring(src) drawingHF = DrawingHF.from_tree(xml) assert drawingHF.lho == 7 def test_write(self, DrawingHF): drawingHF = DrawingHF(lho=7, lhf=6, id='rId3') expected = """ """ xml = tostring(drawingHF.to_tree("drawingHF")) diff = compare_xml(xml, expected) assert diff is None, diff ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chartsheet/tests/test_views.py0000644000000000000000000000331000000000000020205 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest from openpyxl.xml.functions import fromstring, tostring from openpyxl.tests.helper import compare_xml @pytest.fixture def ChartsheetView(): from ..views import ChartsheetView return ChartsheetView class TestChartsheetView: def test_read(self, ChartsheetView): src = """ """ xml = fromstring(src) chart = ChartsheetView.from_tree(xml) assert chart.tabSelected == True def test_write(self, ChartsheetView): sheetview = ChartsheetView(tabSelected=True, zoomScale=80, workbookViewId=0, zoomToFit=True) expected = """""" xml = tostring(sheetview.to_tree()) diff = compare_xml(xml, expected) assert diff is None, diff @pytest.fixture def ChartsheetViewList(): from ..views import ChartsheetViewList return ChartsheetViewList class TestChartsheetViewList: def test_read(self, ChartsheetViewList): src = """ """ xml = fromstring(src) views = ChartsheetViewList.from_tree(xml) assert views.sheetView[0].tabSelected == 1 def test_write(self, ChartsheetViewList): views = ChartsheetViewList() expected = """ """ xml = tostring(views.to_tree()) diff = compare_xml(xml, expected) assert diff is None, diff ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/chartsheet/views.py0000644000000000000000000000247500000000000016017 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors import ( Bool, Integer, Typed, Sequence ) from openpyxl.descriptors.excel import ExtensionList from openpyxl.descriptors.serialisable import Serialisable class ChartsheetView(Serialisable): tagname = "sheetView" tabSelected = Bool(allow_none=True) zoomScale = Integer(allow_none=True) workbookViewId = Integer() zoomToFit = Bool(allow_none=True) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = () def __init__(self, tabSelected=None, zoomScale=None, workbookViewId=0, zoomToFit=None, extLst=None, ): self.tabSelected = tabSelected self.zoomScale = zoomScale self.workbookViewId = workbookViewId self.zoomToFit = zoomToFit class ChartsheetViewList(Serialisable): tagname = "sheetViews" sheetView = Sequence(expected_type=ChartsheetView, ) extLst = Typed(expected_type=ExtensionList, allow_none=True) __elements__ = ('sheetView',) def __init__(self, sheetView=None, extLst=None, ): if sheetView is None: sheetView = [ChartsheetView()] self.sheetView = sheetView ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/comments/__init__.py0000644000000000000000000000010300000000000016076 0ustar00# Copyright (c) 2010-2021 openpyxl from .comments import Comment ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/comments/author.py0000644000000000000000000000060400000000000015647 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import ( Sequence, Alias ) class AuthorList(Serialisable): tagname = "authors" author = Sequence(expected_type=str) authors = Alias("author") def __init__(self, author=(), ): self.author = author ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/comments/comment_sheet.py0000644000000000000000000001336200000000000017204 0ustar00# Copyright (c) 2010-2021 openpyxl ## Incomplete! from openpyxl.descriptors.serialisable import Serialisable from openpyxl.descriptors import ( Typed, Float, Integer, Set, String, Bool, ) from openpyxl.descriptors.excel import Guid, ExtensionList from openpyxl.descriptors.sequence import NestedSequence from openpyxl.utils.indexed_list import IndexedList from openpyxl.xml.constants import SHEET_MAIN_NS from openpyxl.xml.functions import tostring from openpyxl.cell.text import Text #from openpyxl.worksheet.ole import ObjectAnchor from .author import AuthorList from .comments import Comment from .shape_writer import ShapeWriter class Properties(Serialisable): locked = Bool(allow_none=True) defaultSize = Bool(allow_none=True) _print = Bool(allow_none=True) disabled = Bool(allow_none=True) uiObject = Bool(allow_none=True) autoFill = Bool(allow_none=True) autoLine = Bool(allow_none=True) altText = String(allow_none=True) textHAlign = Set(values=(['left', 'center', 'right', 'justify', 'distributed'])) textVAlign = Set(values=(['top', 'center', 'bottom', 'justify', 'distributed'])) lockText = Bool(allow_none=True) justLastX = Bool(allow_none=True) autoScale = Bool(allow_none=True) rowHidden = Bool(allow_none=True) colHidden = Bool(allow_none=True) #anchor = Typed(expected_type=ObjectAnchor, ) __elements__ = ('anchor',) def __init__(self, locked=None, defaultSize=None, _print=None, disabled=None, uiObject=None, autoFill=None, autoLine=None, altText=None, textHAlign=None, textVAlign=None, lockText=None, justLastX=None, autoScale=None, rowHidden=None, colHidden=None, anchor=None, ): self.locked = locked self.defaultSize = defaultSize self._print = _print self.disabled = disabled self.uiObject = uiObject self.autoFill = autoFill self.autoLine = autoLine self.altText = altText self.textHAlign = textHAlign self.textVAlign = textVAlign self.lockText = lockText self.justLastX = justLastX self.autoScale = autoScale self.rowHidden = rowHidden self.colHidden = colHidden self.anchor = anchor class CommentRecord(Serialisable): tagname = "comment" ref = String() authorId = Integer() guid = Guid(allow_none=True) shapeId = Integer(allow_none=True) text = Typed(expected_type=Text) commentPr = Typed(expected_type=Properties, allow_none=True) author = String(allow_none=True) __elements__ = ('text', 'commentPr') __attrs__ = ('ref', 'authorId', 'guid', 'shapeId') def __init__(self, ref="", authorId=0, guid=None, shapeId=0, text=None, commentPr=None, author=None, height=79, width=144 ): self.ref = ref self.authorId = authorId self.guid = guid self.shapeId = shapeId if text is None: text = Text() self.text = text self.commentPr = commentPr self.author = author self.height = height self.width = width @classmethod def from_cell(cls, cell): """ Class method to convert cell comment """ comment = cell._comment ref = cell.coordinate self = cls(ref=ref, author=comment.author) self.text.t = comment.content self.height = comment.height self.width = comment.width return self @property def content(self): """ Remove all inline formatting and stuff """ return self.text.content class CommentSheet(Serialisable): tagname = "comments" authors = Typed(expected_type=AuthorList) commentList = NestedSequence(expected_type=CommentRecord, count=0) extLst = Typed(expected_type=ExtensionList, allow_none=True) _id = None _path = "/xl/comments/comment{0}.xml" mime_type = "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml" _rel_type = "comments" _rel_id = None __elements__ = ('authors', 'commentList') def __init__(self, authors=None, commentList=None, extLst=None, ): self.authors = authors self.commentList = commentList def to_tree(self): tree = super(CommentSheet, self).to_tree() tree.set("xmlns", SHEET_MAIN_NS) return tree @property def comments(self): """ Return a dictionary of comments keyed by coord """ authors = self.authors.author for c in self.commentList: yield c.ref, Comment(c.content, authors[c.authorId], c.height, c.width) @classmethod def from_comments(cls, comments): """ Create a comment sheet from a list of comments for a particular worksheet """ authors = IndexedList() # dedupe authors and get indexes for comment in comments: comment.authorId = authors.add(comment.author) return cls(authors=AuthorList(authors), commentList=comments) def write_shapes(self, vml=None): """ Create the VML for comments """ sw = ShapeWriter(self.comments) return sw.write(vml) @property def path(self): """ Return path within the archive """ return self._path.format(self._id) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/comments/comments.py0000644000000000000000000000270200000000000016173 0ustar00# Copyright (c) 2010-2021 openpyxl class Comment(object): _parent = None def __init__(self, text, author, height=79, width=144): self.content = text self.author = author self.height = height self.width = width @property def parent(self): return self._parent def __eq__(self, other): return ( self.content == other.content and self.author == other.author ) def __repr__(self): return "Comment: {0} by {1}".format(self.content, self.author) def __copy__(self): """Create a detached copy of this comment.""" clone = self.__class__(self.content, self.author, self.height, self.width) return clone def bind(self, cell): """ Bind comment to a particular cell """ if cell is not None and self._parent is not None and self._parent != cell: fmt = "Comment already assigned to {0} in worksheet {1}. Cannot assign a comment to more than one cell" raise AttributeError(fmt.format(cell.coordinate, cell.parent.title)) self._parent = cell def unbind(self): """ Unbind a comment from a cell """ self._parent = None @property def text(self): """ Any comment text stripped of all formatting. """ return self.content @text.setter def text(self, value): self.content = value ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/comments/shape_writer.py0000644000000000000000000000743400000000000017051 0ustar00# Copyright (c) 2010-2021 openpyxl from openpyxl.xml.functions import ( Element, SubElement, tostring, fromstring, ) from openpyxl.utils import ( column_index_from_string, coordinate_to_tuple, ) vmlns = "urn:schemas-microsoft-com:vml" officens = "urn:schemas-microsoft-com:office:office" excelns = "urn:schemas-microsoft-com:office:excel" class ShapeWriter(object): """ Create VML for comments """ vml = None vml_path = None def __init__(self, comments): self.comments = comments def add_comment_shapetype(self, root): shape_layout = SubElement(root, "{%s}shapelayout" % officens, {"{%s}ext" % vmlns: "edit"}) SubElement(shape_layout, "{%s}idmap" % officens, {"{%s}ext" % vmlns: "edit", "data": "1"}) shape_type = SubElement(root, "{%s}shapetype" % vmlns, {"id": "_x0000_t202", "coordsize": "21600,21600", "{%s}spt" % officens: "202", "path": "m,l,21600r21600,l21600,xe"}) SubElement(shape_type, "{%s}stroke" % vmlns, {"joinstyle": "miter"}) SubElement(shape_type, "{%s}path" % vmlns, {"gradientshapeok": "t", "{%s}connecttype" % officens: "rect"}) def add_comment_shape(self, root, idx, coord, height, width): row, col = coordinate_to_tuple(coord) row -= 1 col -= 1 shape = _shape_factory(row, col, height, width) shape.set('id', "_x0000_s%04d" % idx) root.append(shape) def write(self, root): if not hasattr(root, "findall"): root = Element("xml") # Remove any existing comment shapes comments = root.findall("{%s}shape[@type='#_x0000_t202']" % vmlns) for c in comments: root.remove(c) # check whether comments shape type already exists shape_types = root.find("{%s}shapetype[@id='_x0000_t202']" % vmlns) if not shape_types: self.add_comment_shapetype(root) for idx, (coord, comment) in enumerate(self.comments, 1026): self.add_comment_shape(root, idx, coord, comment.height, comment.width) return tostring(root) def _shape_factory(row, column, height, width): style = ("position:absolute; " "margin-left:59.25pt;" "margin-top:1.5pt;" "width:{width}px;" "height:{height}px;" "z-index:1;" "visibility:hidden").format(height=height, width=width) attrs = { "type": "#_x0000_t202", "style": style, "fillcolor": "#ffffe1", "{%s}insetmode" % officens: "auto" } shape = Element("{%s}shape" % vmlns, attrs) SubElement(shape, "{%s}fill" % vmlns, {"color2": "#ffffe1"}) SubElement(shape, "{%s}shadow" % vmlns, {"color": "black", "obscured": "t"}) SubElement(shape, "{%s}path" % vmlns, {"{%s}connecttype" % officens: "none"}) textbox = SubElement(shape, "{%s}textbox" % vmlns, {"style": "mso-direction-alt:auto"}) SubElement(textbox, "div", {"style": "text-align:left"}) client_data = SubElement(shape, "{%s}ClientData" % excelns, {"ObjectType": "Note"}) SubElement(client_data, "{%s}MoveWithCells" % excelns) SubElement(client_data, "{%s}SizeWithCells" % excelns) SubElement(client_data, "{%s}AutoFill" % excelns).text = "False" SubElement(client_data, "{%s}Row" % excelns).text = str(row) SubElement(client_data, "{%s}Column" % excelns).text = str(column) return shape ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/comments/tests/__init__.py0000644000000000000000000000000000000000000017234 0ustar00././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/comments/tests/conftest.py0000644000000000000000000000045600000000000017341 0ustar00# Copyright (c) 2010-2021 openpyxl import pytest @pytest.fixture def datadir(): """DATADIR as a LocalPath""" import os here = os.path.split(__file__)[0] DATADIR = os.path.join(here, "data") from py._path.local import LocalPath return LocalPath(DATADIR) # objects under test ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/comments/tests/data/comments.xlsx0000644000000000000000000003162200000000000020617 0ustar00PK!P)s[Content_Types].xml (UN0#(q B) G@|ĶKiB}ED#ޙهwG7˦N8a6 ic\L+ )U,b(nƧ'&lm1 `dB^sU< .e,Z 1M`jJSɫ"RBy_B n63hW5 4Vԙ3c(V5v#*c( +]Оjbh$wFC=+|wa<ۯkcFxe {;8':.Hߧ$HҪ #!J]w: ״] ~k#c蹃?瑇D5ȭumgEӠp82PK!U0#L _rels/.rels (MO0 HݐBKwAH!T~I$ݿ'TG~< ֶҝ`@CqNsD$%襤`)qm.cuy %΅ڦqa4:r&7wӽ6;ʦtN<*f/t o m*pk ܖ^^ń=BbނBpXhT\b@2m)j;U-p3q]R'w[ HL2gЕF[] zg}ٴz ϬjHJ$n yJ/qہiY#$Qˎ7$5ҭ<:0 [OLV:09kPß^X_a-m=s%iLf/Nل1pNݘkJPI\'A16vҤ4ާp.F4ݗCaLJU 9B8cvd&` /}'<Ó?f;(_|ٟ_㹎O~s;&[x{W# >$1U|`1Mydc!b@ض^] ju[) xy~sA,#_b+r,y2u lc(1B۟@Ydau8‘!Ɩ&pn%Cr`$Ri -˨m=|d"@B~h.Pl39D1Dd#HG:Dz)sc̹ϵ ={tTC]Ę0Bʙ$B":63yq@p"BptUT$|2O->.a2 $9SONԳtZ;)Z;|?(=4Ocxg ;~^7څPuv7.'}x;4@Vj+72(iT'e#"`_U)MO3cVYm)j08۱VrwGhvm 4]ʼNnyI@'$Lu Ʋw$΅E¢)/C@mX?9j Qr_{PK!9xl/worksheets/sheet3.xmlSK0#,7InFIVjEHwי$VmIBJQ9icsr2$ Zٶ߿>,DakBKMqD @d`Cɻ]Av`DHЁM <!``( +{6 ?tʅ T߅W{q$+q7{gDn].?>Ǩ~wViσ]Ό׭E/&r= yR߯V>CS3V0 fQl7AF)="k\pBFuuW ρJ"H/ :g54bW<~vh}߄> H'안*<eT'r*d3 P-@$}5h𭲁ihϜQaPIcD3:z@dY1N jJw ~~ėWdsH}腊ė+j_4B|VPK!zxl/worksheets/sheet2.xmln0 lYWv14(ÀavWd"$ۏ@w Ydsb ;A]˫ ^忟ort49c8 1")%_ V=80X( >GֈMY~VjBa v\Z L?NǕf{pV({mtPάFA ~>K j0 ‰E[wNkzMrY*.fn *f{Cx[^Tv$'xcZqP\8Og`= h/<=NVaKn麿 *6.6̝۫LkM^=jkT2Erq궍84EV ~0japYX }uKj5hՀ'Ĵ&)PK! 1#xl/worksheets/_rels/sheet1.xml.relsj1 E>Lx lC<סv Mw.::hY9V780x=@Ih \Y`=>l"k&7'\PK!x4_H]#xl/worksheets/_rels/sheet3.xml.relsJ1n4Kz1;C&VNlTcOb\ jY`c m| b@ {$X7LO4D)4'Ȏ ɘ0pM2*5T>e@;cu!{}c;h??f|9Z>9b,jK]w c8>:|:8fm,A*\J$N FXJV=T,eǫW^ԼVVŕiyYE&\GQv/lI]^.[bcU}u vW *z:KU[c:Wîg[ : {" ?4^|JRnl}ɬӣSji.E Hźfq(vU4m.qŲWm=[{gS|<0ϱ_yŠ`,շ\HbcO_7K|.˹b5NJ^ܱ;c$w|Zg1-KS|ZTԥ?4l UֿPK!&Axl/worksheets/sheet1.xmlM0,C6m&]5JU׿D5g8{:jE༴&ISFR:?}nJӧ`7 6!)c^4l #uܺ/CZY`KCBaتVV40@(PodϴcytL$Kz[HXi].>Qv!6RpۥDt]FDɜJ~^'x!*IyAY%'kac ˜H@t#!?{XR9]&~nH62377GJNdtuxfaFHp;&Or1aq(MVX2kncۼxKLyo7>aț7sk]-' ~ ӊNm=olVw GTֆ /Jt[Io *PK!4 xl/styles.xmlUmo0=s5Lt]I!H|uvG sKQhKm_=w4{OTd«yTbrŸ!X"+•:RnoRcvZ cS J/҂X8-6{MIe%qS,C_@я_*'mgb!OTl8Pm )p/XQ8ꚕe HyZ+iW0,'(`D8XBT\iBeXkDp̹D0~̑3Ԝ;sɊ6HkS; HQݸ}ee+.*8?9 jY]έ_(]m<(]:‰ߙB5j~7Z<*Iso rrK =y-qxl/sharedStrings.xml|J1rY{P$=>A}mB53[퍕RhS1|բ8:}4f9}{Ҋ% !8 72N"1+dVva 0<2jiAqQ/-goKlxk~_ImNSB# (WkURTLXEIϹfMS$LvЂ +-ňZL2Z흍p6zG\D$xU0ԦYN$k'UsU;VێCz0ԎcaB(Hx 灟/%M̂>x븠_&^ka ng=ߔixAAE&fBhW5"bq 70D "lA!sDB:`cqEVzyc6k%[ ks?7 '? 4n }$IG뾄N_BǻJ1m%:_Ck H(_iߕы`" ev>?mFGoUtz=ΖG2z2ƯEB::Az Had!:³Rbt%S+>3 PK!,xl/comments2.xmlTPj0 |W'}݈]Ơ0cFCc;XNISd00Fw:Yԕ1(7( Xlxx؁⌡.2p#N{ 6r#=41yYskvDwz[cV8dYܱk!%TK jֿdv\*(IΧ\x=t164LʉL,:'AvNuvyrJI!TZd9Z/!"?PK!iZEGxl/comments1.xmlUmK0.Blst p%&%֗@à^r%Dm z2rK6uX>.g#)( wc$'I@HpK!c(X\wVXkEGH#"W~\`L"vE21RvsA|h-د=̭U,)@7Y,:PbN[vI% 䱼,.w^{4)-AjK UfZƑ4jMiv]S )a&ܦİ5ڟB5u/]7d:txl?qLWfǍY;ċa gbp.?:t'0P 4 =y˔C1FCD;PK!i/ُGdocProps/app.xml (Ao0  96 bH7agMc$׏Qn'RRק:H/r B]}iBŵ~NRf5QHeJRk(CU9 7>I/S7ohlχsd`8ko8' sQ1Srtֹ[ue%_L?q hӁ2tyl+2=N!:Xm< u~kB%06r^..}%QڙD ^ωw|9D:Ht~aPhh#C1Kl}miISCSӇlkP>{'s? 9YOɗPK!YB]docProps/core.xml (OK0ߡ&vd''[Hmen޴je<&_?:* &Emg(r)j@'ph^P-Xm \HQn P߁d. [l߳-{,3<-06HsuC w8MR`@'tá}tPl&i&FO{j\vVP N-=xfߜ7S}{ (^O%*3N4I&Nt~W:,Ob(/2WPK!幚5&'xl/printerSettings/printerSettings1.binraHeBDb  y %P!9&`dafG;#',nF~&F $L%WD3s Ub`z"81>>d0 `r%F$H` 9D Gh=$}#|FKć+y"dm Fh%6C:m(  m        B  ̪#2wPK-!P)s[Content_Types].xmlPK-!U0#L _rels/.relsPK-! (xl/_rels/workbook.xml.relsPK-!2R; xl/workbook.xmlPK-!nX xl/theme/theme1.xmlPK-!9~xl/worksheets/sheet3.xmlPK-!zxl/worksheets/sheet2.xmlPK-! 1#xl/worksheets/_rels/sheet1.xml.relsPK-!x4_H]#xl/worksheets/_rels/sheet3.xml.relsPK-!wG_xl/drawings/vmlDrawing2.vmlPK-!&ASxl/worksheets/sheet1.xmlPK-!4 xl/styles.xmlPK-!>ql xl/sharedStrings.xmlPK-!l author2 author author3 text2 text text3 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/comments/tests/data/comments2.xml0000644000000000000000000000354600000000000020507 0ustar00 Cuke Not Cuke Cuke: First Comment Cuke: Second Comment Not Cuke: Third Comment ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1632315091.0 openpyxl-3.0.9/openpyxl/comments/tests/data/commentsDrawing1.vml0000644000000000000000000000441700000000000022016 0ustar00

False 6 2