diff --git a/.gitignore b/.gitignore index e40d98e6..2e79367e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,5 @@ # virtual env -/bin/ -/include/ -/lib/ -/local/ -/share/ -/virtualenv/ -/pip-selfcheck.json +/env/ # transient files /db-test.sqlite3* @@ -16,7 +10,7 @@ # aux files *.pyc -*.swp +*.sw[mnop] # secrets /django.secret @@ -33,3 +27,9 @@ TODO # .htpasswd pro AESOPa /.htpasswd-aesop + +# reversion kvůli historii objektů v reversion +**/reversion + +# pro lidi, co programují v nástrojích od JetBrains +.idea diff --git a/MIGRATIONS b/MIGRATIONS new file mode 100644 index 00000000..3cf73ac4 --- /dev/null +++ b/MIGRATIONS @@ -0,0 +1,187 @@ +Jak zvládnout migrace na nový model: + +- V mojí verzi databáze mají úlohy-Problémy typ "b'uloha'" + + +Log migrace na nový model: + +Operations to perform: + Apply all migrations: admin, auth, contenttypes, django_comments, flatpages, fluent_comments, galerie, korektury, prednasky, reversion, seminar, sessions, sites, sitetree, taggit, threadedcomments +Running migrations: + Applying admin.0003_logentry_add_action_flag_choices... OK + Applying auth.0009_alter_user_last_name_max_length... OK + Applying auth.0010_alter_group_name_max_length... OK + Applying auth.0011_update_proxy_permissions... OK + Applying galerie.0008_auto_20190430_2340... OK + Applying galerie.0009_auto_20190610_2358... OK + Applying galerie.0010_auto_20200819_0947... OK + Applying korektury.0016_auto_20190430_2340... OK + Applying korektury.0017_auto_20190610_2358... OK + Applying prednasky.0011_auto_20190430_2340... OK + Applying prednasky.0012_auto_20190610_2358... OK + Applying seminar.0049_auto_20190430_2354... OK + Applying seminar.0050_auto_20190510_2228... OK + Applying seminar.0051_resitel_to_osoba... OK + Applying seminar.0052_user_to_organizator... OK +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2004-12-31 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (1998-01-01 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2017-12-31 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2017-01-01 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2014-12-31 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2011-01-01 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2013-12-31 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2004-01-01 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2013-01-01 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2012-12-31 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2007-01-01 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2011-12-31 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2009-01-01 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2009-12-31 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2008-12-31 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2005-01-01 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2015-12-31 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2001-01-01 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2010-01-01 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2008-01-01 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2006-12-31 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2002-01-01 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2005-12-31 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (1999-01-01 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2003-01-01 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2000-01-01 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2002-12-31 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2001-12-31 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (1996-01-01 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2000-12-31 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (1999-12-31 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (1996-12-31 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (1994-01-01 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2012-01-01 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2016-12-31 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2018-12-31 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2014-01-01 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2019-12-31 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2006-01-01 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (1995-01-01 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_do received a naive datetime (2007-12-31 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2015-01-01 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2016-01-01 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2018-01-01 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2019-01-01 00:00:00) while time zone support is active. + RuntimeWarning) +/aux/akce/mam/www/mamweb-test/env/lib/python3.7/site-packages/django/db/models/fields/__init__.py:1427: RuntimeWarning: DateTimeField Organizator.organizuje_od received a naive datetime (2020-01-01 00:00:00) while time zone support is active. + RuntimeWarning) + Applying seminar.0053_organizator_organizuje_od_do... OK + Applying seminar.0055_smazat_nemigrovane_zastarale_veci... OK + Applying seminar.0056_vrcholy_pro_rocniky_a_cisla... OK + Applying seminar.0057_reseni_to_reseni_hodnoceni...!!!!!!!!!!!!!!! +31397 Reseni object (31397) +!!!!!!!!!!!!!!! +!!!!!!!!!!!!!!! +31396 Reseni object (31396) +!!!!!!!!!!!!!!! +!!!!!!!!!!!!!!! +31395 Reseni object (31395) +!!!!!!!!!!!!!!! +!!!!!!!!!!!!!!! +31394 Reseni object (31394) +!!!!!!!!!!!!!!! +!!!!!!!!!!!!!!! +31393 Reseni object (31393) +!!!!!!!!!!!!!!! + OK + Applying seminar.0058_problem_to_uloha_tema_clanek... OK + Applying seminar.fix_0058... OK + Applying seminar.0059_vytvorit_pohadkanode... OK + Applying seminar.0060_spoj_stromy... OK + Applying seminar.0061_kill_frankenstein... OK + Applying seminar.0062_redukce_modelu_pohadky... OK + Applying seminar.0063_procisteni_migraci... OK + Applying seminar.0064_auto_20190610_2358... OK + Applying seminar.0065_treenode_polymorphic_ctype... OK + Applying seminar.0066_problem_polymorphic_ctype... OK + Applying seminar.0067_auto_20190814_0805... OK + Applying seminar.0068_treenode_nazev... OK + Applying seminar.0069_auto_20191120_2115... OK + Applying seminar.0070_auto_20191120_2357... OK + Applying seminar.0071_remove_nastaveni_aktualni_rocnik... OK + Applying seminar.0072_auto_20191204_2257... OK + Applying seminar.0073_copy_osoba_email_to_user_email... OK + Applying seminar.0074_auto_20200228_1401... OK + Applying seminar.0075_auto_20200228_2010... OK + Applying seminar.0076_auto_20200228_2013... OK + Applying seminar.0077_auto_20200318_2146... OK + Applying seminar.0078_otistenereseninode... OK + Applying seminar.0079_clanek_resitelsky... OK + Applying seminar.0080_zruseni_claneknode_a_konferanode... OK + Applying seminar.0081_auto_20200408_2221... OK + Applying seminar.0082_auto_20200506_1951... OK + Applying seminar.0083_auto_20200506_1952... OK +WARNING 2020-08-20 00:49:07,941 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (2215) +WARNING 2020-08-20 00:49:07,953 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (2221) +WARNING 2020-08-20 00:49:07,959 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (2212) +WARNING 2020-08-20 00:49:07,965 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (1955) +WARNING 2020-08-20 00:49:07,968 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (2027) +WARNING 2020-08-20 00:49:07,971 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (1981) +WARNING 2020-08-20 00:49:07,974 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (1970) +WARNING 2020-08-20 00:49:07,978 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (2001) +WARNING 2020-08-20 00:49:07,981 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (2004) +WARNING 2020-08-20 00:49:07,984 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (1941) +WARNING 2020-08-20 00:49:07,990 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (2024) +WARNING 2020-08-20 00:49:07,993 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (2031) +WARNING 2020-08-20 00:49:07,997 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (2211) +WARNING 2020-08-20 00:49:08,005 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (2073) +WARNING 2020-08-20 00:49:08,017 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (2018) +WARNING 2020-08-20 00:49:08,022 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (2222) +WARNING 2020-08-20 00:49:08,028 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (1953) +WARNING 2020-08-20 00:49:08,034 0084_clanek_cislo: Více než jedno řešení pro článek Clanek object (2026) + Applying seminar.0084_clanek_cislo... OK + Applying seminar.0085_nepovinna_prezdivka... OK + Applying seminar.0086_auto_20200819_0959... OK + Applying sitetree.0001_initial... OK + Applying taggit.0003_taggeditem_add_unique_index... OK + diff --git a/Makefile b/Makefile index 33e1f229..bc272aa8 100644 --- a/Makefile +++ b/Makefile @@ -1,68 +1,71 @@ -.PHONY: clean_env init_env clean_virtualenv install_packages clean install run all schema_seminar.pdf schema_all.pdf sync_test_media sync_test_db sync_test sync_local_media sync_local_db sync_local -PYTHON=python2.7 -VE_VER=16.0.0 -LOCAL_PYTHON=bin/python - -all: install - -clean: clean_env - -veryclean: clean clean_virtualenv - -install: virtualenv bin/python install_packages - - -# phony, but depends on file -make_env: ${LOCAL_PYTHON} - -# phony, but fast repeated execution -install_packages: make_env - bin/pip install -r requirements.txt --upgrade - -# phony -clean_env: - rm -rf bin/ include/ lib/ local/ share/ +PYTHON ?= python3 +VENV ?= ${PYTHON} -m venv +# Všechny flagy, které se s venvem/virtualenvem/... mají volat patří sem. Volá se "${VENV} cesta" +VENV_PATH ?= env +# Musí být definovaná, i kdyby to měla být "." + +.PHONY: all venv_check clean install install_web install_venv clean_venv clean_schema run test deploy_test deploy_prod sync_test_media sync_test_db sync_test sync_local_media sync_local_db sync_local + +# activate by mělo být předpokladem ke všemu, co volá webový python (i.e. python nasazený do ${VENV}u kvůli webu, např. manage.py) +all: + @# Just echo: + # Install je trochu magický: + # Spusť následující posloupnost příkazů: + # make install_venv + # . ${VENV_PATH}/bin/activate + # make install_web + # + # Pokud install_web říká Error: pg_config executable not found. nainstaluj si libpq-dev + # Pokud chybová hláška obsahuje #include , nainstaluj si python3-dev + # + # Až skončíš s vývojem webu, spusť "deactivate". Tím zmizí '(${VENV_PATH})' ze začátku promptu. + +venv_check: + @# Pokud org nemá zapnutý venv, poradíme mu, aby si ho zapnul a spadneme. Jinak nic. + @expr $$PATH : ".*:*$(shell pwd)/${VENV_PATH}/bin" > /dev/null && exit 0 || echo 'Není zapnutý venv, spusť ". ${VENV_PATH}/bin/activate".\nPokud není venv nainstalovaný, spusť "make install_venv"' && false + +clean: clean_venv clean_schema + +install: install_web + +install_web: venv_check + @# venv může být příšerně starý, takže nejdříve upgradujeme venvové věci + pip install --upgrade pip + pip install --upgrade setuptools + # Instalace závislostí webu + pip install -r requirements.txt --upgrade + # Po vygenerování testdat spusť ./manage.py loaddata data/*, ať máš menu a další modely + # Pro synchronizaci flatpages spusť make sync_prod_flatpages + +install_venv: + ${VENV} ${VENV_PATH} + +clean_venv: + # Možná není 100% foolproof... + @test ! ${VENV_PATH} = . || ! echo "Smaž si prosím venv sám, nebudu mazat celý web" + rm -rfv ${VENV_PATH} rm -f pip-selfcheck.json +clean_schema: rm -f schema_seminar.pdf schema_all.pdf -# binary name representing set-up env -${LOCAL_PYTHON}: virtualenv - ${PYTHON} virtualenv/virtualenv.py . - - - -# directory name -virtualenv: - # I could not find a link without hash anymore. This will probably break in - # the future. - curl -O https://files.pythonhosted.org/packages/33/bc/fa0b5347139cd9564f0d44ebd2b147ac97c36b2403943dbee8a25fd74012/virtualenv-16.0.0.tar.gz - tar xvfz virtualenv-${VE_VER}.tar.gz - mv -T virtualenv-${VE_VER} virtualenv - rm virtualenv-${VE_VER}.tar.gz - -# phony -clean_virtualenv: - rm -rf virtualenv/ - rm -rf virtualenv-*.tar.gz - -run: +run: venv_check ./manage.py runserver -test: +test: venv_check ./manage.py test -v2 seminar mamweb # DB schemata schema: schema_seminar.pdf schema_all.pdf -schema_seminar.pdf: +schema_seminar.pdf: venv_check ./manage.py graph_models seminar | dot -Tpdf > schema_seminar.pdf -schema_all.pdf: +schema_all.pdf: venv_check ./manage.py graph_models -a -g | dot -Tpdf > schema_all.pdf # Deploy to current *mamweb-test* directory -deploy_test: +deploy_test: venv_check @if [ ${USER} != "mam-web" ]; then echo "Only possible by user mam-web"; exit 1; fi @if [ `readlink -f .` != "/aux/akce/mam/www/mamweb-test" ]; then echo "Only possible in directory mamweb-test"; exit 1; fi @echo "Installing version from origin/test ..." @@ -78,7 +81,7 @@ deploy_test: @echo Done. # Deploy to current *mamweb-prod* directory -deploy_prod: +deploy_prod: venv_check @if [ ${USER} != "mam-web" ]; then echo "Only possible by user mam-web"; exit 1; fi @if [ `readlink -f .` != "/aux/akce/mam/www/mamweb-prod" ]; then echo "Only possible in directory mamweb-prod"; exit 1; fi @echo "Backing up production DB ..." @@ -96,6 +99,15 @@ deploy_prod: @echo Done. +sync_prod_flatpages: venv_check + @echo Downloading current version of flatpages from mamweb-prod. + ssh mam-web@gimli.ms.mff.cuni.cz \ + "cd /akce/mam/www/mamweb-prod; ./manage.py dumpdata flatpages --indent=2 > flat.json" + rsync -ave ssh mam-web@gimli.ms.mff.cuni.cz:/akce/mam/www/mamweb-prod/flat.json ./flat.json + @echo "Applying downloaded flatpages." + ./manage.py loaddata flat.json + @echo "Done." + # Sync test media directory with production sync_test_media: @if [ ${USER} != "mam-web" ]; then echo "Only possible by user mam-web"; exit 1; fi @@ -107,12 +119,24 @@ sync_test_db: @if [ ${USER} != "mam-web" ]; then echo "Only possible by user mam-web"; exit 1; fi pg_dump mam_test > dump-test-`date +"%Y%m%d_%H%M"`.sql pg_dump -Fc mam_prod > dump-prod.sql - pg_restore -c -d mam_test dump-prod.sql + pg_restore -c --if-exists -d mam_test dump-prod.sql + rm dump-prod.sql + @echo Done. + +# Aggresive variant: destroy original mam_test db with 'DROP OWNED BY "mam-web";' +sync_test_db_aggressive: + @if [ ${USER} != "mam-web" ]; then echo "Only possible by user mam-web"; exit 1; fi + pg_dump mam_test > dump-test-`date +"%Y%m%d_%H%M"`.sql + pg_dump -Fc mam_prod > dump-prod.sql + @# I am not sure which shell is used, so I am calling bash to make sure + bash -c "psql mam_test <<< 'DROP OWNED BY \"mam-web\";'" + pg_restore -c --if-exists -d mam_test dump-prod.sql rm dump-prod.sql @echo Done. # Sync test with production -sync_test: sync_test_media sync_test_db +# HACK ALERT: using aggressive variant, due to the schemas being too different. +sync_test: sync_test_media sync_test_db_aggressive # Sync media directory with atrey. Useful for local development with production database @@ -128,4 +152,10 @@ sync_local_db: pg_restore -c -d mam-prod last.pgdump # Sync database and media. See above lines -sync_local: sync_media sync_db +sync_local: sync_local_media sync_local_db + +# Push local compiled Vue to gimli test site +push_compiled_vue_to_test: + scp vue_frontend/webpack-stats.json mam-web@gimli:/akce/mam/www/mamweb-test/vue_frontend/ + rsync -ave ssh seminar/static/seminar/vue mam-web@gimli:/akce/mam/www/mamweb-test/seminar/static/seminar/ + ssh mam-web@gimli.ms.mff.cuni.cz 'cd /akce/mam/www/mamweb-test/ && . env/bin/activate && ./manage.py collectstatic --noinput' diff --git a/README.md b/README.md index 057de635..4c69c825 100644 --- a/README.md +++ b/README.md @@ -13,12 +13,12 @@ Use git :-) Quickstart ---------- +Run the following commands: + make install_venv + . env/bin/activate + make install_web -Install the following packages in Debian/Ubuntu: `libpq-dev python-dev python-setuptools python2.7 libjpeg-dev libpng12-dev`. Then run: - - make - ./manage.py testdata - make run +After finishing development, run "deactivate". Make commands ------------- @@ -41,6 +41,8 @@ Make commands * `make schema` - generates graph of seminar and all schemas as PDF. Supercool! +* `make sync_prod_flatpages` - downloads and applies static/flat pages from mamweb-prod + ./manage.py commands -------------------- @@ -56,6 +58,8 @@ Make commands * `./manage.py test` - run the tests. +* `./manage.py shell` - run commands, list elemements of database, check syntax + by importing files, etc. Configurations -------------- diff --git a/Schema_new.dia b/Schema_new.dia new file mode 100644 index 00000000..c212ec3b Binary files /dev/null and b/Schema_new.dia differ diff --git a/admin_org_prava.json b/admin_org_prava.json new file mode 100644 index 00000000..f1b6445d --- /dev/null +++ b/admin_org_prava.json @@ -0,0 +1,637 @@ +[ + { + "codename": "org", + "ct_app_label": "auth", + "ct_model": "user" + }, + { + "codename": "add_flatpage", + "ct_app_label": "flatpages", + "ct_model": "flatpage" + }, + { + "codename": "change_flatpage", + "ct_app_label": "flatpages", + "ct_model": "flatpage" + }, + { + "codename": "delete_flatpage", + "ct_app_label": "flatpages", + "ct_model": "flatpage" + }, + { + "codename": "view_flatpage", + "ct_app_label": "flatpages", + "ct_model": "flatpage" + }, + { + "codename": "add_galerie", + "ct_app_label": "galerie", + "ct_model": "galerie" + }, + { + "codename": "change_galerie", + "ct_app_label": "galerie", + "ct_model": "galerie" + }, + { + "codename": "delete_galerie", + "ct_app_label": "galerie", + "ct_model": "galerie" + }, + { + "codename": "view_galerie", + "ct_app_label": "galerie", + "ct_model": "galerie" + }, + { + "codename": "add_obrazek", + "ct_app_label": "galerie", + "ct_model": "obrazek" + }, + { + "codename": "change_obrazek", + "ct_app_label": "galerie", + "ct_model": "obrazek" + }, + { + "codename": "delete_obrazek", + "ct_app_label": "galerie", + "ct_model": "obrazek" + }, + { + "codename": "view_obrazek", + "ct_app_label": "galerie", + "ct_model": "obrazek" + }, + { + "codename": "add_komentar", + "ct_app_label": "korektury", + "ct_model": "komentar" + }, + { + "codename": "change_komentar", + "ct_app_label": "korektury", + "ct_model": "komentar" + }, + { + "codename": "delete_komentar", + "ct_app_label": "korektury", + "ct_model": "komentar" + }, + { + "codename": "view_komentar", + "ct_app_label": "korektury", + "ct_model": "komentar" + }, + { + "codename": "add_korekturovanepdf", + "ct_app_label": "korektury", + "ct_model": "korekturovanepdf" + }, + { + "codename": "change_korekturovanepdf", + "ct_app_label": "korektury", + "ct_model": "korekturovanepdf" + }, + { + "codename": "delete_korekturovanepdf", + "ct_app_label": "korektury", + "ct_model": "korekturovanepdf" + }, + { + "codename": "view_korekturovanepdf", + "ct_app_label": "korektury", + "ct_model": "korekturovanepdf" + }, + { + "codename": "add_oprava", + "ct_app_label": "korektury", + "ct_model": "oprava" + }, + { + "codename": "change_oprava", + "ct_app_label": "korektury", + "ct_model": "oprava" + }, + { + "codename": "delete_oprava", + "ct_app_label": "korektury", + "ct_model": "oprava" + }, + { + "codename": "view_oprava", + "ct_app_label": "korektury", + "ct_model": "oprava" + }, + { + "codename": "add_hlasovani", + "ct_app_label": "prednasky", + "ct_model": "hlasovani" + }, + { + "codename": "change_hlasovani", + "ct_app_label": "prednasky", + "ct_model": "hlasovani" + }, + { + "codename": "delete_hlasovani", + "ct_app_label": "prednasky", + "ct_model": "hlasovani" + }, + { + "codename": "view_hlasovani", + "ct_app_label": "prednasky", + "ct_model": "hlasovani" + }, + { + "codename": "add_prednaska", + "ct_app_label": "prednasky", + "ct_model": "prednaska" + }, + { + "codename": "change_prednaska", + "ct_app_label": "prednasky", + "ct_model": "prednaska" + }, + { + "codename": "delete_prednaska", + "ct_app_label": "prednasky", + "ct_model": "prednaska" + }, + { + "codename": "view_prednaska", + "ct_app_label": "prednasky", + "ct_model": "prednaska" + }, + { + "codename": "add_seznam", + "ct_app_label": "prednasky", + "ct_model": "seznam" + }, + { + "codename": "change_seznam", + "ct_app_label": "prednasky", + "ct_model": "seznam" + }, + { + "codename": "delete_seznam", + "ct_app_label": "prednasky", + "ct_model": "seznam" + }, + { + "codename": "view_seznam", + "ct_app_label": "prednasky", + "ct_model": "seznam" + }, + { + "codename": "add_cislo", + "ct_app_label": "seminar", + "ct_model": "cislo" + }, + { + "codename": "change_cislo", + "ct_app_label": "seminar", + "ct_model": "cislo" + }, + { + "codename": "delete_cislo", + "ct_app_label": "seminar", + "ct_model": "cislo" + }, + { + "codename": "view_cislo", + "ct_app_label": "seminar", + "ct_model": "cislo" + }, + { + "codename": "add_clanek", + "ct_app_label": "seminar", + "ct_model": "clanek" + }, + { + "codename": "change_clanek", + "ct_app_label": "seminar", + "ct_model": "clanek" + }, + { + "codename": "delete_clanek", + "ct_app_label": "seminar", + "ct_model": "clanek" + }, + { + "codename": "view_clanek", + "ct_app_label": "seminar", + "ct_model": "clanek" + }, + { + "codename": "add_konfera", + "ct_app_label": "seminar", + "ct_model": "konfera" + }, + { + "codename": "change_konfera", + "ct_app_label": "seminar", + "ct_model": "konfera" + }, + { + "codename": "delete_konfera", + "ct_app_label": "seminar", + "ct_model": "konfera" + }, + { + "codename": "view_konfera", + "ct_app_label": "seminar", + "ct_model": "konfera" + }, + { + "codename": "add_konfery_ucastnici", + "ct_app_label": "seminar", + "ct_model": "konfery_ucastnici" + }, + { + "codename": "change_konfery_ucastnici", + "ct_app_label": "seminar", + "ct_model": "konfery_ucastnici" + }, + { + "codename": "delete_konfery_ucastnici", + "ct_app_label": "seminar", + "ct_model": "konfery_ucastnici" + }, + { + "codename": "view_konfery_ucastnici", + "ct_app_label": "seminar", + "ct_model": "konfery_ucastnici" + }, + { + "codename": "add_nastaveni", + "ct_app_label": "seminar", + "ct_model": "nastaveni" + }, + { + "codename": "change_nastaveni", + "ct_app_label": "seminar", + "ct_model": "nastaveni" + }, + { + "codename": "delete_nastaveni", + "ct_app_label": "seminar", + "ct_model": "nastaveni" + }, + { + "codename": "view_nastaveni", + "ct_app_label": "seminar", + "ct_model": "nastaveni" + }, + { + "codename": "add_novinky", + "ct_app_label": "seminar", + "ct_model": "novinky" + }, + { + "codename": "change_novinky", + "ct_app_label": "seminar", + "ct_model": "novinky" + }, + { + "codename": "delete_novinky", + "ct_app_label": "seminar", + "ct_model": "novinky" + }, + { + "codename": "view_novinky", + "ct_app_label": "seminar", + "ct_model": "novinky" + }, + { + "codename": "add_organizator", + "ct_app_label": "seminar", + "ct_model": "organizator" + }, + { + "codename": "change_organizator", + "ct_app_label": "seminar", + "ct_model": "organizator" + }, + { + "codename": "delete_organizator", + "ct_app_label": "seminar", + "ct_model": "organizator" + }, + { + "codename": "view_organizator", + "ct_app_label": "seminar", + "ct_model": "organizator" + }, + { + "codename": "add_osoba", + "ct_app_label": "seminar", + "ct_model": "osoba" + }, + { + "codename": "change_osoba", + "ct_app_label": "seminar", + "ct_model": "osoba" + }, + { + "codename": "delete_osoba", + "ct_app_label": "seminar", + "ct_model": "osoba" + }, + { + "codename": "view_osoba", + "ct_app_label": "seminar", + "ct_model": "osoba" + }, + { + "codename": "add_pohadka", + "ct_app_label": "seminar", + "ct_model": "pohadka" + }, + { + "codename": "change_pohadka", + "ct_app_label": "seminar", + "ct_model": "pohadka" + }, + { + "codename": "delete_pohadka", + "ct_app_label": "seminar", + "ct_model": "pohadka" + }, + { + "codename": "view_pohadka", + "ct_app_label": "seminar", + "ct_model": "pohadka" + }, + { + "codename": "add_prijemce", + "ct_app_label": "seminar", + "ct_model": "prijemce" + }, + { + "codename": "change_prijemce", + "ct_app_label": "seminar", + "ct_model": "prijemce" + }, + { + "codename": "delete_prijemce", + "ct_app_label": "seminar", + "ct_model": "prijemce" + }, + { + "codename": "view_prijemce", + "ct_app_label": "seminar", + "ct_model": "prijemce" + }, + { + "codename": "add_problem", + "ct_app_label": "seminar", + "ct_model": "problem" + }, + { + "codename": "change_problem", + "ct_app_label": "seminar", + "ct_model": "problem" + }, + { + "codename": "delete_problem", + "ct_app_label": "seminar", + "ct_model": "problem" + }, + { + "codename": "view_problem", + "ct_app_label": "seminar", + "ct_model": "problem" + }, + { + "codename": "add_resitel", + "ct_app_label": "seminar", + "ct_model": "resitel" + }, + { + "codename": "change_resitel", + "ct_app_label": "seminar", + "ct_model": "resitel" + }, + { + "codename": "delete_resitel", + "ct_app_label": "seminar", + "ct_model": "resitel" + }, + { + "codename": "view_resitel", + "ct_app_label": "seminar", + "ct_model": "resitel" + }, + { + "codename": "add_rocnik", + "ct_app_label": "seminar", + "ct_model": "rocnik" + }, + { + "codename": "change_rocnik", + "ct_app_label": "seminar", + "ct_model": "rocnik" + }, + { + "codename": "delete_rocnik", + "ct_app_label": "seminar", + "ct_model": "rocnik" + }, + { + "codename": "view_rocnik", + "ct_app_label": "seminar", + "ct_model": "rocnik" + }, + { + "codename": "add_skola", + "ct_app_label": "seminar", + "ct_model": "skola" + }, + { + "codename": "change_skola", + "ct_app_label": "seminar", + "ct_model": "skola" + }, + { + "codename": "delete_skola", + "ct_app_label": "seminar", + "ct_model": "skola" + }, + { + "codename": "view_skola", + "ct_app_label": "seminar", + "ct_model": "skola" + }, + { + "codename": "add_soustredeni", + "ct_app_label": "seminar", + "ct_model": "soustredeni" + }, + { + "codename": "change_soustredeni", + "ct_app_label": "seminar", + "ct_model": "soustredeni" + }, + { + "codename": "delete_soustredeni", + "ct_app_label": "seminar", + "ct_model": "soustredeni" + }, + { + "codename": "view_soustredeni", + "ct_app_label": "seminar", + "ct_model": "soustredeni" + }, + { + "codename": "add_soustredeni_organizatori", + "ct_app_label": "seminar", + "ct_model": "soustredeni_organizatori" + }, + { + "codename": "change_soustredeni_organizatori", + "ct_app_label": "seminar", + "ct_model": "soustredeni_organizatori" + }, + { + "codename": "delete_soustredeni_organizatori", + "ct_app_label": "seminar", + "ct_model": "soustredeni_organizatori" + }, + { + "codename": "view_soustredeni_organizatori", + "ct_app_label": "seminar", + "ct_model": "soustredeni_organizatori" + }, + { + "codename": "add_soustredeni_ucastnici", + "ct_app_label": "seminar", + "ct_model": "soustredeni_ucastnici" + }, + { + "codename": "change_soustredeni_ucastnici", + "ct_app_label": "seminar", + "ct_model": "soustredeni_ucastnici" + }, + { + "codename": "delete_soustredeni_ucastnici", + "ct_app_label": "seminar", + "ct_model": "soustredeni_ucastnici" + }, + { + "codename": "view_soustredeni_ucastnici", + "ct_app_label": "seminar", + "ct_model": "soustredeni_ucastnici" + }, + { + "codename": "add_tema", + "ct_app_label": "seminar", + "ct_model": "tema" + }, + { + "codename": "change_tema", + "ct_app_label": "seminar", + "ct_model": "tema" + }, + { + "codename": "delete_tema", + "ct_app_label": "seminar", + "ct_model": "tema" + }, + { + "codename": "view_tema", + "ct_app_label": "seminar", + "ct_model": "tema" + }, + { + "codename": "add_uloha", + "ct_app_label": "seminar", + "ct_model": "uloha" + }, + { + "codename": "change_uloha", + "ct_app_label": "seminar", + "ct_model": "uloha" + }, + { + "codename": "delete_uloha", + "ct_app_label": "seminar", + "ct_model": "uloha" + }, + { + "codename": "view_uloha", + "ct_app_label": "seminar", + "ct_model": "uloha" + }, + { + "codename": "add_tag", + "ct_app_label": "taggit", + "ct_model": "tag" + }, + { + "codename": "change_tag", + "ct_app_label": "taggit", + "ct_model": "tag" + }, + { + "codename": "delete_tag", + "ct_app_label": "taggit", + "ct_model": "tag" + }, + { + "codename": "view_tag", + "ct_app_label": "taggit", + "ct_model": "tag" + }, + { + "codename": "add_taggeditem", + "ct_app_label": "taggit", + "ct_model": "taggeditem" + }, + { + "codename": "change_taggeditem", + "ct_app_label": "taggit", + "ct_model": "taggeditem" + }, + { + "codename": "delete_taggeditem", + "ct_app_label": "taggit", + "ct_model": "taggeditem" + }, + { + "codename": "view_taggeditem", + "ct_app_label": "taggit", + "ct_model": "taggeditem" + }, + { + "codename": "add_fotkaheader", + "ct_app_label": "header_fotky", + "ct_model": "fotkaheader" + }, + { + "codename": "change_fotkaheader", + "ct_app_label": "header_fotky", + "ct_model": "fotkaheader" + }, + { + "codename": "view_fotkaheader", + "ct_app_label": "header_fotky", + "ct_model": "fotkaheader" + }, + { + "codename": "add_fotkaurlvazba", + "ct_app_label": "header_fotky", + "ct_model": "fotkaurlvazba" + }, + { + "codename": "change_fotkaurlvazba", + "ct_app_label": "header_fotky", + "ct_model": "fotkaurlvazba" + }, + { + "codename": "view_fotkaurlvazba", + "ct_app_label": "header_fotky", + "ct_model": "fotkaurlvazba" + } +] diff --git a/checklinks.sh b/checklinks.sh new file mode 100755 index 00000000..63898075 --- /dev/null +++ b/checklinks.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +# Props to https://www.commandlinefu.com/commands/view/8234/check-broken-links-using-wget-as-a-spider +set -eu + +logfile="$(pwd)/wget.log.$(date +%FT%T)" +tmp=$(mktemp --directory) +cd "$tmp" + +wget --spider -o "$logfile" -r -p -X '/soustredeni/*/fotogalerie/' "$@" diff --git a/convert_spaces_to_tabs.sh b/convert_spaces_to_tabs.sh new file mode 100755 index 00000000..8f98f6ae --- /dev/null +++ b/convert_spaces_to_tabs.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +if test "$#" -lt 1 +then + echo "Usage: $0 file ..." + exit 2 +fi + +for file in "$@" +do + # Do the sed magic: keep replacing 4 spaces at the begining of line + sed -i -re ' + : loop + s/^( *) /\1 / + t loop + ' "$file" +done diff --git a/data/flat.json b/data/flat.json new file mode 100644 index 00000000..3dcdc342 --- /dev/null +++ b/data/flat.json @@ -0,0 +1,182 @@ +[ + { + "fields": { + "content": "

Vítejte na stránce semináře MaM!

\r\n", + "enable_comments": false, + "registration_required": false, + "sites": [ + 1 + ], + "template_name": "home.html", + "title": "Seminář M&M", + "url": "/" + }, + "model": "flatpages.flatpage", + "pk": 2 + }, + { + "fields": { + "content": "

Co je M&M?

\r\n\r\n

M&M je mezioborový korespondenční seminář pro středoškoláky

\r\n\r\n

Ptáš se, co že je to ten korespondenční seminář? Je to jednoduché, zamysli se nad zadanou úlohou či problémem, odevzdej řešení, my ti jej opravíme a pošleme zpět. Nabízíme témata z různých oblastí matematiky, fyziky, informatiky i dalších oborů, takže si u nás určitě najdeš to svoje. Při řešení si můžeš vyzkoušet, jak vypadá vědecká práce, a mnoho zajímavého se naučit. Podívej se na tipy v sekci Jak řešit a pusť se do toho! Můžeš se připojit kdykoliv během roku.

\r\n\r\n

M&M jsou témata

\r\n\r\n

Jádro M&M tvoří takzvaná témata, tedy texty doplněné o úlohy a náměty vyzývající k přemýšlení a experimentování. Přijímáme i originální přístup k problémům, takže můžeš například vyřešit fyzikální problém naprogramováním simulace. v minulých letech řešitelé sestavovali spektrometry, pomocí laserových ukazovátek měřili index lomu různých látek, zkoumali křivky popisující vývoj počtu cestujících v tramvaji v průběhu cesty nebo programovali strategie v jednoduché hře a pak je nechávali soupeřit v turnajích. Podívej se, jaká témata nabízíme právě teď.

\r\n\r\n

M&M je časopis

\r\n\r\n

Zadání a texty od organizátorů vydáváme formou časopisu. Kromě toho zde rovněž otiskujeme řešení a příspěvky našich řešitelů k tématům, články shrnující výsledky konfer – projektů, kterými se zabývali na soustředění, i výsledky jejich vlastního výzkumu. Díky tomu jsme si například mohli přečíst o Lichtenbergových obrazcích či gravitaci v placatém světě. Během ročníku obvykle vyjde šest čísel časopisu, prohlédnout si je můžeš v Archivu.

\r\n\r\n

M&M je soutěž

\r\n\r\n

Ke všem příspěvkům posíláme řešitelům zpětnou vazbu a udělujeme za ně body. Vítězové semináře se mohou těšit na zajímavé knihy a deskové hry, autora nejlepšího otištěného článku každoročně odměňujeme dortem. Úspěšným řešitelům jsou navíc prominuty přijímací zkoušky na MFF UK.

\r\n\r\n

M&M jsou soustředění

\r\n\r\n

Aktivní řešitelé mají možnost s námi za odměnu jet dvakrát do roka na soustředění. Pojeď taky! Budeš mít možnost strávit týden v přírodě plný odborného programu a nejrůznější zábavy s partou kamarádů. Čekají tě malé vědecké projekty, přednášky, workshopy, šifrovačka, výlet a mnoho dalšího. Chceš-li se dozvědět víc, přečti si stránku Soustředění nebo se podívej na fotky.

\r\n\r\n

M&M jsme my

\r\n\r\n

Spolu s řešiteli jsme tu i my, organizátoři. Většina z nás jsou studenti Matfyzu, tedy Matematicko-fyzikální fakulty Univerzity Karlovy. Společně se snažíme předávat dál radost z poznávání zajímavých zákoutí matematiky, fyziky a informatiky a budovat komunitu aktivních lidí, kteří se budou rádi scházet, ať už na soustředěních, víkendovkách či jiných akcích. Chceš nás poznat blíž? Podívej se na stránku Organizátoři nebo rovnou něco vyřeš a pojeď s námi na soustředění!

\r\n\r\n

Zaujali jsme tě? Zapoj se! Přečti si jak řešit a podívej se na aktuální zadání. Už se těšíme na tvé příspěvky!

", + "enable_comments": false, + "registration_required": false, + "sites": [ + 1 + ], + "template_name": "", + "title": "Co je M&M?", + "url": "/o-nas/uvod/" + }, + "model": "flatpages.flatpage", + "pk": 3 + }, + { + "fields": { + "content": "

V M&M publikujeme články – stejně jako v opravdovém vědeckém časopise. Setkat se u nás můžeš jednak s články od organizátorů (v rámci nějakého seriálu, nebo jen tak), jednak nám můžeš poslat článek ty sám.

\r\n\r\n

Organizátorské články

\r\n\r\n

Organizátoři tě ve svých článcích obvykle chtějí naučit něco, co by se ti mohlo hodit nebo líbit.

\r\n\r\n

Články od řešitelů

\r\n\r\n

Ty sám nám také můžeš zaslat článek k publikování. Krom článku k tématu (který spadá do jiné sekce) to nejčastěji bude nejspíš článek o tvé konfeře ze soustředění. Můžeš nám ale poslat i pojednání o čemkoli jiném, o čem si myslíš, že by to mohlo ostatní řešitele zajímat. My pak tvoji práci zredigujeme a otiskneme. 

\r\n\r\n

Protože víc hlav víc ví, můžete na článcích pracovat i ve skupinách – stejně jako při řešení témat!

\r\n\r\n

Při psaní článku do M&M je dobré mít na paměti základní zásady pro psaní vědeckého článku.

\r\n", + "enable_comments": false, + "registration_required": false, + "sites": [ + 1 + ], + "template_name": "", + "title": "Články", + "url": "/clanky/uvod/" + }, + "model": "flatpages.flatpage", + "pk": 4 + }, + { + "fields": { + "content": "

Jak řešit

\r\n\r\n

V našem semináři simulujeme vědeckou práci. Vydáváme časopis, v němž se věnujeme různým tématům z oblasti matematiky, fyziky, informatiky a občas i jiných oborů.

\r\n\r\n

Témata

\r\n\r\n

Naším cílem je vás prostřednictvím témat seznámit se zajímavými zákoutími matematiky, fyziky a informatiky a inspirovat vás, abyste sami objevovali jejich krásy. Témata většinou obsahují průvodní text od organizátorů. Na něj navazují různé otázky, nad kterými můžeš v průběhu školního roku přemýšlet a bádat. o své výsledky se pak podělíš s námi, my tvou práci ohodnotíme a pošleme ti zpětnou vazbu. Vybrané příspěvky také otiskujeme, takže si je mohou přečíst ostatní řešitelé a reagovat na ně.

\r\n\r\n

Každý ročník vypisujeme zhruba čtyři až šest témat. Pokud si mezi nimi nevybereš, můžeš si položit vlastní otázku, přemýšlet, experimentovat a o svých výsledcích nám napsat článek. Nabízíme ti [pár tipů](Jak psát článek), jak jej napsat pěkně a přehledně. Autora nejlepšího otištěného článku každoročně odměňujeme dortem.

\r\n\r\n

Otázky u jednotlivých témat jsou dvou druhů. Podle toho se bude lišit i formát tvého řešení.

\r\n\r\n

Úlohy

\r\n\r\n

Jak vypadají?

\r\n\r\n

V rámci témat jsou zadány uzavřené úlohy. Tyto úlohy bývají trochu těžší než obvyklé školní a jejich řešení často vyžaduje hlubší zamyšlení nebo nějaký trik. k jejich vyřešení by ti však měly stačit středoškolské znalosti a pochopení průvodního textu, který tyto znalosti rozvíjí.

\r\n\r\n

Jak na to?

\r\n\r\n

Vyřeš úlohu a pošli nám řešení. Nezapomeň na postup! u každé úlohy je uveden počet bodů za správné řešení, přiměřenou část však lze získat i za řešení neúplné. Neboj se proto poslat své úvahy, i když nedojdeš ke zdárnému konci. Částečné řešení je lepší než žádné. Pokud je naopak tvé řešení velmi elegantní, můžeš získat body navíc.

\r\n\r\n

Používáš-li v řešení nějaké pojmy, které nebyly v rámci témátka definovány a nepatří mezi běžné středoškolské znalosti, nezapomeň jen krátce definovat.

\r\n\r\n

Termín odevzdání

\r\n\r\n

Odevzdávání úloh je omezené termínem odeslání, poté je zveřejněno vzorové řešení. Tím se může stát i tvé pěkně sepsané řešení.

\r\n\r\n

Problémy

\r\n\r\n

Jak vypadají?

\r\n\r\n

Témata poskytují příležitost pro rozsáhlejší zamyšlení a podrobnější rozbor zadaných otázek. Řešení proto obvykle vyžaduje o něco víc prostoru než řešení úlohy. Zároveň je v závislosti na kvalitě štědřeji bodově hodnoceno.

\r\n\r\n

Jak na to?

\r\n\r\n

Řešením problému může být popis (případně videozáznam) provedeného experimentu a diskuze výsledků, popis teoretického výpočtu či napsaného programu, úvaha založená na dosud známých informacích, souhrn dalších (podle tebe zajímavých a nezodpovězených) otázek z daného okruhu nebo jakýkoliv další přístup, který příspívá k řešení problému. Můžeš navrhnout i vlastní problém týkající se tématu a jeho řešení. Řešení konkrétního problému jdoucí do hloubky je bodově hodnoceno výrazně lépe než souhrn krátce zmiňující kdeco.

\r\n\r\n

Řešení problému můžeš sepsat jako článek nebo krátký příspěvek. Napsat článek je trochu náročnější a je tedy lépe bodově hodnocen. Nabízíme ti [pár tipů](Jak psát článek), jak jej pěkně a přehledně napsat. Neboj se však k tématu poslat i méně propracovaný příspěvek, klidně jeden odstavec shrnující tvé myšlenky.

\r\n\r\n

Zaslané řešení vedoucí tématu ohodnotí, případně zkoriguje – probere s tebou, co by bylo vhodné vylepšit, doplnit či upřesnit. Na závěr článek publikujeme na webu či dokonce v čísle.

\r\n\r\n

Inspiruj se a reaguj!

\r\n\r\n

Velmi důležitou vlastností témat je, že můžeš na články ostatních reagovat – rozvíjet je, nebo naopak bořit autorovy představy. Přesně to se děje i při skutečné vědecké práci. Proto se hodí poslat také částečná řešení, postřehy nebo nápady ohledně dalších otázek k tématu, které třeba nezvládneš vyřešit sám. Takovéto příspěvky dávají prostor ostatním a mohou je dál inspirovat a přivést k novým nápadům – ostatní zase svými příspěvky mohou inspirovat či navést k zajímavému nápadu tebe.

\r\n\r\n

Spolupracuj

\r\n\r\n

Protože víc hlav víc ví, můžeš na tématech spolupracovat s ostatními řešiteli. i opravdové vědecké práce často publikuje kolektiv autorů. Pokud se na zaslaném řešení podílí n

\r\n\r\n

autorů, dostane každý z nich 3b/(n+2) bodů, kde b

\r\n\r\n

je počet bodů, které by řešení získalo, pokud by mělo jednoho autora.

\r\n\r\n

Ke spolupráci můžeš využít e-mailové konference. Pokud pošleš e-mail na její adresu, přijde všem vedoucím tématu a řešitelům, kteří se jím také zabývají. Pošleš-li k danému tématu alespoň nějaké řešení, automaticky tě přidáme do příslušné konference. Pokud bys chtěl do konference přidat, i když jsi zatím nic neposlal, neboj se nám ozvat.

\r\n\r\n

Termín odevzdání

\r\n\r\n

Nad problémy k tématům sice můžeš většinou přemýšlet celý rok až do termínu odevzdání poslední série úloh, ale čím dříve nám článek pošleš, tím dříve na něj ostatní budou moci zareagovat. Zároveň se ti nestane, že ti tvůj nápad někdo vyfoukne.

\r\n\r\n

Jak poslat řešení

\r\n\r\n

Řešení jednotlivých témat sepiš samostatně, aby si je mohli vedoucí rozdělit. Nezapomeň uvést své jméno a číslo tématu i jednotlivých úloh a problémů. Svá řešení odevzdej elektronicky v odevzdávátku. Textové řešení ve formátu PDF můžeš doplnit libovolnou přílohou, například videem nebo kódem. Pokud bys měl s odevzdáním nějaký problém, tak nám neváhej napsat na mam@matfyz.cz.

\r\n\r\n

Termíny odevzdání

\r\n\r\n

Každé číslo má dva deadliny pro odevzdání řešení úloh, které jsou v něm otištěné. Pokud pošleš řešení do 1. deadlinu, stihneme ti poslat opravená řešení již s následujícím číslem časopisu, ve kterém se zároveň objeví body, které jsi za toto řešení dostal.

\r\n\r\n

Když tedy v prvním čísle zašleš řešení úlohy do 1. deadlinu, pak se body za něj získané objeví ve druhém čísle. Opravené řešení ti přijde e-mailem před vydáním druhého čísla nebo v obálce s druhým číslem.

\r\n\r\n

Tvá řešení se snažíme opravit co nejdříve a rovnou ti je poslat opravená e-mailem. Pokud ti přijde opravené řešení před 2. deadlinem, máš možnost si jej ještě vylepšit a poslat nám další verzi. Čím dříve své řešení pošleš, tím větší je šance, že jej stihneme opravit s předstihem. Nemůžeme ti to však zcela slíbit.

\r\n\r\n

Úlohy poslané mezi 1. a 2. deadlinem pravděpodobně do následujícího čísla opravit nestihneme, výjimečně se to ale stát může. 2. deadline je finální a úlohy, které přijdou po něm, už nebudou hodnoceny.

\r\n\r\n

Příklad: Pokud tedy úlohu zadanou v prvním čísle pošleš mezi 1. a 2. deadlinem, opravené řešení a body typicky dostaneš až se třetím číslem.

\r\n\r\n

Články

\r\n\r\n

Pokud se rozhodneš poslat řešení formou článku, budeme rádi, pokud to uděláš co nejdřív. Může se totiž stát, že bude potřeba abychom jej před vydáním společně ještě trochu upravili. Na to se hodí, abychom měli my i ty dostatek času. Vždy záleží na konkrétním případu, ale pokud pošleš článek až po 1. deadlinu, je velmi nepravděpodobné, že by se stihl objevit už v následujícím čísle.

\r\n\r\n

 

", + "enable_comments": false, + "registration_required": false, + "sites": [ + 1 + ], + "template_name": "", + "title": "Jak řešit?", + "url": "/jak-resit/" + }, + "model": "flatpages.flatpage", + "pk": 7 + }, + { + "fields": { + "content": "

Jaký je smysl M&M?

\r\n\r\n

Smyslem M&M je pomáhat studentům s nadáním na matematiku, fyziku či informatiku rozvíjet jejich schopnosti a zprostředkovávat jejich setkávání a navazování přátelství.

\r\n\r\n

Jsem student střední školy, posledních ročníků základní školy či ekvivalentních ročníků víceletého gymnázia: Co mi M&M může přinést?

\r\n\r\n

Pokud tě zajímá matematika, fyzika nebo informatika, můžeme ti nabídnout zajímavé podněty k přemýšlení. A pokud se zúčastníš některého z našich soustředění, pak i přátelský kolektiv fajn lidí podobných tobě.

\r\n\r\n

Jsem učitel matematiky, fyziky či informatiky na střední škole: K čemu mi M&M může být dobré?

\r\n\r\n

Jestliže nabídnete svým studentům M&M k řešení, může je náš časopis motivovat k dalšímu rozvoji. Náš archiv úloh a témat můžete použít jako zdroj náročnějších úloh pro nadané žáky. Naše úlohy jsou řešitelné se středoškolskými znalostmi – s trochou přemýšlení.

\r\n\r\n

Jsem rodič studenta nadaného na matematiku, fyziku či informatiku: Je M&M pro moje dítě dobré?

\r\n\r\n

Jednoznačně ano – pokud o nás samo bude stát. Primárně můžeme Vaše dítě odborně rozvíjet. Náš kolektiv je navíc velmi otevřený a dovede přijmout i mládež, která má problém s integrací do běžného školního kolektivu.

\r\n\r\n

Ještě nějaké dotazy?

\r\n\r\n

Sem s nimi!

\r\n", + "enable_comments": false, + "registration_required": false, + "sites": [ + 1 + ], + "template_name": "", + "title": "Často kladené dotazy", + "url": "/o-nas/FAQ/" + }, + "model": "flatpages.flatpage", + "pk": 8 + }, + { + "fields": { + "content": "

Soustředění

\r\n\r\n

Dvakrát do roka pořádáme týdenní soustředění plné odborného programu i nejrůznější zábavy. Na co se můžeš těšit?

\r\n\r\n

Konfery

\r\n\r\n

Konfery jsou malé projekty, při nichž si v průběhu soustředění zkusíš, jak vypadá vědecká práce v praxi. Nabídka bývá rozmanitá. v minulých letech jsme se zabývali například zkoumáním a testováním různých tepelných štítů, analyzovali jsme provoz na zabezpečené Wi-Fi, zkusili postavit Stirlingův motor, zkoumali geometrii origami a mnoho dalšího.

\r\n\r\n

Na začátku si vybereš, které téma je ti blízké. Během týdne se mu pak věnuješ v malé skupince pod vedením některého organizátora. Své výsledky na konci soustředění prezentujete ostatním na malé vědecké konferenci. Za nejlepší příspěvek můžete vyhrát nějakou drobnou cenu. Pokud navíc své výsledky po soustředění sepíšete do článku, který budeme moci otisknout, můžete získat body podobně jako za příspěvky k tématům.

\r\n\r\n

Přednášky

\r\n\r\n

Téměř každý den se ve dvou blocích přednášek dozvíš něco nového. V každém bloku probíhají tři přednášky zároveň a vybrat si obvykle můžeš mezi matematikou, fyzikou a informatikou, ale někdy se objeví i biologie či něco úplně jiného. Některé přednášky jsou lehčí, jiné těžší, obecně je ale jejich úroveň vhodná právě pro zvídavé středoškoláky.

\r\n\r\n

Přednášíme i na požádání – stačí, když si vybereš téma, které tě zajímá, a oslovíš toho správného organizátora.

\r\n\r\n

Hry

\r\n\r\n

Máme pro tebe připravenou celou řadu her – denních i nočních, uvnitř i venku, strategických i akčních, a někdy tohle všechno dohromady. Zkusíš si činnosti, ke kterým se běžně nedostaneš. Střelba z luku, lezení po skalách, slackline či celonoční šifrovačka? Není problém! Účast je samozřejmě dobrovolná.

\r\n\r\n

Legenda

\r\n\r\n

Soustřední bývá rámováno příběhem, v jehož duchu se pak nese neodborný (a občas i odborný) program. Už jsme přistáli na jiné planetě, navštívili Tajuplný ostrov, vyšetřovali zločin a zestárli a odešli do důchodu. Co nás čeká příště?

\r\n\r\n

Kamarádi

\r\n\r\n

Poznáš nové lidi, které baví přemýšlet a matematika pro ně není sprosté slovo. Pokud budeš někdy v budoucnu studovat na Matfyzu, pravděpodobně zde na své kamarády z M&M narazíš mezi spolužáky či vyučujícími. Především se ale sejde parta lidí, kteří se rádi baví a se kterými si užiješ mnoho legrace během her, na výletě, při hraní na kytaru či jen tak. Těšíme se, až tě v našem kolektivu uvítáme!

\r\n\r\n

Absence ve škole

\r\n\r\n

Než pojedeš na soustředění, pošleme ti oficiální omluvenku od MFF UK. Jelikož je soustředění plné odborného programu, většina škol naše řešitele bez problému uvolňuje. Některé školy dokonce účast na soustředění nezapočítávají do absence. Vždy je ale dobré se informovat, jak účast na podobných akcích řeší tvoje škola, a případně se osobně domluvit s ředitelem či ředitelkou.

\r\n\r\n

Kapacita soustředění

\r\n\r\n

Chceme zachovat přátelskou a komorní atmosféru soustředění, proto zveme na soustředění zhruba dvacet nejúspěšnějších řešitelů korespondenčního semináře. Několik dalších řešitelů zveme jako náhradníky pro případ, že by někteří pozvaní nemohli. Pokud tě na soustředění nepozveme, nezoufej a zkus v příštím půlroce poslat více řešení. Dostat se mezi nejlepších dvacet řešitelů je s trochou píle hračka.

", + "enable_comments": false, + "registration_required": false, + "sites": [ + 1 + ], + "template_name": "", + "title": "Informace", + "url": "/soustredeni/" + }, + "model": "flatpages.flatpage", + "pk": 9 + }, + { + "fields": { + "content": "

Podzimní soustředění

\r\n\r\n

se uskuteční 16. - 24. října 2021.

", + "enable_comments": false, + "registration_required": false, + "sites": [ + 1 + ], + "template_name": "", + "title": "Připravujeme", + "url": "/soustredeni/pripravujeme/" + }, + "model": "flatpages.flatpage", + "pk": 11 + }, + { + "fields": { + "content": "

Svá řešení nahrávejte do odevzdávátka.

\r\n\r\n

 

\r\n\r\n

Máte-li nějaké dotazy, neváhejte nás kontaktovat.

\r\n\r\n

E-mail: mam@matfyz.cz

\r\n\r\n

Facebook: Korespondenční seminář M&M

\r\n\r\n

Adresa redakce:

\r\n\r\n

M&M, OPMK MFF UK
\r\nKe Karlovu 3
\r\n121 16 Praha 2

\r\n\r\n

 

\r\n\r\n

Akce a termíny pro odevzdávání řešení najdete v našem kalendáři.

\r\n\r\n

Google Kalendář: casopis.mam@gmail.com

\r\n\r\n

 

\r\n\r\n

Během školního roku je velká část organizátorů k zastižení na koleji 17. listopadu či jinde po Praze.

", + "enable_comments": false, + "registration_required": false, + "sites": [ + 1 + ], + "template_name": "", + "title": "Kontakt", + "url": "/o-nas/kontakt/" + }, + "model": "flatpages.flatpage", + "pk": 22 + }, + { + "fields": { + "content": "

Odměny

\r\n\r\n

Největší odměnou za řešení M&M je účast na soustředění, kromě toho však každý rok oceňujeme pět nejlepších řešitelů knihou a deskovou hrou dle jejich výběru. Letos můžeš být mezi nimi i ty, stačí pilně řešit!

\r\n\r\n

\"\"

\r\n\r\n

Tituly

\r\n\r\n

Za pilné řešení semináře můžeš postupně získat různé titulyMM. Titul u tvého jména v časopisu značí, jakých úspěchů jsi za celou svoji kariéru v M&M zatím dosáhl/a. Kromě toho se s jeho dosažením vždy pojí nějaká drobná či větší odměna.

\r\n\r\n\r\n\r\n

\"\"

\r\n\r\n

Přijímací zkoušky na MFF

\r\n\r\n

Matematicko-fyzikální fakulta Univerzity Karlovy se rozhodla úspěšným řešitelům našeho korespondenčního semináře odpustit přijímací zkoušky. Konkrétně se to týká těch řešitelů, kteří získají za rok alespoň 100 bodů. Ti od nás dostanou „osvědčení úspěšného řešitele“, které pak mohou předložit fakultě.

\r\n\r\n

Dort za článek

\r\n\r\n

Autorovi nebo autorům nejlepšího otištěného článku v každém ročníku upečeme lahodný dort.

\r\n\r\n

 

\r\n\r\n

\"\"

", + "enable_comments": false, + "registration_required": false, + "sites": [ + 1 + ], + "template_name": "", + "title": "Odměny", + "url": "/o-nas/odmeny/" + }, + "model": "flatpages.flatpage", + "pk": 25 + }, + { + "fields": { + "content": "

Zážitkové akce

\r\n\r\n
Letní a Zimní Škola Matematiky a Fyziky
\r\n\r\n

ŠMFko je zážitková akce určená středoškolákům se zájmem o další sebevzdělání. Krom populárně naučných přednášek se na ŠMFku proběhneš venku, vyřádíš se ve sněhu, užiješ si veselý vnitřní program a taky se pobavíš během společného šarádění, lenošení nebo hraní na kytaru.

\r\n\r\n
InterSoB
\r\n\r\n

InterSoB je zábavná a poučná jednodenní soutěž středoškolských studentů, při které máte možnost podívat se netradičním způsobem do zákulisí Masarykovy univerzity, vyzkoušet si své schopnosti v mnoha různých oblastech, udělat si s kamarády zajímavý výlet po Brně a v neposlední řadě také poměřit svoje síly s dalšími týmy.

\r\n\r\n

Další semináře

\r\n\r\n
Korespondenční Seminář z Programování
\r\n\r\n

KSP je seminář určený pro studenty středních a základních škol, kteří mají zájem naučit se něco z oblasti algoritmů, logických úloh, programování a informatiky vůbec. Na své si však přijdou i příznivci matematiky (a vlastně libovolného přemýšlení), ježto oba obory mají mnoho společného.

\r\n\r\n
FYzikální KOrespondenční Seminář
\r\n\r\n

FYKOS pro vás představuje možnost si zajímavým způsobem rozšířit chápání fyziky a proniknout do dalších, dosud nepoznaných, oblastí této vědy. Cílem FYKOSu je rozvíjet fyzikální myšlení, protože člověk, který se umí nad (nejen fyzikálními) problémy zamyslet a cítí touhu dobrat se k nějakému řešení, se uplatní všude, kde si schopností lidského mozku cení.

\r\n\r\n
Matematický korespondenční seminář PraSe (PRAžský SEminář)
\r\n\r\n

Řešením úloh tohoto semináře získáš mnoho matematických znalostí a naučíš přesněji a srozumitelněji formulovat své myšlenky a závěry. Seminář je dobrou přípravou pro účast v nejrůznějších matematických soutěžích i pro další studium matematiky, ale schopnost logického myšlení, kterou si můžeš procvičit, se ti v životě bude hodit, i když se v něm třeba právě matematice věnovat nehodláš.

\r\n\r\n

Pro mladší sourozence

\r\n\r\n
Pikomat
\r\n\r\n

Pikomat je matematický korespondenční seminář určený žákům šestých až devátých tříd základních škol a studentům odpovídajících ročníků víceletých gymnázií. Spočívá v řešení několika úloh propojených příběhem. Na jaře se koná soustředění pro nejlepší řešitele, v létě pak tábor pro všechny zájemce.

\r\n\r\n
Výfuk (VÝpočty Fyzikálních UKolů)
\r\n\r\n

Výfuk je samostatný korespondenční seminář Matfyzu, který spadá pod Katedru didaktiky fyziky. Během školního roku kromě šesti sérií semináře organizátoři připravují i podzimní a jarní setkání, letní tábor a Náboj junior.

\r\n\r\n

Databáze mimoškolních aktivit

\r\n\r\n

Je-li ti výčet aktivit výše málo nebo tě žádná z nich nezaujala, doporučujeme navštívit web organizace ProStředoškoláky, jež zde připravila rozsáhlou databázi mimoškolních aktivit a akcí. Krom toho organizace pořádá soutěž Středoškolák roku, ve které každý rok oceňuje nejaktivnější středoškoláky. Věnuješ-li se tedy mimoškolně něčemu ve větším měřítku, neváhej se do soutěže přihlásit.

", + "enable_comments": false, + "registration_required": false, + "sites": [ + 1 + ], + "template_name": "", + "title": "Další aktivity", + "url": "/o-nas/dalsi-akce/" + }, + "model": "flatpages.flatpage", + "pk": 27 + }, + { + "fields": { + "content": "

Jak psát článek

\r\n\r\n

Proč články?

\r\n\r\n

V rámci témat se vás snažíme inspirovat, abyste nejen řešili uzavřené úlohy, ale také se zamýšleli nad problémy a kladli si vlastní otázky. Budeme moc rádi, pokud nám výsledky svého bádání pošleš ve formě článku.

\r\n\r\n

Článek ti poskytuje více prostoru k vyjádření ucelené myšlenky než obyčejné řešení. Při jeho psaní se naučíš utřídit a formulovat výsledky svého bádání. Je důležité umět srozumitelně vysvětlit své objevy, neboť sebelepší nápad není užitečný, pokud mu nikdo jiný nerozumí. Ostatní řešitelé se mohou tvým článkem inspirovat a navázat na tvoji práci.

\r\n\r\n

Smyslem článku nicméně nemusí být pouze popsání revolučního objevu. Bádání mohou posunout vpřed i malé krůčky, neboj se tedy do psaní článku pustit i když ti třeba přijde, že jsi nakonec tolik nového neobjevil/a. Kromě toho je důležité i srozumitelné vysvětlení, proč něco nejde či proč experiment nevyšel, občas je třeba prozkoumat i slepé uličky. Ostatní se pak nebudou muset znovu zdržovat zjišťováním, že tudy cesta nevede.

\r\n\r\n

Obsah

\r\n\r\n

Obsahem článku může být tvé řešení některého z problémů zadaných v rámci témat. Pokud se chceš věnovat více problémům zároveň, zvaž, zda je nerozdělit do více článků – dej si pozor, aby jeden článek nemotal páté přes deváté. Kromě řešení zadaných problémů se můžeš v článku věnovat i vlastním otázkám, ať už se týkají některého z témat či nikoliv.

\r\n\r\n

Článek by měl přinášet ostatním řešitelům nové poznatky k vybranému tématu. Právě ostatní řešitelé budou hlavními čtenáři tvého článku, na ně by tedy měla cílit jeho odborná úroveň. Jednoduše, pokud chceš použít nějakou znalost, se kterou se student na střední škole běžně nesetká nebo nebyla zmíněna v tématu, vysvětli ji. Snaž se své objevy popsat jasně a stručně. Článek vůbec nemusí být dlouhý, hlavní je, aby obsahoval všechny důležité informace, se kterými chceš čtenáře seznámit. Vědecký článek není umělecké dílo, neměl by tedy obsahovat květnaté nicneříkající líčení či historky ze života.

\r\n\r\n

Jak má článek vypadat?

\r\n\r\n

Měl by být přehledně strukturován. Nejprve v úvodu představ, čím jsi se zabýval/a. Poslední částí článku by pak měl být závěr, kde shrneš své výsledky a případně navrhneš, jak by se dalo v bádání pokračovat a zmíníš, které otázky zůstávají nezodpovězeny. Samozřejmostí je členění textu na odstavce. Pokud je článek delší, může být vhodné ho rozdělit pomocí podnadpisů.

\r\n\r\n

Co bude hlavním obsahem článku závisí na tom, jaký problém řešíš. Pokud například provádíš experiment, je nutné podrobně popsat nejen výsledky, ale také postup, aby bylo možné jej později zopakovat. Pokud zkoušíš něco teoreticky dokázat či vyvrátit, nezapomeň pečlivě uvést všechny přepoklady, které používáš. Pokud píšeš rešerši, tedy shrnuješ informace nastudované z mnoha různých zdrojů, dej si pozor, ať se držíš tématu a neobjevují se ti v textu informace, které spolu vůbec nesouvisí. Možností, jak může článek vypadat, je mnoho. Zamysli se, jaká forma se bude ve tvém konkrétním případě nejlépe hodit.

\r\n\r\n

Používáš-li při psaní článku nějaké jiné zdroje než vlastní hlavu, nezapomeň je uvést. Snaž se být přiměřeně konkrétní, pokud tedy například používáš delší učebnici, uveď, ve které kapitole se daná informace nachází. Zdroje je dobré uvádět přímo u informací, které jsi z nich čerpal, nejen jako seznam na konci článku. Obvykle se v článku použije jen odkaz, např. „…Jak je uvedeno v [1], můžeme výraz upravit…“ Na konci pak stačí například „[1] Karel Bartuška, Fyzika pro gymnázia – Molekulová fyzika a termika (rok vydání 2005), 3. kapitola“ .

\r\n\r\n

Piš spisovnou češtinou a snaž se vyvarovat překlepů. Článek si po sobě nezapomeň na závěr přečíst, ať v něm nejsou zbytečné, nejen jazykové, chyby.

\r\n\r\n

Inspirace

\r\n\r\n

Pro lepší představu si můžeš prohlédnout články z minulých ročníků:

\r\n\r\n", + "enable_comments": false, + "registration_required": false, + "sites": [ + 1 + ], + "template_name": "", + "title": "Jak psát článek", + "url": "/jak-resit/jak-psat-clanek/" + }, + "model": "flatpages.flatpage", + "pk": 28 + }, + { + "fields": { + "content": "

Jak řešit

\r\n\r\n

V našem semináři simulujeme vědeckou práci. Vydáváme časopis, v němž se věnujeme různým tématům z oblasti matematiky, fyziky, informatiky a občas i jiných oborů.

\r\n\r\n

Témata

\r\n\r\n

Naším cílem je vás prostřednictvím témat seznámit se zajímavými zákoutími matematiky, fyziky a informatiky a inspirovat vás, abyste sami objevovali jejich krásy. Témata většinou obsahují průvodní text od organizátorů. Na něj navazují různé otázky, nad kterými můžeš v průběhu školního roku přemýšlet a bádat. o své výsledky se pak podělíš s námi, my tvou práci ohodnotíme a pošleme ti zpětnou vazbu. Vybrané příspěvky také otiskujeme, takže si je mohou přečíst ostatní řešitelé a reagovat na ně.

\r\n\r\n

Každý ročník vypisujeme zhruba čtyři až šest témat. Pokud si mezi nimi nevybereš, můžeš si položit vlastní otázku, přemýšlet, experimentovat a o svých výsledcích nám napsat článek. Nabízíme ti pár tipů, jak jej napsat pěkně a přehledně. Autora nejlepšího otištěného článku každoročně odměňujeme dortem.

\r\n\r\n

Otázky u jednotlivých témat jsou dvou druhů. Podle toho se bude lišit i formát tvého řešení, jak je popsáno níže.

\r\n\r\n

Úlohy

\r\n\r\n

Jak vypadají?

\r\n\r\n

V rámci témat jsou zadány uzavřené úlohy. Tyto úlohy bývají trochu těžší než obvyklé školní a jejich řešení často vyžaduje hlubší zamyšlení nebo nějaký trik. k jejich vyřešení by ti však měly stačit středoškolské znalosti a pochopení průvodního textu, který tyto znalosti rozvíjí.

\r\n\r\n

Jak na to?

\r\n\r\n

Vyřeš úlohu a pošli nám řešení. Nezapomeň na postup! U každé úlohy je uveden počet bodů za správné řešení, přiměřenou část však lze získat i za řešení neúplné. Neboj se proto poslat své úvahy, i když nedojdeš ke zdárnému konci. Částečné řešení je lepší než žádné. Pokud je naopak tvé řešení velmi elegantní, můžeš získat body navíc.

\r\n\r\n

Používáš-li v řešení nějaké pojmy, které nebyly v rámci témátka definovány a nepatří mezi běžné středoškolské znalosti, nezapomeň jen krátce definovat.

\r\n\r\n

Termín odevzdání

\r\n\r\n

Odevzdávání úloh je omezené termínem odeslání, poté je zveřejněno vzorové řešení. Tím se může stát i tvé pěkně sepsané řešení.

\r\n\r\n

Problémy

\r\n\r\n

Jak vypadají?

\r\n\r\n

Témata poskytují příležitost pro rozsáhlejší zamyšlení a podrobnější rozbor zadaných otázek. Řešení proto obvykle vyžaduje o něco víc prostoru než řešení úlohy. Zároveň je v závislosti na kvalitě štědřeji bodově hodnoceno.

\r\n\r\n

Jak na to?

\r\n\r\n

Řešením problému může být popis (případně videozáznam) provedeného experimentu a diskuze výsledků, popis teoretického výpočtu či napsaného programu, úvaha založená na dosud známých informacích, souhrn dalších (podle tebe zajímavých a nezodpovězených) otázek z daného okruhu nebo jakýkoliv další přístup, který příspívá k řešení problému. Můžeš navrhnout i vlastní problém týkající se tématu a jeho řešení. Řešení konkrétního problému jdoucí do hloubky je bodově hodnoceno výrazně lépe než souhrn krátce zmiňující kdeco.

\r\n\r\n

Řešení problému můžeš sepsat jako článek nebo krátký příspěvek. Napsat článek je trochu náročnější a je tedy lépe bodově hodnocen. Nabízíme ti pár tipů, jak jej pěkně a přehledně napsat. Neboj se však k tématu poslat i méně propracovaný příspěvek, klidně jeden odstavec shrnující tvé myšlenky.

\r\n\r\n

Zaslané řešení vedoucí tématu ohodnotí, případně zkoriguje – probere s tebou, co by bylo vhodné vylepšit, doplnit či upřesnit. Na závěr článek publikujeme na webu či dokonce v čísle.

\r\n\r\n

Inspiruj se a reaguj!

\r\n\r\n

Velmi důležitou vlastností témat je, že můžeš na články ostatních reagovat – rozvíjet je, nebo naopak bořit autorovy představy. Přesně to se děje i při skutečné vědecké práci. Proto se hodí poslat také částečná řešení, postřehy nebo nápady ohledně dalších otázek k tématu, které třeba nezvládneš vyřešit sám. Takovéto příspěvky dávají prostor ostatním a mohou je dál inspirovat a přivést k novým nápadům – ostatní zase svými příspěvky mohou inspirovat či navést k zajímavému nápadu tebe.

\r\n\r\n

Termín odevzdání

\r\n\r\n

Nad problémy k tématům sice můžeš většinou přemýšlet celý rok až do termínu odevzdání poslední série úloh, ale čím dříve nám článek pošleš, tím dříve na něj ostatní budou moci zareagovat. Zároveň se ti nestane, že ti tvůj nápad někdo vyfoukne.

\r\n\r\n

Jak poslat řešení

\r\n\r\n

Řešení jednotlivých témat sepiš samostatně, aby si je mohli vedoucí rozdělit. Nezapomeň uvést své jméno a číslo tématu i jednotlivých úloh a problémů. Svá řešení odevzdej elektronicky v odevzdávátku. Textové řešení ve formátu PDF můžeš doplnit libovolnou přílohou, například videem nebo kódem. Pokud bys měl s odevzdáním nějaký problém, tak nám neváhej napsat na mam@matfyz.cz.

\r\n\r\n

Termíny odevzdání

\r\n\r\n

Každé číslo má dva deadliny pro odevzdání řešení úloh, které jsou v něm otištěné. Pokud pošleš řešení do 1. deadlinu, stihneme ti poslat opravená řešení již s následujícím číslem časopisu, ve kterém se zároveň objeví body, které jsi za toto řešení dostal.

\r\n\r\n

Když tedy v prvním čísle zašleš řešení úlohy do 1. deadlinu, pak se body za něj získané objeví ve druhém čísle. Opravené řešení ti přijde e-mailem před vydáním druhého čísla nebo v obálce s druhým číslem.

\r\n\r\n

Tvá řešení se snažíme opravit co nejdříve a rovnou ti je poslat opravená e-mailem. Pokud ti přijde opravené řešení před 2. deadlinem, máš možnost si jej ještě vylepšit a poslat nám další verzi. Čím dříve své řešení pošleš, tím větší je šance, že jej stihneme opravit s předstihem. Nemůžeme ti to však zcela slíbit.

\r\n\r\n

Úlohy poslané mezi 1. a 2. deadlinem pravděpodobně do následujícího čísla opravit nestihneme, výjimečně se to ale stát může. 2. deadline je finální a úlohy, které přijdou po něm, už nebudou hodnoceny.

\r\n\r\n

Příklad: Pokud tedy úlohu zadanou v prvním čísle pošleš mezi 1. a 2. deadlinem, opravené řešení a body typicky dostaneš až se třetím číslem.

\r\n\r\n

Články

\r\n\r\n

Pokud se rozhodneš poslat řešení formou článku, budeme rádi, pokud to uděláš co nejdřív. Může se totiž stát, že bude potřeba abychom jej před vydáním společně ještě trochu upravili. Na to se hodí, abychom měli my i ty dostatek času. Vždy záleží na konkrétním případu, ale pokud pošleš článek až po 1. deadlinu, je velmi nepravděpodobné, že by se stihl objevit už v následujícím čísle.

\r\n\r\n

Spolupracuj

\r\n\r\n

Protože víc hlav víc ví, můžeš na tématech spolupracovat s ostatními řešiteli. i opravdové vědecké práce často publikuje kolektiv autorů. Pokud se na zaslaném řešení podílí n autorů, dostane každý z nich 3b/(n + 2) bodů, kde b je počet bodů, které by řešení získalo, pokud by mělo jednoho autora.

\r\n\r\n

Ke spolupráci můžeš využít e-mailové konference. Pokud pošleš e-mail na její adresu, přijde všem vedoucím tématu a řešitelům, kteří se jím také zabývají. Pošleš-li k danému tématu alespoň nějaké řešení, automaticky tě přidáme do příslušné konference. Pokud bys chtěl do konference přidat, i když jsi zatím nic neposlal, neboj se nám ozvat.

", + "enable_comments": false, + "registration_required": false, + "sites": [ + 1 + ], + "template_name": "", + "title": "Jak řešit", + "url": "/jak-resit/podrobneji/" + }, + "model": "flatpages.flatpage", + "pk": 29 + } +] diff --git a/data/fotka_header.json b/data/fotka_header.json new file mode 100644 index 00000000..800fce6e --- /dev/null +++ b/data/fotka_header.json @@ -0,0 +1,207 @@ +[ +{ + "model": "header_fotky.fotkaheader", + "pk": "baliky.jpg", + "fields": { + "cas": "2020-09-20T09:18:34.562Z", + "fotka": "header/baliky.jpg" + } +}, +{ + "model": "header_fotky.fotkaheader", + "pk": "beh.jpg", + "fields": { + "cas": "2020-09-20T09:18:34.562Z", + "fotka": "header/beh.jpg" + } +}, +{ + "model": "header_fotky.fotkaheader", + "pk": "kryptografie.jpg", + "fields": { + "cas": "2020-09-20T09:18:34.562Z", + "fotka": "header/kryptografie.jpg" + } +}, +{ + "model": "header_fotky.fotkaheader", + "pk": "mam_cernobile.jpg", + "fields": { + "cas": "2020-09-20T09:18:34.562Z", + "fotka": "header/mam_cernobile.jpg" + } +}, +{ + "model": "header_fotky.fotkaheader", + "pk": "noc.jpg", + "fields": { + "cas": "2020-09-20T09:18:34.562Z", + "fotka": "header/noc.jpg" + } +}, +{ + "model": "header_fotky.fotkaheader", + "pk": "ohen.jpg", + "fields": { + "cas": "2020-09-20T09:18:34.562Z", + "fotka": "header/ohen.jpg" + } +}, +{ + "model": "header_fotky.fotkaheader", + "pk": "snih.jpg", + "fields": { + "cas": "2020-09-20T09:18:34.562Z", + "fotka": "header/snih.jpg" + } +}, +{ + "model": "header_fotky.fotkaheader", + "pk": "spolecna.jpg", + "fields": { + "cas": "2020-09-20T09:18:34.562Z", + "fotka": "header/spolecna.jpg" + } +}, +{ + "model": "header_fotky.fotkaheader", + "pk": "stiny.jpg", + "fields": { + "cas": "2020-09-20T09:18:34.562Z", + "fotka": "header/stiny.jpg" + } +}, +{ + "model": "header_fotky.fotkaheader", + "pk": "vikendovka.jpg", + "fields": { + "cas": "2020-09-20T09:18:34.562Z", + "fotka": "header/vikendovka.jpg" + } +}, +{ + "model": "header_fotky.fotkaheader", + "pk": "vylet.jpg", + "fields": { + "cas": "2020-09-20T09:18:34.562Z", + "fotka": "header/vylet.jpg" + } +}, +{ + "model": "header_fotky.fotkaurlvazba", + "pk": 1, + "fields": { + "url": "/archiv/", + "fotka": "stiny.jpg", + "denni_doba": "oboji" + } +}, +{ + "model": "header_fotky.fotkaurlvazba", + "pk": 2, + "fields": { + "url": "/clanky/", + "fotka": "kryptografie.jpg", + "denni_doba": "den" + } +}, +{ + "model": "header_fotky.fotkaurlvazba", + "pk": 3, + "fields": { + "url": "/clanky/", + "fotka": "ohen.jpg", + "denni_doba": "noc" + } +}, +{ + "model": "header_fotky.fotkaurlvazba", + "pk": 4, + "fields": { + "url": "/aktualni/", + "fotka": "baliky.jpg", + "denni_doba": "den" + } +}, +{ + "model": "header_fotky.fotkaurlvazba", + "pk": 5, + "fields": { + "url": "/aktualni/", + "fotka": "stiny.jpg", + "denni_doba": "noc" + } +}, +{ + "model": "header_fotky.fotkaurlvazba", + "pk": 6, + "fields": { + "url": "/o-nas/", + "fotka": "vikendovka.jpg", + "denni_doba": "den" + } +}, +{ + "model": "header_fotky.fotkaurlvazba", + "pk": 7, + "fields": { + "url": "/o-nas/", + "fotka": "noc.jpg", + "denni_doba": "noc" + } +}, +{ + "model": "header_fotky.fotkaurlvazba", + "pk": 8, + "fields": { + "url": "/soustredeni/", + "fotka": "beh.jpg", + "denni_doba": "den" + } +}, +{ + "model": "header_fotky.fotkaurlvazba", + "pk": 9, + "fields": { + "url": "/soustredeni/", + "fotka": "vylet.jpg", + "denni_doba": "noc" + } +}, +{ + "model": "header_fotky.fotkaurlvazba", + "pk": 10, + "fields": { + "url": "/prihlasit/", + "fotka": "baliky.jpg", + "denni_doba": "den" + } +}, +{ + "model": "header_fotky.fotkaurlvazba", + "pk": 11, + "fields": { + "url": "/prihlasit/", + "fotka": "stiny.jpg", + "denni_doba": "noc" + } +}, +{ + "model": "header_fotky.fotkaurlvazba", + "pk": 12, + "fields": { + "url": "/profil/", + "fotka": "baliky.jpg", + "denni_doba": "den" + } +}, +{ + "model": "header_fotky.fotkaurlvazba", + "pk": 13, + "fields": { + "url": "/profil/", + "fotka": "stiny.jpg", + "denni_doba": "noc" + } +} +] diff --git a/data/sitetree.json b/data/sitetree.json new file mode 100644 index 00000000..bc507430 --- /dev/null +++ b/data/sitetree.json @@ -0,0 +1,860 @@ +[ + { + "fields": { + "alias": "main_menu", + "title": "Hlavní menu" + }, + "model": "sitetree.tree", + "pk": 1 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": null, + "sort_order": 1, + "title": "Co je M&M", + "tree": 1, + "url": "/o-nas/uvod/", + "urlaspattern": false + }, + "model": "sitetree.treeitem", + "pk": 1 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": null, + "sort_order": 2, + "title": "Jak řešit", + "tree": 1, + "url": "/jak-resit/", + "urlaspattern": false + }, + "model": "sitetree.treeitem", + "pk": 2 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": null, + "sort_order": 3, + "title": "Aktuální
ročník", + "tree": 1, + "url": "seminar_aktualni_zadani", + "urlaspattern": true + }, + "model": "sitetree.treeitem", + "pk": 3 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": null, + "sort_order": 4, + "title": "Soustředění", + "tree": 1, + "url": "/soustredeni/", + "urlaspattern": false + }, + "model": "sitetree.treeitem", + "pk": 4 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": null, + "sort_order": 5, + "title": "Archiv", + "tree": 1, + "url": "seminar_archiv_rocniky", + "urlaspattern": true + }, + "model": "sitetree.treeitem", + "pk": 5 + }, + { + "fields": { + "access_guest": true, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": null, + "sort_order": 6, + "title": "Přihlásit", + "tree": 1, + "url": "login", + "urlaspattern": true + }, + "model": "sitetree.treeitem", + "pk": 6 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": 1, + "sort_order": 7, + "title": "Úvod", + "tree": 1, + "url": "/o-nas/uvod/", + "urlaspattern": false + }, + "model": "sitetree.treeitem", + "pk": 7 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": 1, + "sort_order": 8, + "title": "Organizátoři", + "tree": 1, + "url": "organizatori", + "urlaspattern": true + }, + "model": "sitetree.treeitem", + "pk": 8 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": 1, + "sort_order": 10, + "title": "Kontakt", + "tree": 1, + "url": "/o-nas/kontakt/", + "urlaspattern": false + }, + "model": "sitetree.treeitem", + "pk": 10 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": 2, + "sort_order": 11, + "title": "Úvod", + "tree": 1, + "url": "/jak-resit/", + "urlaspattern": false + }, + "model": "sitetree.treeitem", + "pk": 11 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": 2, + "sort_order": 45, + "title": "Jak psát článek", + "tree": 1, + "url": "/jak-resit/jak-psat-clanek/", + "urlaspattern": false + }, + "model": "sitetree.treeitem", + "pk": 12 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": 3, + "sort_order": 43, + "title": "Výsledková listina", + "tree": 1, + "url": "seminar_aktualni_vysledky", + "urlaspattern": true + }, + "model": "sitetree.treeitem", + "pk": 16 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": 4, + "sort_order": 18, + "title": "Úvod", + "tree": 1, + "url": "/soustredeni/", + "urlaspattern": false + }, + "model": "sitetree.treeitem", + "pk": 18 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": 4, + "sort_order": 19, + "title": "Připravujeme", + "tree": 1, + "url": "/soustredeni/pripravujeme/", + "urlaspattern": false + }, + "model": "sitetree.treeitem", + "pk": 19 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": 4, + "sort_order": 20, + "title": "Proběhlo", + "tree": 1, + "url": "seminar_seznam_soustredeni", + "urlaspattern": true + }, + "model": "sitetree.treeitem", + "pk": 20 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": true, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": null, + "sort_order": 21, + "title": "Profil", + "tree": 1, + "url": "profil", + "urlaspattern": true + }, + "model": "sitetree.treeitem", + "pk": 21 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": 21, + "sort_order": 23, + "title": "Osobní údaje", + "tree": 1, + "url": "seminar_resitel_edit", + "urlaspattern": true + }, + "model": "sitetree.treeitem", + "pk": 22 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [ + 2 + ], + "access_restricted": true, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": 21, + "sort_order": 36, + "title": "Poslat řešení", + "tree": 1, + "url": "seminar_nahraj_reseni", + "urlaspattern": true + }, + "model": "sitetree.treeitem", + "pk": 23 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": 5, + "sort_order": 35, + "title": "Témata", + "tree": 1, + "url": "seminar_archiv_temata", + "urlaspattern": true + }, + "model": "sitetree.treeitem", + "pk": 24 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [ + 1 + ], + "access_restricted": true, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": null, + "sort_order": 28, + "title": "HIDDEN", + "tree": 1, + "url": "/korektury/", + "urlaspattern": false + }, + "model": "sitetree.treeitem", + "pk": 28 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": 28, + "sort_order": 30, + "title": "Aktuální", + "tree": 1, + "url": "korektury_list", + "urlaspattern": true + }, + "model": "sitetree.treeitem", + "pk": 30 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": 28, + "sort_order": 31, + "title": "Zastaralé", + "tree": 1, + "url": "korektury_stare_list", + "urlaspattern": true + }, + "model": "sitetree.treeitem", + "pk": 31 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": 28, + "sort_order": 32, + "title": "Nápověda", + "tree": 1, + "url": "/korektury/help/", + "urlaspattern": false + }, + "model": "sitetree.treeitem", + "pk": 32 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": 3, + "sort_order": 15, + "title": "Aktuální číslo", + "tree": 1, + "url": "seminar_aktualni_zadani", + "urlaspattern": true + }, + "model": "sitetree.treeitem", + "pk": 33 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": 5, + "sort_order": 24, + "title": "Čísla", + "tree": 1, + "url": "seminar_archiv_rocniky", + "urlaspattern": true + }, + "model": "sitetree.treeitem", + "pk": 35 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": 21, + "sort_order": 22, + "title": "Úvod", + "tree": 1, + "url": "profil", + "urlaspattern": true + }, + "model": "sitetree.treeitem", + "pk": 36 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [ + 1 + ], + "access_restricted": true, + "alias": null, + "description": "", + "hidden": false, + "hint": "To, co ŘEŠITELÉ poslali", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": 21, + "sort_order": 38, + "title": "Došlá řešení", + "tree": 1, + "url": "odevzdavatko_tabulka", + "urlaspattern": true + }, + "model": "sitetree.treeitem", + "pk": 37 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": true, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": 21, + "sort_order": 42, + "title": "Odhlásit se", + "tree": 1, + "url": "logout", + "urlaspattern": true + }, + "model": "sitetree.treeitem", + "pk": 38 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [ + 1 + ], + "access_restricted": true, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": 21, + "sort_order": 36, + "title": "Nahrát řešení", + "tree": 1, + "url": "seminar_vloz_reseni", + "urlaspattern": true + }, + "model": "sitetree.treeitem", + "pk": 39 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": 5, + "sort_order": 40, + "title": "Řešitelské články", + "tree": 1, + "url": "/archiv/clanky", + "urlaspattern": false + }, + "model": "sitetree.treeitem", + "pk": 40 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": 1, + "sort_order": 41, + "title": "Odměny", + "tree": 1, + "url": "/o-nas/odmeny/", + "urlaspattern": false + }, + "model": "sitetree.treeitem", + "pk": 41 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [ + 2 + ], + "access_restricted": true, + "alias": null, + "description": "", + "hidden": false, + "hint": "To, co jsem JÁ odevzdal", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": 21, + "sort_order": 37, + "title": "Odevzdaná řešení", + "tree": 1, + "url": "seminar_resitel_odevzdana_reseni", + "urlaspattern": true + }, + "model": "sitetree.treeitem", + "pk": 42 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": 3, + "sort_order": 33, + "title": "Aktuální ročník", + "tree": 1, + "url": "seminar_aktualni_rocnik", + "urlaspattern": true + }, + "model": "sitetree.treeitem", + "pk": 43 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": 1, + "sort_order": 44, + "title": "Další aktivity", + "tree": 1, + "url": "/o-nas/dalsi-akce/", + "urlaspattern": false + }, + "model": "sitetree.treeitem", + "pk": 44 + }, + { + "fields": { + "access_guest": false, + "access_loggedin": false, + "access_perm_type": 1, + "access_permissions": [], + "access_restricted": false, + "alias": null, + "description": "", + "hidden": false, + "hint": "", + "inbreadcrumbs": true, + "inmenu": true, + "insitetree": true, + "parent": 2, + "sort_order": 12, + "title": "Podrobněji", + "tree": 1, + "url": "/jak-resit/podrobneji/", + "urlaspattern": false + }, + "model": "sitetree.treeitem", + "pk": 45 + } +] diff --git a/db_compare.py b/db_compare.py new file mode 100755 index 00000000..031bde86 --- /dev/null +++ b/db_compare.py @@ -0,0 +1,513 @@ +#!/usr/bin/env python3 + +import psycopg2 +import psycopg2.extras + +OLD_DB = "mam_old" +NEW_DB = "mamweb" + +oldconn = psycopg2.connect(f"dbname={OLD_DB}") +newconn = psycopg2.connect(f"dbname={NEW_DB}") + +oldcur = oldconn.cursor(cursor_factory=psycopg2.extras.DictCursor) +newcur = newconn.cursor(cursor_factory=psycopg2.extras.DictCursor) + + +# Uses global variables oldcur, newcur! +def execute_simple(old_query, new_query=None): + if new_query is None: + new_query = old_query + + oldcur.execute(old_query) + newcur.execute(new_query) + + if oldcur.rowcount != newcur.rowcount: + raise ValueError(f"Queries '{old_query}' and '{new_query}' returned different number of rows ({oldcur.rowcount} and {newcur.rowcount})") + + return(oldcur.fetchall(), newcur.fetchall()) + +def check_same(old_row, new_row, old_fields, new_fields=None): + if type(old_fields) != list: + old_fields = [old_fields] + + if new_fields is None: + new_fields = old_fields + + fields = zip(old_fields, new_fields) + + for old_field, new_field in fields: + if old_row[old_field] == new_row[new_field]: + continue + raise ValueError(f"Fields '{old_field}'({old_row[old_field]}) and '{new_field}'({new_row[new_field]}) differs for rows \n'{old_row}' and \n'{new_row}'") + return True + +def get_user_id_for_org_id(org_id): + query = """SELECT auth_user.id FROM auth_user + INNER JOIN seminar_osoby ON seminar_osoby.user_id = auth_user.id + INNER JOIN seminar_organizator ON seminar_organizator.osoba_id = seminar_osoby.id + WHERE seminar_organizator.id = %s """ + + newcur.execute(query,(org_id,)) + return newcur.fetchone()['id'] + + + + +def check_skola(): + old_query = "SELECT * FROM seminar_skoly ORDER BY id" + + old_res, new_res = execute_simple(old_query) + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n,['id','aesop_id','izo','nazev','kratky_nazev','ulice','mesto','psc','stat','je_zs','je_ss','poznamka']) + +def check_resitel(): + old_query = 'SELECT * FROM seminar_resitele ORDER BY id' + new_query = '''SELECT seminar_resitele.id, skola_id, rok_maturity, zasilat, seminar_resitele.poznamka, + o.jmeno AS jmeno, o.prijmeni AS prijmeni, o.user_id AS user_id, o.pohlavi_muz AS pohlavi_muz, o.email AS email, o.telefon AS telefon, o.datum_narozeni AS datum_narozeni, + o.datum_souhlasu_udaje AS datum_souhlasu_udaje, o.datum_souhlasu_zasilani AS datum_souhlasu_zasilani, o.datum_registrace AS datum_prihlaseni, o.ulice AS ulice, o.mesto AS mesto, o.psc AS psc, o.stat AS stat + FROM seminar_resitele JOIN seminar_osoby AS o ON seminar_resitele.osoba_id = o.id ORDER BY seminar_resitele.id''' + + old_res, new_res = execute_simple(old_query,new_query) + + res = zip(old_res,new_res) + + fields_osoba = [ + 'jmeno', + 'prijmeni', + 'user_id', + 'pohlavi_muz', + #'email', #vyreseno separatne + 'telefon', + 'datum_narozeni', + 'datum_souhlasu_udaje', + 'datum_souhlasu_zasilani', + 'datum_prihlaseni', + 'ulice', + 'mesto', + 'psc', + 'stat', + ] + fields_keep = [ + 'id', + 'skola_id', + 'rok_maturity', + 'zasilat', + 'poznamka', + ] + fields = fields_keep+fields_osoba + for o,n in res: + check_same(o,n,fields) + if o['email'] != n['email'] and o['email'] != '': + print(f"WARNING: Emails differ: old: {o['email']}, new: {n['email']}") + +def check_reseni(): + # Migrace 0058 zamerne meni (zmensuje) pocet reseni, aby kazdy clanek mel + # jen jedno reseni (s vice resiteli, coz postaru neslo) + # Kvuli tomu je potreba kontrolovat dve veci: + # 1) Ze kazdy resitel dostal za kazdy problem spravne bodu + # 2) Ze detaily reseni zustaly zachovany + + # Cast 1) + old_query = 'SELECT * FROM seminar_reseni ORDER BY problem_id, resitel_id, body, timestamp' + new_query = '''SELECT seminar_reseni.id, forma, seminar_reseni.poznamka, cas_doruceni, hodnoceni.problem_id AS problem_id, hodnoceni.body AS body, hodnoceni.cislo_body_id AS cislo_body_id, res.id AS resitel_id + FROM seminar_reseni + JOIN seminar_hodnoceni AS hodnoceni ON seminar_reseni.id = hodnoceni.reseni_id + JOIN seminar_reseni_resitele AS rr ON seminar_reseni.id = rr.reseni_id + JOIN seminar_resitele AS res ON res.id = rr.resitele_id + ORDER BY problem_id, resitel_id, body, cas_doruceni''' + + # Po spojeni nekterych problemu se lisi casy doruceni a poznamky, proto je nebudeme kontrolovat (jde v podstate o triviality, tak je to snad jedno) + same_fields = ['forma', 'problem_id', 'body', 'cislo_body_id', 'resitel_id'] + renamed_fields = [ + #('timestamp', 'cas_doruceni'), + ] + old_fields = same_fields + [f[0] for f in renamed_fields] + new_fields = same_fields + [f[1] for f in renamed_fields] + + old_res, new_res = execute_simple(old_query, new_query) + + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n,old_fields, new_fields) + + # Cast 2) + # Query se lisi tim, ze uz nejoinujeme resitele. + old_query = 'SELECT * FROM seminar_reseni ORDER BY id' + new_query = '''SELECT seminar_reseni.id, forma, poznamka, cas_doruceni AS timestamp, h.problem_id AS problem_id, h.body AS body, h.cislo_body_id AS cislo_body_id + FROM seminar_reseni + JOIN seminar_hodnoceni AS h ON h.reseni_id = seminar_reseni.id + ORDER BY id''' + + # execute_simple kontroluje stejnost poctu radku, to nechceme. + oldcur.execute(old_query) + newcur.execute(new_query) + old_res, new_res = oldcur.fetchall(), newcur.fetchall() + # Zkontrolujeme, ze pro kazde nove reseni ma stare reseni spravna data. + new_ids = [n['id'] for n in new_res] + spravna_old = list(filter(lambda o: o['id'] in new_ids, old_res)) + res = zip(spravna_old,new_res) + for o,n in res: + # Tady by se poznamky i timestampy mely zachovat + # Z nejakeho duvodu se ale poznamky lisi ve whitespace, tak je zkontrolujeme separatne + check_same(o,n,['id', 'forma', 'timestamp', 'problem_id', 'body', 'cislo_body_id']) + old_pozn = o['poznamka'].strip() + new_pozn = n['poznamka'].strip() + if old_pozn != new_pozn: + raise ValueError('Poznamky se lisi pro radky {dict(o)} a {dict(n)}') + + + +def check_organizator(): + old_query = 'SELECT * FROM seminar_organizator ORDER BY id' + new_query = '''SELECT seminar_organizator.id AS id, studuje, strucny_popis_organizatora, users.id AS uid, osoba.prezdivka AS o_prezdivka, osoba.foto AS o_foto, organizuje_od, organizuje_do + FROM seminar_organizator + JOIN seminar_osoby AS osoba ON osoba_id = osoba.id + JOIN auth_user AS users ON osoba.user_id = users.id + ORDER BY seminar_organizator.id''' + + same_fields = ['studuje', 'strucny_popis_organizatora'] + renamed_fields = [ + ('user_id', 'uid'), + #('prezdivka', 'o_prezdivka'), + ('foto', 'o_foto'), + ] + old_fields = same_fields + [f[0] for f in renamed_fields] + new_fields = same_fields + [f[1] for f in renamed_fields] + + old_res, new_res = execute_simple(old_query,new_query) + res = zip(old_res, new_res) + for o,n in res: + check_same(o,n,old_fields, new_fields) + # organizuje od, do: + # Migrace prirazuje aktualni casovou zonu, takze chceme tady rucne vynutit CET. + from datetime import timedelta, timezone + cet = timezone(timedelta(hours=1)) + if o['organizuje_od_roku'] is None and n['organizuje_od'] is None: + pass + elif o['organizuje_od_roku'] != n['organizuje_od'].astimezone(cet).year: + raise ValueError(f'Not matching organizuje_od for org id={o["id"]}: old {o["organizuje_od_roku"]}, new {n["organizuje_od"]}') + if o['organizuje_do_roku'] is None and n['organizuje_do'] is None: + pass + elif o['organizuje_do_roku'] != n['organizuje_do'].astimezone(cet).year: + raise ValueError(f'Not matching organizuje_do for org id={o["id"]}: old {o["organizuje_do_roku"]}, new {n["organizuje_do"]}') + if o['prezdivka'] == n['o_prezdivka']: + continue + if o['prezdivka'] is None and n['o_prezdivka'] == '': + continue + raise ValueError(f'Not matching prezdivka for org id={o["id"]}: old {o["prezdivka"]}, new {n["o_prezdivka"]}') + + +def check_rocnik(): + old_query = "SELECT * FROM seminar_rocniky ORDER BY id" + + old_res, new_res = execute_simple(old_query) + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n,['id','prvni_rok', 'rocnik', 'exportovat']) + +def check_cislo(): + old_query = "SELECT * FROM seminar_cisla ORDER BY id" + + old_res, new_res = execute_simple(old_query) + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n, ['id','rocnik_id','cislo', 'datum_vydani','datum_deadline','verejne','poznamka','pdf'], + ['id','rocnik_id','poradi','datum_vydani','datum_deadline','verejne','poznamka','pdf']) + +def check_priloha_reseni(): + old_query = "SELECT * FROM seminar_priloha_reseni" + + old_res, new_res = execute_simple(old_query) + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n, ['id','reseni_id', 'timestamp', 'soubor', 'poznamka'], + ['id','reseni_id', 'vytvoreno', 'soubor', 'poznamka']) + +def check_soustredeni(): + old_query = "SELECT * FROM seminar_soustredeni ORDER BY id" + + old_res, new_res = execute_simple(old_query) + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n,['id','rocnik_id','datum_zacatku','datum_konce','verejne','misto','text','typ','exportovat']) + #Kontrola ucasnici, organizatori v samostatnych funkcich + +def check_soustredeni_ucastnici(): + old_query = "SELECT * FROM seminar_soustredeni_ucastnici ORDER BY id" + + old_res, new_res = execute_simple(old_query) + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n,['id','resitel_id','soustredeni_id','poznamka']) + +def check_soustredeni_organizatori(): + old_query = "SELECT * FROM seminar_soustredeni_organizatori ORDER BY id" + + old_res, new_res = execute_simple(old_query) + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n,['id','organizator_id','soustredeni_id','poznamka']) + +def check_nastaveni(): + old_query = "SELECT * FROM seminar_nastaveni ORDER BY id" + + old_res, new_res = execute_simple(old_query) + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n,['id','aktualni_cislo_id']) + +def check_novinky(): + old_query = "SELECT * FROM seminar_novinky ORDER BY id" + + old_res, new_res = execute_simple(old_query) + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n,['id','datum','text','obrazek','zverejneno']) + if get_user_id_for_org_id(n['autor_id']) != o['autor_id']: + raise ValueError("Nesedi autori u novinek") + +def check_pohadka(): + old_query = "SELECT * FROM seminar_pohadky ORDER BY id" + new_query = """SELECT sp.id AS id, sp.autor_id AS autor_id, sp.vytvoreno AS vytvoreno, snp.treenode_ptr_id AS treenode_ptr_id, st.na_web AS text, + zn_pred.uloha_id AS uloha_pred, zn_po.uloha_id AS uloha_po + FROM seminar_pohadky AS sp + -- Text pohádky + INNER JOIN seminar_nodes_pohadka AS snp ON sp.id = snp.pohadka_id + INNER JOIN seminar_nodes_treenode AS snt ON snt.id = snp.treenode_ptr_id + INNER JOIN seminar_nodes_obsah AS sno ON sno.treenode_ptr_id = snt.first_child_id + INNER JOIN seminar_texty AS st ON sno.text_id = st.id + -- Predchozí úloha + LEFT OUTER JOIN seminar_nodes_treenode AS ztn_pred ON ztn_pred.succ_id = snt.id + LEFT OUTER JOIN seminar_nodes_uloha_zadani AS zn_pred ON zn_pred.treenode_ptr_id = ztn_pred.id + -- Následující úloha + LEFT OUTER JOIN seminar_nodes_uloha_zadani AS zn_po ON zn_po.treenode_ptr_id = snt.succ_id + + ORDER BY sp.id""" + + old_res, new_res = execute_simple(old_query,new_query) + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n,['id','timestamp','text'],['id','vytvoreno','text']) + if o['autor_id'] is not None: + if get_user_id_for_org_id(n['autor_id']) != o['autor_id']: + raise ValueError("Nesedi autori u pohadky") + # Správné úlohy + # NOTE: o['pred'] rika, zda je pohadka pred ulohou, nikoliv zda je relevantni uloha pred pohadkou! + spravny_klic = 'uloha_po' if o['pred'] else 'uloha_pred' + if o['uloha_id'] != n[spravny_klic]: + raise ValueError(f"Pohádka přidružená ke špatné úloze! old: {o['uloha_id']}, new: {n[spravny_klic]}, pozice: {spravny_klic}") + + +# Problémy jsou rozdělené podle typů: +def check_problem_common(): + old_query = "SELECT id, nazev, stav, kod, autor_id, text_org, timestamp, typ FROM seminar_problemy ORDER BY id" + new_query = """SELECT sp.id AS id, sp.nazev AS nazev, sp.stav AS stav, sp.kod AS kod, au.id AS autor_id, sp.poznamka AS poznamka, sp.vytvoreno AS vytvoreno + FROM seminar_problemy AS sp + LEFT OUTER JOIN seminar_organizator AS so ON sp.autor_id = so.id + LEFT OUTER JOIN seminar_osoby AS sos ON so.osoba_id = sos.id + LEFT OUTER JOIN auth_user AS au ON sos.user_id = au.id + ORDER BY sp.id""" + + same_fields = ['id', 'nazev', 'stav', 'autor_id', 'kod'] + renamed_fields = [ + ('text_org', 'poznamka'), + ('timestamp', 'vytvoreno'), + ] + old_fields = same_fields + [f[0] for f in renamed_fields] + new_fields = same_fields + [f[1] for f in renamed_fields] + + old_res, new_res = execute_simple(old_query,new_query) + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n, old_fields, new_fields) + + # Opravovatelé + # Po staru byli opravovatele organizatori, takze je potreba je dohledat. + old_query = """SELECT seminar_problemy.id, org.id AS opravovatel_id FROM seminar_problemy + JOIN seminar_organizator AS org ON seminar_problemy.opravovatel_id = org.user_id;""" + new_query = "SELECT problem_id, organizator_id FROM seminar_problemy_opravovatele" + + # Simple cursors + #oldcur = oldconn.cursor() + oldcur.execute(old_query) + old_results = oldcur.fetchall() + #newcur = newconn.cursor() + newcur.execute(new_query) + new_results = newcur.fetchall() + + for oldr in old_results: + if oldr not in new_results: + raise ValueError(f'Opravovatel pair {oldr} not found in new db.') + + # Zaměření se vyřeší okometricky (#1186) + + +def check_uloha(): + old_query = "SELECT * FROM seminar_problemy WHERE typ = 'uloha' ORDER BY id" + new_query = """SELECT cislo_zadani_id, cislo_reseni_id, problem_ptr_id, max_body, COALESCE(uzt.na_web, '') AS text_zadani, COALESCE(uvt.na_web, '') AS text_reseni, cislo_deadline_id + FROM seminar_ulohy + -- Problém: + JOIN seminar_problemy AS problem ON problem_ptr_id = problem.id + -- Text zadání: + -- ZadaniNode a VzorakNode maji existovat vzdy, ale obsah nemusi (pokud ho nemaji) + INNER JOIN seminar_nodes_uloha_zadani AS uzn ON problem.id = uzn.uloha_id + INNER JOIN seminar_nodes_treenode AS uztn ON uztn.id = uzn.treenode_ptr_id + LEFT OUTER JOIN seminar_nodes_obsah AS uzo ON uzo.treenode_ptr_id = uztn.first_child_id + LEFT OUTER JOIN seminar_texty AS uzt ON uzo.text_id = uzt.id + -- Text vzoráku: + INNER JOIN seminar_nodes_uloha_vzorak AS uvn ON problem.id = uvn.uloha_id + INNER JOIN seminar_nodes_treenode AS uvtn ON uvtn.id = uvn.treenode_ptr_id + LEFT OUTER JOIN seminar_nodes_obsah AS uvo ON uvo.treenode_ptr_id = uvtn.first_child_id + LEFT OUTER JOIN seminar_texty AS uvt ON uvo.text_id = uvt.id + + ORDER BY problem_ptr_id""" + + same_fields = ['cislo_zadani_id', 'cislo_reseni_id', 'text_zadani', 'text_reseni'] + renamed_fields = [ + ('id', 'problem_ptr_id'), + ('body', 'max_body'), + ] + old_fields = same_fields + [f[0] for f in renamed_fields] + new_fields = same_fields + [f[1] for f in renamed_fields] + + old_res, new_res = execute_simple(old_query, new_query) + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n, old_fields, new_fields) + # Datum deadline vypadá prázdně, tak to budeme předpokládat. + if n['cislo_deadline_id'] is not None: + raise ValueError("Úloha má deadline.") + +def check_tema(): + old_query = """SELECT text_zadani, text_reseni, typ, c.rocnik_id AS rocnik_id + FROM seminar_problemy + LEFT OUTER JOIN seminar_cisla AS c ON c.id = cislo_zadani_id + WHERE typ IN ('tema', 'serial') + ORDER BY seminar_problemy.id""" + new_query = """SELECT tema_typ, COALESCE(zad_text.na_web, '') AS text_zadani, COALESCE(res_text.na_web, '') AS text_reseni, rn.rocnik_id AS rocnik_id + FROM seminar_temata + -- Problém: + JOIN seminar_problemy AS problem ON problem_ptr_id = problem.id + -- Text: + -- TvCNode má dva potomky, oba TextNode. První drží původní text zadání, druhý řešení. + INNER JOIN seminar_nodes_temavcisle AS tvcn ON tvcn.tema_id = id + INNER JOIN seminar_nodes_treenode AS ttn ON tvcn.treenode_ptr_id = ttn.id + LEFT OUTER JOIN seminar_nodes_treenode AS zad_tn ON ttn.first_child_id = zad_tn.id -- jen 33 z nich ma zadani + LEFT OUTER JOIN seminar_nodes_treenode AS res_tn ON zad_tn.succ_id = res_tn.id -- jen 4 z nich ma reseni + LEFT OUTER JOIN seminar_nodes_obsah AS zad_on ON zad_on.treenode_ptr_id = zad_tn.id + LEFT OUTER JOIN seminar_nodes_obsah AS res_on ON res_on.treenode_ptr_id = res_tn.id + LEFT OUTER JOIN seminar_texty AS zad_text ON zad_on.text_id = zad_text.id + LEFT OUTER JOIN seminar_texty AS res_text ON res_on.text_id = res_text.id -- vsechny 4 + -- Ročník tématu: + -- Podle rootu TvCN + LEFT OUTER JOIN seminar_nodes_rocnik AS rn ON ttn.root_id = rn.treenode_ptr_id + + ORDER BY problem_ptr_id""" + same_fields = ['text_zadani', 'text_reseni', 'rocnik_id'] + renamed_fields = [ + ('typ', 'tema_typ'), + ] + old_fields = same_fields + [f[0] for f in renamed_fields] + new_fields = same_fields + [f[1] for f in renamed_fields] + + old_res, new_res = execute_simple(old_query, new_query) + res = zip(old_res,new_res) + + for o,n in res: + check_same(o,n, old_fields, new_fields) + +def check_konfera(): + old_query = "SELECT * FROM seminar_problemy WHERE typ = 'konfera'" + new_query = "SELECT * FROM seminar_konfera" + + oldcur.execute(old_query) + newcur.execute(new_query) + + if oldcur.rowcount != 0 or newcur.rowcount != 0: + raise ValueError('There exists a Konfera!') + +def check_org_clanek(): + old_query = "SELECT * FROM seminar_problemy WHERE typ = 'org-clanek'" + + oldcur.execute(old_query) + + if oldcur.rowcount != 0: + raise ValueError('There exists a Org-clanek!') + +def check_res_clanek(): + # Dva(!) články mají text (zadání), který se má zachovat. + old_query = "SELECT * FROM seminar_problemy WHERE typ = 'res-clanek' ORDER BY id" + new_query = """SELECT cislo_id, text.na_web AS text_zadani + FROM seminar_clanky + JOIN seminar_problemy AS problem ON problem_ptr_id = problem.id + INNER JOIN seminar_hodnoceni AS hodn ON problem.id = hodn.problem_id + INNER JOIN seminar_reseni AS rese ON rese.id = hodn.reseni_id + INNER JOIN seminar_nodes_otistene_reseni AS rn ON rese.text_cely_id = rn.treenode_ptr_id -- Tenhle radek neni potreba, ale ujistuje se mj. o spravnem typu TreeNode. + INNER JOIN seminar_nodes_treenode AS tn ON rn.treenode_ptr_id = tn.id + -- Nektere clanky vubec nemely text, tak jim migr 0058 nevyrobila dalsi treenody + LEFT OUTER JOIN seminar_nodes_obsah AS son ON son.treenode_ptr_id = tn.first_child_id + LEFT OUTER JOIN seminar_texty AS text ON text.id = son.text_id + + ORDER BY problem_ptr_id""" + same_fields = ['text_zadani'] + renamed_fields = [ + ('cislo_zadani_id', 'cislo_id'), + ] + old_fields = same_fields + [f[0] for f in renamed_fields] + new_fields = same_fields + [f[1] for f in renamed_fields] + + old_res, new_res = execute_simple(old_query, new_query) + res = zip(old_res,new_res) + + for o,n in res: + # text_zadani po novu mohl byt None + if n['text_zadani'] is None: + n['text_zadani'] = '' + check_same(o,n, old_fields, new_fields) + assert(o['text_reseni'] == '') + +def check_untyped_problem(): + old_query = "SELECT * FROM seminar_problemy WHERE typ NOT IN ('uloha', 'tema', 'serial', 'konfera', 'org-clanek', 'res-clanek')" + + oldcur.execute(old_query) + + if oldcur.rowcount != 0: + raise ValueError('There exists a Problem without type!') + + + +check_skola() +check_resitel() +check_reseni() +check_organizator() +check_rocnik() +check_cislo() +check_priloha_reseni() +check_soustredeni() +check_soustredeni_ucastnici() +check_soustredeni_organizatori() +check_nastaveni() +check_novinky() +check_pohadka() + +check_problem_common() +check_uloha() +check_tema() +check_konfera() +check_org_clanek() +check_res_clanek() +check_untyped_problem() diff --git a/deploy_v2/README b/deploy_v2/README new file mode 100644 index 00000000..dec6d746 --- /dev/null +++ b/deploy_v2/README @@ -0,0 +1,3 @@ +Tahle slozka obsahuje vsechny detaily a popisy, jak nasadit "druhou verzi" M&M webu. + +TODO: chybi tu popis na zprovozneni flatpages, na loaddata &c. diff --git a/deploy_v2/full_redeploy.sh b/deploy_v2/full_redeploy.sh new file mode 100644 index 00000000..cec9c15c --- /dev/null +++ b/deploy_v2/full_redeploy.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +set -u + +deactivate || true + +cd /akce/mam/www/mamweb-test/ +make sync_test +systemctl --user stop mamweb-test.service +rm -rvf env +make install_venv +. env/bin/activate +make install +deploy_v2/pre_migration.py +make deploy_test +./manage.py load_org_permissions admin_org_prava.json +./manage.py loaddata data/* +systemctl --user start mamweb-test.service +./manage.py generate_thumbnails + +echo 'Et voilá!' +echo 'Nezapomeň opravit práva pro sitetree!' diff --git a/deploy_v2/post_deploy.txt b/deploy_v2/post_deploy.txt new file mode 100644 index 00000000..ff6275da --- /dev/null +++ b/deploy_v2/post_deploy.txt @@ -0,0 +1,3 @@ +Jsou špatně práva k sitetree (protože se používají primární klíče, které jsou jiné :-() +Špatné položky se dají najít pomocí následujícího příkazu: + grep -E 'access_permissions": \[$' data/sitetree.json -A17 | grep -E 'acc|tit' -A2 diff --git a/deploy_v2/pre_migration.py b/deploy_v2/pre_migration.py new file mode 100755 index 00000000..7501976f --- /dev/null +++ b/deploy_v2/pre_migration.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 + +import os +import sys + +import django + +#### Inicializace Djanga +sys.path.append(os.path.dirname(os.path.realpath(__file__))+'/..') +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mamweb.settings') +django.setup() + +## Pozor, nejde pouzit ORM, protoze kod je na jine verzi nez databaze a nejde namigrovat. +from django.db import connection + + +def smaz_zle_clanky(): + # Tyhle clanky vubec nejsou clanky, bude potreba je udelat cele jinak a spravne. + #m.Problem.objects.filter(id__in=[1981, 1970, 2222]).delete() + ## with connection.cursor() as cursor: + ## # Nejdriv musime smazat reseni: + ## cursor.execute('DELETE FROM seminar_reseni WHERE problem_id IN (1981, 1970, 2222);') + ## # Nakonec i ty clanky samotne + ## cursor.execute('DELETE FROM seminar_problemy WHERE id IN (1981, 1970, 2222);') + + # Update: stejně je v DB bordel, tak z nich prostě jen udělám témata a všechno zhruba přežije… + with connection.cursor() as cursor: + cursor.execute("UPDATE seminar_problemy SET typ = 'tema' WHERE id IN (1981, 1970, 2222);") + +def smaz_divne_uzivatele(): + # U techto uzivatelu neexistuje Organizator s nimi spojeny + # Takze pak delaji akorat neporadek + with connection.cursor() as cursor: + # Jeste je potreba zrusit vazby + cursor.execute('UPDATE django_comments SET user_id = NULL WHERE user_id = 34;') + cursor.execute('UPDATE seminar_problemy SET autor_id = NULL WHERE autor_id = 34;') + cursor.execute('DELETE FROM django_admin_log WHERE user_id = 34;') + cursor.execute('DELETE FROM auth_user_groups WHERE user_id = 34;') + cursor.execute('DELETE FROM auth_user WHERE id IN (34, 40, 30, 50, 54, 58, 43);') + +smaz_zle_clanky() +smaz_divne_uzivatele() diff --git a/fix_json.py b/fix_json.py new file mode 100755 index 00000000..411349f2 --- /dev/null +++ b/fix_json.py @@ -0,0 +1,12 @@ +#!/usr/bin/python3 + +import json +import argparse + +parser = argparse.ArgumentParser() +parser.add_argument("input", type=argparse.FileType('r', encoding='utf-8')) +parser.add_argument('output', type=argparse.FileType('w', encoding='utf-8')) +args = parser.parse_args() + +data = json.load(args.input) +json.dump(data, args.output, ensure_ascii=False, sort_keys=True, indent='\t') diff --git a/galerie/admin.py b/galerie/admin.py index 0ca32dc9..54b0751e 100644 --- a/galerie/admin.py +++ b/galerie/admin.py @@ -5,50 +5,50 @@ from django.contrib import admin from django.http import HttpResponseRedirect from django import forms from django.db import models -from autocomplete_light import shortcuts as autocomplete_light # akction def zverejnit_fotogalerii(modeladmin, request, queryset): - '''zverejni vybranou fotogalerii i jeji vsechny podgalerie''' - for galerie in queryset: - galerie.zobrazit = 0 - galerie.save() - zverejnit_fotogalerii(modeladmin, request, - Galerie.objects.filter(galerie_up = galerie)) - zverejnit_fotogalerii.short_description = 'Zveřejnit fotogalerie' + '''zverejni vybranou fotogalerii i jeji vsechny podgalerie''' + for galerie in queryset: + galerie.zobrazit = 0 + galerie.save() + zverejnit_fotogalerii(modeladmin, request, + Galerie.objects.filter(galerie_up = galerie)) + zverejnit_fotogalerii.short_description = 'Zveřejnit fotogalerie' def prepnout_fotogalerii_do_org_rezimu(modeladmin, request, queryset): - '''zneverjni vybranou fotogalerii i jeji vsechny podgalerie''' - for galerie in queryset: - galerie.zobrazit = 1 - galerie.save() - prepnout_fotogalerii_do_org_rezimu(modeladmin, request, - Galerie.objects.filter(galerie_up = galerie)) - prepnout_fotogalerii_do_org_rezimu.short_description = \ - 'Přepnout do režimu úprav (zneveřejní galerii)' + '''zneverjni vybranou fotogalerii i jeji vsechny podgalerie''' + for galerie in queryset: + galerie.zobrazit = 1 + galerie.save() + prepnout_fotogalerii_do_org_rezimu(modeladmin, request, + Galerie.objects.filter(galerie_up = galerie)) + prepnout_fotogalerii_do_org_rezimu.short_description = \ + 'Přepnout do režimu úprav (zneveřejní galerii)' class GalerieInline(admin.TabularInline): - model = Obrazek - fields = ['obrazek_velky', 'nazev', 'popis', 'obrazek_maly_tag', 'poradi'] - readonly_fields = ['nazev', 'obrazek_maly_tag'] - formfield_overrides = { - models.TextField: {'widget': forms.TextInput}, - } + model = Obrazek + fields = ['obrazek_velky', 'nazev', 'popis', 'obrazek_maly_tag', 'poradi'] + readonly_fields = ['nazev', 'obrazek_maly_tag'] + formfield_overrides = { + models.TextField: {'widget': forms.TextInput}, + } class ObrazekAdmin(admin.ModelAdmin): - list_display = ('obrazek_velky', 'nazev', 'popis', 'obrazek_maly_tag', 'poradi') - + list_display = ('obrazek_velky', 'nazev', 'popis', 'obrazek_maly_tag', 'poradi') + search_fields = ['nazev','popis'] + class GalerieAdmin(admin.ModelAdmin): - form = autocomplete_light.modelform_factory(Galerie, autocomplete_fields=['titulni_obrazek'], fields=['titulni_obrazek']) - model = Galerie - fields = ('zobrazit', 'nazev', 'titulni_obrazek', 'popis', 'galerie_up', 'soustredeni', 'poradi') - list_display = ('nazev', 'soustredeni', 'galerie_up', 'poradi', 'zobrazit', 'datum_zmeny') - inlines = [GalerieInline] - actions = [zverejnit_fotogalerii, prepnout_fotogalerii_do_org_rezimu] - save_on_top = True - ordering = ['galerie_up__nazev', 'poradi'] + model = Galerie + fields = ('zobrazit', 'nazev', 'titulni_obrazek', 'popis', 'galerie_up', 'soustredeni', 'poradi') + autocomplete_fields = ['titulni_obrazek'] + list_display = ('nazev', 'soustredeni', 'galerie_up', 'poradi', 'zobrazit', 'datum_zmeny') + inlines = [GalerieInline] + actions = [zverejnit_fotogalerii, prepnout_fotogalerii_do_org_rezimu] + save_on_top = True + ordering = ['galerie_up__nazev', 'poradi'] admin.site.register(Obrazek, ObrazekAdmin) admin.site.register(Galerie, GalerieAdmin) diff --git a/galerie/autocomplete_light_registry.py b/galerie/autocomplete_light_registry.py.old similarity index 92% rename from galerie/autocomplete_light_registry.py rename to galerie/autocomplete_light_registry.py.old index 69dc6a5b..dcedfc1a 100644 --- a/galerie/autocomplete_light_registry.py +++ b/galerie/autocomplete_light_registry.py.old @@ -1,11 +1,9 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals - from autocomplete_light import shortcuts as autocomplete_light -from models import Obrazek, Galerie -from views import cesta_od_korene +from .models import Obrazek, Galerie +from .views import cesta_od_korene class ObrazekAutocomplete(autocomplete_light.AutocompleteModelBase): diff --git a/galerie/forms.py b/galerie/forms.py index 1cadb3fc..e6666884 100644 --- a/galerie/forms.py +++ b/galerie/forms.py @@ -4,8 +4,8 @@ from django import forms from seminar.models import Soustredeni class KomentarForm(forms.Form): - komentar = forms.CharField(label = "Komentář:", max_length = 300, required=False) + komentar = forms.CharField(label = "Komentář:", max_length = 300, required=False) class NewGalerieForm(forms.Form): - nazev = forms.CharField(label = "Název galerie", max_length = 100) - #popis = forms.CharField(label = "Popis", required = False, max_length = 2000, widget = forms.Textarea) + nazev = forms.CharField(label = "Název galerie", max_length = 100) + #popis = forms.CharField(label = "Popis", required = False, max_length = 2000, widget = forms.Textarea) diff --git a/galerie/migrations/0001_initial.py b/galerie/migrations/0001_initial.py index b7406da6..21701185 100644 --- a/galerie/migrations/0001_initial.py +++ b/galerie/migrations/0001_initial.py @@ -21,8 +21,8 @@ class Migration(migrations.Migration): ('datum_zmeny', models.DateTimeField(auto_now=True, verbose_name=b'Datum posledn\xc3\xad zm\xc4\x9bny')), ('popis', models.TextField(null=True, verbose_name=b'Popis', blank=True)), ('zobrazit', models.IntegerField(default=1, verbose_name=b'Zobrazit?', choices=[(0, b'V\xc5\xbedy'), (1, b'Organiz\xc3\xa1tor\xc5\xafm'), (2, b'Nikdy')])), - ('galerie_up', models.ForeignKey(blank=True, to='galerie.Galerie', null=True)), - ('soustredeni', models.ForeignKey(blank=True, to='seminar.Soustredeni', null=True)), + ('galerie_up', models.ForeignKey(blank=True, to='galerie.Galerie', null=True, on_delete=models.CASCADE)), + ('soustredeni', models.ForeignKey(blank=True, to='seminar.Soustredeni', null=True, on_delete=models.CASCADE)), ], options={ 'verbose_name': 'Galerie', @@ -42,7 +42,7 @@ class Migration(migrations.Migration): ('datum_vlozeni', models.DateTimeField(auto_now_add=True, verbose_name=b'Datum vlo\xc5\xbeen\xc3\xad')), ('datum', models.DateTimeField(verbose_name=b'Datum po\xc5\x99\xc3\xadzen\xc3\xad fotografie')), ('poradi', models.IntegerField(null=True, verbose_name=b'Po\xc5\x99ad\xc3\xad', blank=True)), - ('galerie', models.ForeignKey(to='galerie.Galerie')), + ('galerie', models.ForeignKey(to='galerie.Galerie', on_delete=models.CASCADE)), ], options={ 'verbose_name': 'Obr\xe1zek', diff --git a/galerie/migrations/0004_nepovinna_galerie_u_obrazku.py b/galerie/migrations/0004_nepovinna_galerie_u_obrazku.py index c522adfe..53e17922 100644 --- a/galerie/migrations/0004_nepovinna_galerie_u_obrazku.py +++ b/galerie/migrations/0004_nepovinna_galerie_u_obrazku.py @@ -14,7 +14,7 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='obrazek', name='galerie', - field=models.ForeignKey(blank=True, to='galerie.Galerie', null=True), + field=models.ForeignKey(blank=True, to='galerie.Galerie', null=True, on_delete=models.CASCADE), preserve_default=True, ), ] diff --git a/galerie/migrations/0008_auto_20190430_2340.py b/galerie/migrations/0008_auto_20190430_2340.py new file mode 100644 index 00000000..140d554a --- /dev/null +++ b/galerie/migrations/0008_auto_20190430_2340.py @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-04-30 21:40 +from __future__ import unicode_literals + +from django.db import migrations, models +import galerie.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('galerie', '0007_obrazek_odstranen_datum'), + ] + + operations = [ + migrations.AlterField( + model_name='galerie', + name='datum_vytvoreni', + field=models.DateTimeField(auto_now_add=True, verbose_name='Datum vytvoření'), + ), + migrations.AlterField( + model_name='galerie', + name='datum_zmeny', + field=models.DateTimeField(auto_now=True, verbose_name='Datum poslední změny'), + ), + migrations.AlterField( + model_name='galerie', + name='nazev', + field=models.CharField(max_length=100, verbose_name='Název'), + ), + migrations.AlterField( + model_name='galerie', + name='popis', + field=models.TextField(blank=True, null=True, verbose_name='Popis'), + ), + migrations.AlterField( + model_name='galerie', + name='poradi', + field=models.IntegerField(blank=True, null=True, verbose_name='Pořadí'), + ), + migrations.AlterField( + model_name='galerie', + name='zobrazit', + field=models.IntegerField(choices=[(0, 'Vždy'), (1, 'Organizátorům'), (2, 'Nikdy')], default=1, verbose_name='Zobrazit?'), + ), + migrations.AlterField( + model_name='obrazek', + name='datum_vlozeni', + field=models.DateTimeField(auto_now_add=True, verbose_name='Datum vložení'), + ), + migrations.AlterField( + model_name='obrazek', + name='nazev', + field=models.CharField(blank=True, max_length=50, null=True, verbose_name='Název'), + ), + migrations.AlterField( + model_name='obrazek', + name='obrazek_velky', + field=models.ImageField(help_text='Lze vložit libovolně velký obrázek. Ideální je, aby alespoň jeden rozměr měl alespoň 500px.', upload_to=galerie.models.obrazek_filename), + ), + migrations.AlterField( + model_name='obrazek', + name='popis', + field=models.TextField(blank=True, null=True, verbose_name='Popis'), + ), + migrations.AlterField( + model_name='obrazek', + name='poradi', + field=models.IntegerField(blank=True, null=True, verbose_name='Pořadí'), + ), + ] diff --git a/galerie/migrations/0009_auto_20190610_2358.py b/galerie/migrations/0009_auto_20190610_2358.py new file mode 100644 index 00000000..0228a8a7 --- /dev/null +++ b/galerie/migrations/0009_auto_20190610_2358.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.21 on 2019-06-10 21:58 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('galerie', '0008_auto_20190430_2340'), + ] + + operations = [ + migrations.AlterField( + model_name='galerie', + name='galerie_up', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='galerie.Galerie'), + ), + migrations.AlterField( + model_name='galerie', + name='soustredeni', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Soustredeni'), + ), + migrations.AlterField( + model_name='obrazek', + name='galerie', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='galerie.Galerie'), + ), + ] diff --git a/galerie/migrations/0008_auto_20191209_2326.py b/galerie/migrations/0010_auto_20200819_0947.py similarity index 59% rename from galerie/migrations/0008_auto_20191209_2326.py rename to galerie/migrations/0010_auto_20200819_0947.py index 12e605f4..b7678ac1 100644 --- a/galerie/migrations/0008_auto_20191209_2326.py +++ b/galerie/migrations/0010_auto_20200819_0947.py @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.26 on 2019-12-09 22:26 -from __future__ import unicode_literals +# Generated by Django 2.2.15 on 2020-08-19 07:47 from django.db import migrations, models @@ -8,13 +6,13 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('galerie', '0007_obrazek_odstranen_datum'), + ('galerie', '0009_auto_20190610_2358'), ] operations = [ migrations.AlterField( model_name='galerie', name='poradi', - field=models.IntegerField(blank=True, default=0, verbose_name=b'Po\xc5\x99ad\xc3\xad'), + field=models.IntegerField(blank=True, default=0, verbose_name='Pořadí'), ), ] diff --git a/galerie/models.py b/galerie/models.py index 1b64194c..8e6efdc7 100644 --- a/galerie/models.py +++ b/galerie/models.py @@ -2,7 +2,7 @@ from django.db import models #from django.db.models import Q -from django.utils.encoding import force_unicode +from django.utils.encoding import force_text from imagekit.models import ImageSpecField from imagekit.processors import ResizeToFit, Transpose @@ -14,109 +14,112 @@ VZDY=0 ORG=1 NIKDY=2 VIDITELNOST = ( - (VZDY, 'Vždy'), - (ORG, 'Organizátorům'), - (NIKDY, 'Nikdy'), + (VZDY, 'Vždy'), + (ORG, 'Organizátorům'), + (NIKDY, 'Nikdy'), ) # tyhle funkce jsou tady jen kvůli starým migracím, které se na ně odkazují # až se ty migrace někdy squashnou, tak by mělo být možné funkce smazat def obrazek_filename_maly(): - pass + pass def obrazek_filename_stredni(): - pass + pass def obrazek_filename_velky(): - pass + pass def obrazek_filename(self, filename): - gal = self.galerie - cislo_gal = force_unicode(gal.pk) + gal = self.galerie + cislo_gal = gal.pk - # najdi kořenovou galerii - while (gal.galerie_up): - gal = gal.galerie_up + # najdi kořenovou galerii + while (gal.galerie_up): + gal = gal.galerie_up - # soustředění je v cestě jen pokud galerie pod nějaké patří - cesta = ( - ['Galerie'] + - (["soustredeni_" + force_unicode(gal.soustredeni.pk)] if gal.soustredeni else []) + - ["galerie_" + cislo_gal, force_unicode(self.nazev)] - ) + # soustředění je v cestě jen pokud galerie pod nějaké patří + cesta = ( + ['Galerie'] + + (["soustredeni_{}".format(gal.soustredeni.pk)] if gal.soustredeni else []) + + ["galerie_{}".format(cislo_gal), self.nazev] + ) - return os.path.join(*cesta) + return os.path.join(*cesta) class Obrazek(models.Model): - obrazek_velky = models.ImageField(upload_to=obrazek_filename, - help_text = "Lze vložit libovolně velký obrázek. Ideální je, aby alespoň jeden rozměr měl alespoň 500px.") - obrazek_stredni = ImageSpecField(source='obrazek_velky', - processors=[Transpose(Transpose.AUTO), ResizeToFit(900, 675, upscale=False)], - options={'quality': 95}) - obrazek_maly = ImageSpecField(source='obrazek_velky', - processors=[Transpose(Transpose.AUTO), ResizeToFit(167, 167, upscale=False)], - options={'quality': 95}) - nazev = models.CharField('Název', max_length=50, blank=True, null=True) - popis = models.TextField('Popis', blank=True, null=True) - datum_vlozeni = models.DateTimeField('Datum vložení', auto_now_add=True) - galerie = models.ForeignKey('Galerie', blank=True, null=True) - poradi = models.IntegerField('Pořadí', blank=True, null=True) - - def __unicode__(self): - return unicode(self.obrazek_velky.name) - - class Meta: - verbose_name = 'Obrázek' - verbose_name_plural = 'Obrázky' - ordering = ['nazev'] - - def obrazek_maly_tag(self): - return u''.format(self.obrazek_maly.url) - obrazek_maly_tag.short_description = "Náhled" - obrazek_maly_tag.allow_tags = True - - def save(self, *args, **kwargs): - # obrázek potřebuje název, protože se z něj generuje cesta pro jeho uložení - # (a pak se podle něj taky řadí) - if self.nazev is None: - self.nazev = os.path.basename(self.obrazek_velky.name) - super(Obrazek, self).save(*args, **kwargs) - - + obrazek_velky = models.ImageField(upload_to=obrazek_filename, + help_text = "Lze vložit libovolně velký obrázek. Ideální je, aby alespoň jeden rozměr měl alespoň 500px.") + obrazek_stredni = ImageSpecField(source='obrazek_velky', + processors=[Transpose(Transpose.AUTO), ResizeToFit(900, 675, upscale=False)], + options={'quality': 95}) + obrazek_maly = ImageSpecField(source='obrazek_velky', + processors=[Transpose(Transpose.AUTO), ResizeToFit(167, 167, upscale=False)], + options={'quality': 95}) + nazev = models.CharField('Název', max_length=50, blank=True, null=True) + popis = models.TextField('Popis', blank=True, null=True) + datum_vlozeni = models.DateTimeField('Datum vložení', auto_now_add=True) + galerie = models.ForeignKey('Galerie', blank=True, null=True, on_delete=models.SET_NULL) + poradi = models.IntegerField('Pořadí', blank=True, null=True) + + def __str__(self): + return self.obrazek_velky.name + + class Meta: + verbose_name = 'Obrázek' + verbose_name_plural = 'Obrázky' + ordering = ['nazev'] + + def obrazek_maly_tag(self): + if not self.obrazek_maly: + return '' + return u''.format(self.obrazek_maly.url) + obrazek_maly_tag.short_description = "Náhled" + obrazek_maly_tag.allow_tags = True + + def save(self, *args, **kwargs): + # obrázek potřebuje název, protože se z něj generuje cesta pro jeho uložení + # (a pak se podle něj taky řadí) + if self.nazev is None: + self.nazev = os.path.basename(self.obrazek_velky.name) + super(Obrazek, self).save(*args, **kwargs) + class Galerie(models.Model): - nazev = models.CharField('Název', max_length=100) - datum_vytvoreni = models.DateTimeField('Datum vytvoření', auto_now_add = True) - datum_zmeny = models.DateTimeField('Datum poslední změny', auto_now = True) - popis = models.TextField('Popis', blank = True, null = True) - titulni_obrazek = models.ForeignKey(Obrazek, blank = True, null = True, related_name = "+", on_delete = models.SET_NULL) - zobrazit = models.IntegerField('Zobrazit?', default = ORG, choices = VIDITELNOST) - galerie_up = models.ForeignKey('Galerie', blank = True, null = True) - soustredeni = models.ForeignKey(Soustredeni, blank = True, null = True) - poradi = models.IntegerField('Pořadí', blank = True, null = False, default = 0) - - def __unicode__(self): - return self.nazev - class Meta: - verbose_name = 'Galerie' - verbose_name_plural = 'Galerie' - - #def link_na_preview(self): - #"""Odkaz na galerii, používá se v admin rozhranní. """ - #return 'Preview' % self.id - #link_na_preview.allow_tags = True - #link_na_preview.short_description = 'Zobrazit galerii' + nazev = models.CharField('Název', max_length=100) + datum_vytvoreni = models.DateTimeField('Datum vytvoření', auto_now_add = True) + datum_zmeny = models.DateTimeField('Datum poslední změny', auto_now = True) + popis = models.TextField('Popis', blank = True, null = True) + titulni_obrazek = models.ForeignKey(Obrazek, blank = True, null = True, related_name = "+", on_delete = models.SET_NULL) + zobrazit = models.IntegerField('Zobrazit?', default = ORG, choices = VIDITELNOST) + galerie_up = models.ForeignKey('Galerie', blank = True, null = True, + on_delete=models.SET_NULL) + soustredeni = models.ForeignKey(Soustredeni, blank = True, null = True, + on_delete=models.PROTECT) + poradi = models.IntegerField('Pořadí', blank = True, null = False, default = 0) + + def __str__(self): + return self.nazev + class Meta: + verbose_name = 'Galerie' + verbose_name_plural = 'Galerie' + + #def link_na_preview(self): + #"""Odkaz na galerii, používá se v admin rozhranní. """ + #return 'Preview' % self.id + #link_na_preview.allow_tags = True + #link_na_preview.short_description = 'Zobrazit galerii' # - #def je_publikovano(self): - #"""Vraci True, pokud je tato galerie publikovana. """ - #if self.zobrazit == VZDY: - #return True - #if self.zobrazit == PODLE_CLANKU: - #for clanek in self.clanek_set.all(): - #if clanek.je_publikovano(): - #return True - #return False + #def je_publikovano(self): + #"""Vraci True, pokud je tato galerie publikovana. """ + #if self.zobrazit == VZDY: + #return True + #if self.zobrazit == PODLE_CLANKU: + #for clanek in self.clanek_set.all(): + #if clanek.je_publikovano(): + #return True + #return False # - #@staticmethod - #def publikovane_galerie(): - #"""Vraci galerie, ktere uz maji byt publikovane.""" - #clanky = Blog.models.Clanek.publikovane_clanky() - #return Galerie.objects.filter(Q(zobrazit=VZDY) | (Q(clanek__in=clanky) & Q(zobrazit=PODLE_CLANKU))).distinct() + #@staticmethod + #def publikovane_galerie(): + #"""Vraci galerie, ktere uz maji byt publikovane.""" + #clanky = Blog.models.Clanek.publikovane_clanky() + #return Galerie.objects.filter(Q(zobrazit=VZDY) | (Q(clanek__in=clanky) & Q(zobrazit=PODLE_CLANKU))).distinct() diff --git a/galerie/static/galerie/prvky/dalsi.png b/galerie/static/galerie/prvky/dalsi.png deleted file mode 100644 index b5c68dcc..00000000 Binary files a/galerie/static/galerie/prvky/dalsi.png and /dev/null differ diff --git a/galerie/static/galerie/prvky/dalsi.svg b/galerie/static/galerie/prvky/dalsi.svg new file mode 100644 index 00000000..e928adb2 --- /dev/null +++ b/galerie/static/galerie/prvky/dalsi.svg @@ -0,0 +1,65 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/galerie/static/galerie/prvky/nahoru.png b/galerie/static/galerie/prvky/nahoru.png deleted file mode 100644 index d297af60..00000000 Binary files a/galerie/static/galerie/prvky/nahoru.png and /dev/null differ diff --git a/galerie/static/galerie/prvky/predchozi.png b/galerie/static/galerie/prvky/predchozi.png deleted file mode 100644 index dc657411..00000000 Binary files a/galerie/static/galerie/prvky/predchozi.png and /dev/null differ diff --git a/galerie/static/galerie/prvky/predchozi.svg b/galerie/static/galerie/prvky/predchozi.svg new file mode 100644 index 00000000..b7a491ed --- /dev/null +++ b/galerie/static/galerie/prvky/predchozi.svg @@ -0,0 +1,65 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/galerie/templates/galerie/Base.html b/galerie/templates/galerie/Base.html deleted file mode 100644 index 61f96eb4..00000000 --- a/galerie/templates/galerie/Base.html +++ /dev/null @@ -1,6 +0,0 @@ -{% extends "base.html" %} - -{# TODO predelat pres context processor #} -{% block header %}soustredeni{% endblock %} -{% block menu_soustredeni %}selected{% endblock %} -{% block submenu %}{% include 'seminar/soustredeni/submenu.html' %}{% endblock %} diff --git a/galerie/templates/galerie/Galerie.html b/galerie/templates/galerie/Galerie.html index c23c6c42..b2dfe994 100644 --- a/galerie/templates/galerie/Galerie.html +++ b/galerie/templates/galerie/Galerie.html @@ -1,4 +1,4 @@ -{% extends "galerie/Base.html" %} +{% extends "base.html" %} {% block nadpis1a %} diff --git a/galerie/templates/galerie/GalerieNahled.html b/galerie/templates/galerie/GalerieNahled.html index 7d9313fc..ec0d5f67 100644 --- a/galerie/templates/galerie/GalerieNahled.html +++ b/galerie/templates/galerie/GalerieNahled.html @@ -1,4 +1,4 @@ -{% extends "galerie/Base.html" %} +{% extends "base.html" %} {% block nadpis1a %} Galerie {{galerie.nazev}} @@ -61,7 +61,7 @@ Galerie {{galerie.nazev}} {{ galerie|truncatechars:max_delka_nazvu }} - {% if user.is_staff and galerie.zobrazit > 0 %} + {% if user.je_org and galerie.zobrazit > 0 %}
({{galerie.poradi}}) + @@ -73,7 +73,7 @@ Galerie {{galerie.nazev}} {% endwith %} {% endif %} {% endif %} - {% if user.is_staff and galerie.zobrazit > 0 %} + {% if user.je_org and galerie.zobrazit > 0 %} diff --git a/galerie/templates/galerie/GalerieNew.html b/galerie/templates/galerie/GalerieNew.html index 38237d86..2da23ece 100644 --- a/galerie/templates/galerie/GalerieNew.html +++ b/galerie/templates/galerie/GalerieNew.html @@ -1,4 +1,4 @@ -{% extends "galerie/Base.html" %} +{% extends "base.html" %} {% block title %}{% block nadpis1a %} Vytvářím novou galerii diff --git a/galerie/urls.py b/galerie/urls.py index 4b015e44..d299165f 100644 --- a/galerie/urls.py +++ b/galerie/urls.py @@ -1,13 +1,14 @@ # coding: utf-8 -from django.conf.urls import include, url +from django.urls import path +from seminar.utils import org_required from . import views urlpatterns = [ - url(r'^(?P\d+)/$', views.nahled), - url(r'^(?P\d+)/(?P\d+)/$', views.detail), - url(r'^(?P\d+)/new/$', views.new_galerie), - url(r'^(?P\d+)/plus/(?P\d+)/$', views.plus_galerie), - url(r'^(?P\d+)/minus/(?P\d+)/$', views.minus_galerie), + path('/', views.nahled), + path('//', views.detail), + path('/new/', org_required(views.new_galerie)), + path('/plus//', org_required(views.plus_galerie)), + path('/minus//', org_required(views.minus_galerie)), ] diff --git a/galerie/views.py b/galerie/views.py index 916a869b..4570b8fb 100644 --- a/galerie/views.py +++ b/galerie/views.py @@ -12,226 +12,225 @@ from seminar.models import Soustredeni from galerie.forms import KomentarForm, NewGalerieForm def zobrazit(galerie, request): - preview = False - if galerie.zobrazit >= 1: - if request.user.is_staff: - preview = True; - else: - raise Http404 - return preview + preview = False + if galerie.zobrazit >= 1: + if request.user.je_org: + preview = True; + else: + raise Http404 + return preview def cesta_od_korene(g): - """Vrátí seznam galerií od kořene ke g""" - cesta = [] - while g != None: - cesta.append(g) - g = g.galerie_up - return reversed(cesta) + """Vrátí seznam galerií od kořene ke g""" + cesta = [] + while g != None: + cesta.append(g) + g = g.galerie_up + return reversed(cesta) def nahled(request, pk, soustredeni): - """Zobrazeni nahledu vsech fotek ve skupine.""" - galerie = get_object_or_404(Galerie, pk=pk) - - podgalerie = Galerie.objects.filter(galerie_up = galerie).order_by('poradi') - if not request.user.is_staff: - podgalerie = podgalerie.filter(zobrazit__lt=1) - - obrazky = Obrazek.objects.filter(galerie = galerie).order_by('poradi', 'nazev') - preview = zobrazit(galerie, request) - - sourozenci = [] - if galerie.galerie_up: - sourozenci = galerie.galerie_up.galerie_set.all().order_by('poradi') - if not request.user.is_staff: - sourozenci = sourozenci.filter(zobrazit__lt=1) - - predchozi = None - nasledujici = None - minuly = None - for g in sourozenci: - if g.pk == galerie.pk: - predchozi = minuly - if minuly != None and minuly.pk == galerie.pk: - nasledujici = g - break - minuly = g - - cesta = cesta_od_korene(galerie) - - return render(request, 'galerie/GalerieNahled.html', - {'galerie' : galerie, - 'podgalerie' : podgalerie, - 'obrazky' : obrazky, - 'preview' : preview, - 'cesta': cesta, - 'sourozenci': sourozenci, - 'predchozi': predchozi, - 'nasledujici': nasledujici, - }) + """Zobrazeni nahledu vsech fotek ve skupine.""" + galerie = get_object_or_404(Galerie, pk=pk) + + podgalerie = Galerie.objects.filter(galerie_up = galerie).order_by('poradi') + if not request.user.je_org: + podgalerie = podgalerie.filter(zobrazit__lt=1) + + obrazky = Obrazek.objects.filter(galerie = galerie).order_by('poradi', 'nazev') + preview = zobrazit(galerie, request) + + sourozenci = [] + if galerie.galerie_up: + sourozenci = galerie.galerie_up.galerie_set.all().order_by('poradi') + if not request.user.je_org: + sourozenci = sourozenci.filter(zobrazit__lt=1) + + predchozi = None + nasledujici = None + minuly = None + for g in sourozenci: + if g.pk == galerie.pk: + predchozi = minuly + if minuly != None and minuly.pk == galerie.pk: + nasledujici = g + break + minuly = g + + cesta = cesta_od_korene(galerie) + + return render(request, 'galerie/GalerieNahled.html', + {'galerie' : galerie, + 'podgalerie' : podgalerie, + 'obrazky' : obrazky, + 'preview' : preview, + 'cesta': cesta, + 'sourozenci': sourozenci, + 'predchozi': predchozi, + 'nasledujici': nasledujici, + }) def detail(request, pk, fotka, soustredeni): - """Zobrazeni nahledu fotky s id 'fotka'.""" - MAX_VYSKA = 900 - MAX_SIRKA = 900 - MAX_VYSKA_MALA = 100 - MAX_SIRKA_MALA = 200 - NAHLEDU = 1 - - galerie = get_object_or_404(Galerie, pk=pk) - preview = zobrazit(galerie, request) - obrazek = get_object_or_404(Obrazek, pk=fotka) - obrazky = galerie.obrazek_set.all().order_by('poradi', 'nazev') - - # vytvoreni a obslouzeni formulare - if request.method == 'POST': - form = KomentarForm(request.POST) - if form.is_valid(): - obrazek.popis = form.cleaned_data['komentar'] - obrazek.save() - else: - form = KomentarForm({'komentar': obrazek.popis}) - - # Poradi aktualniho obrazku v galerii/stitku. - for i in range(len(obrazky)): - if obrazky[i] == obrazek: - poradi = i - break - else: - # Obrazek neni v galerii/stitku. - raise Http404 - - - # Nacteni okolnich obrazku a galerii - # TODO vyjmout zjisteni predchozich a nasledujicich galerii - # a udelat z toho funkci, ktera se pouzije u nahledu - predchozi_galerie = None - nasledujici_galerie = None - obrazky_dalsi = obrazky[poradi+1:poradi+NAHLEDU+1] - if (poradi+1) > NAHLEDU: - obrazky_predchozi = obrazky[poradi-NAHLEDU:poradi] - else: - obrazky_predchozi = obrazky[0:poradi] - if galerie.poradi > 1: - predchozi_galerie = Galerie.objects.\ - filter(galerie_up=galerie.galerie_up).\ - filter(poradi=(galerie.poradi-1)) - if predchozi_galerie: - predchozi_galerie = predchozi_galerie[0] - else: - predchozi_galerie = None - if (poradi+1) == len(obrazky): # Tohle je poslední obrázek - if (galerie.poradi is not None - and galerie.galerie_up is not None): - nasledujici_galerie = Galerie.objects.\ - filter(galerie_up=galerie.galerie_up).\ - filter(poradi=(galerie.poradi+1)) - else: - nasledujici_galerie = None - if nasledujici_galerie: - nasledujici_galerie = nasledujici_galerie[0] - else: - nasledujici_galerie = None - - - - # Preskalovani obrazku do vybraneho prostoru. - vyska = obrazek.obrazek_stredni.height - sirka = obrazek.obrazek_stredni.width - if vyska > MAX_VYSKA: - sirka = sirka * MAX_VYSKA / vyska - vyska = MAX_VYSKA - if sirka > MAX_SIRKA: - vyska = vyska * MAX_SIRKA / sirka - sirka = MAX_SIRKA - - return render(request, 'galerie/Galerie.html', - {'galerie' : galerie, - 'predchozi_galerie' : predchozi_galerie, - 'nasledujici_galerie' : nasledujici_galerie, - 'obrazek' : obrazek, - 'vyska' : vyska, - 'sirka' : sirka, - 'obrazky_predchozi' : obrazky_predchozi, - 'obrazky_dalsi' : obrazky_dalsi, - 'preview' : preview, - 'form' : form, - 'cesta': cesta_od_korene(galerie), - }) - + """Zobrazeni nahledu fotky s id 'fotka'.""" + MAX_VYSKA = 900 + MAX_SIRKA = 900 + MAX_VYSKA_MALA = 100 + MAX_SIRKA_MALA = 200 + NAHLEDU = 1 + + galerie = get_object_or_404(Galerie, pk=pk) + preview = zobrazit(galerie, request) + obrazek = get_object_or_404(Obrazek, pk=fotka) + obrazky = galerie.obrazek_set.all().order_by('poradi', 'nazev') + + # vytvoreni a obslouzeni formulare + if request.method == 'POST': + form = KomentarForm(request.POST) + if form.is_valid(): + obrazek.popis = form.cleaned_data['komentar'] + obrazek.save() + else: + form = KomentarForm({'komentar': obrazek.popis}) + + # Poradi aktualniho obrazku v galerii/stitku. + for i in range(len(obrazky)): + if obrazky[i] == obrazek: + poradi = i + break + else: + # Obrazek neni v galerii/stitku. + raise Http404 + + + # Nacteni okolnich obrazku a galerii + # TODO vyjmout zjisteni predchozich a nasledujicich galerii + # a udelat z toho funkci, ktera se pouzije u nahledu + predchozi_galerie = None + nasledujici_galerie = None + obrazky_dalsi = obrazky[poradi+1:poradi+NAHLEDU+1] + if (poradi+1) > NAHLEDU: + obrazky_predchozi = obrazky[poradi-NAHLEDU:poradi] + else: + obrazky_predchozi = obrazky[0:poradi] + if galerie.poradi > 1: + predchozi_galerie = Galerie.objects.\ + filter(galerie_up=galerie.galerie_up).\ + filter(poradi=(galerie.poradi-1)) + if predchozi_galerie: + predchozi_galerie = predchozi_galerie[0] + else: + predchozi_galerie = None + if (poradi+1) == len(obrazky): # Tohle je poslední obrázek + if (galerie.poradi is not None + and galerie.galerie_up is not None): + nasledujici_galerie = Galerie.objects.\ + filter(galerie_up=galerie.galerie_up).\ + filter(poradi=(galerie.poradi+1)) + else: + nasledujici_galerie = None + if nasledujici_galerie: + nasledujici_galerie = nasledujici_galerie[0] + else: + nasledujici_galerie = None + + + + # Preskalovani obrazku do vybraneho prostoru. + vyska = obrazek.obrazek_stredni.height + sirka = obrazek.obrazek_stredni.width + if vyska > MAX_VYSKA: + sirka = sirka * MAX_VYSKA / vyska + vyska = MAX_VYSKA + if sirka > MAX_SIRKA: + vyska = vyska * MAX_SIRKA / sirka + sirka = MAX_SIRKA + + return render(request, 'galerie/Galerie.html', + {'galerie' : galerie, + 'predchozi_galerie' : predchozi_galerie, + 'nasledujici_galerie' : nasledujici_galerie, + 'obrazek' : obrazek, + 'vyska' : vyska, + 'sirka' : sirka, + 'obrazky_predchozi' : obrazky_predchozi, + 'obrazky_dalsi' : obrazky_dalsi, + 'preview' : preview, + 'form' : form, + 'cesta': cesta_od_korene(galerie), + }) def new_galerie(request, galerie, soustredeni): - # zjistime k jakemu soustredeni se vaze nove vytvarena galerie - soustredeni = get_object_or_404(Soustredeni, pk = soustredeni) - # pokud je parametr galerie 0, pak jde o hlavni galerii - # kdyz je nejaky jiny, pak je pk galerie pod kterou tu dalsi vytvarim - if int(galerie) == 0: - galerie_up = False - galerie_text = "Hlavní fotogalerie soustředění" - else: - galerie_up = get_object_or_404(Galerie, pk = int(galerie)) - galerie_text = "podgalerii ke galerii " + str(galerie_up) - - # obsluha formulare umoznujiciho multiple nahravani fotek - if request.method == 'POST': - form = NewGalerieForm(request.POST, request.FILES) - if form.is_valid(): - # vytvoreni nove galerie - gal = Galerie() - gal.nazev = form.cleaned_data['nazev'] - #gal.popis = form.cleaned_data['popis'] # popis nepouzivame - gal.zobrazit = 1 # galerie je v procesu vytvareni - ''' pokud je to podgalerie pridej nadrazenou galerii - a nadrazene soustredeni nechej volne, - pokud je to hlavni galerie, tak nadrazena galerie neexistuje, - ale v takovem pripade musi byt nadrazene soustredeni a ne jinak ''' - if galerie_up: - gal.galerie_up = galerie_up - else: - gal.soustredeni = soustredeni - if gal.galerie_up: - gal.poradi = int(len(gal.galerie_up.galerie_set.all())) + 1 - gal.save() - - # zpracovani obrazku v galerii - for obr in request.FILES.getlist('obr'): - o = Obrazek() - o.obrazek_velky = obr - o.nazev = str(obr) - o.galerie = gal - o.save() - - # presmerovani na prave vzniklou galerii - return HttpResponseRedirect('../../' + str(gal.pk)) - - else: - form = NewGalerieForm() - - - return render(request, 'galerie/GalerieNew.html', - { - 'form' : form, - 'soustredeni' : soustredeni, - 'galerie_text' : galerie_text, - }) + # zjistime k jakemu soustredeni se vaze nove vytvarena galerie + soustredeni = get_object_or_404(Soustredeni, pk = soustredeni) + # pokud je parametr galerie 0, pak jde o hlavni galerii + # kdyz je nejaky jiny, pak je pk galerie pod kterou tu dalsi vytvarim + if int(galerie) == 0: + galerie_up = False + galerie_text = "Hlavní fotogalerie soustředění" + else: + galerie_up = get_object_or_404(Galerie, pk = int(galerie)) + galerie_text = "podgalerii ke galerii " + str(galerie_up) + + # obsluha formulare umoznujiciho multiple nahravani fotek + if request.method == 'POST': + form = NewGalerieForm(request.POST, request.FILES) + if form.is_valid(): + # vytvoreni nove galerie + gal = Galerie() + gal.nazev = form.cleaned_data['nazev'] + #gal.popis = form.cleaned_data['popis'] # popis nepouzivame + gal.zobrazit = 1 # galerie je v procesu vytvareni + ''' pokud je to podgalerie pridej nadrazenou galerii + a nadrazene soustredeni nechej volne, + pokud je to hlavni galerie, tak nadrazena galerie neexistuje, + ale v takovem pripade musi byt nadrazene soustredeni a ne jinak ''' + if galerie_up: + gal.galerie_up = galerie_up + else: + gal.soustredeni = soustredeni + if gal.galerie_up: + gal.poradi = int(len(gal.galerie_up.galerie_set.all())) + 1 + gal.save() + + # zpracovani obrazku v galerii + for obr in request.FILES.getlist('obr'): + o = Obrazek() + o.obrazek_velky = obr + o.nazev = str(obr) + o.galerie = gal + o.save() + + # presmerovani na prave vzniklou galerii + return HttpResponseRedirect('../../' + str(gal.pk)) + + else: + form = NewGalerieForm() + + + return render(request, 'galerie/GalerieNew.html', + { + 'form' : form, + 'soustredeni' : soustredeni, + 'galerie_text' : galerie_text, + }) def plus_galerie(request, galerie, soustredeni, subgalerie): - galerie = get_object_or_404(Galerie, pk=subgalerie) - if galerie.poradi: - galerie.poradi += 1 - else: - galerie.poradi = int(len(galerie.galerie_up.galerie_set.all())) - galerie.save() - return HttpResponseRedirect('../../') + galerie = get_object_or_404(Galerie, pk=subgalerie) + if galerie.poradi: + galerie.poradi += 1 + else: + galerie.poradi = int(len(galerie.galerie_up.galerie_set.all())) + galerie.save() + return HttpResponseRedirect('../../') def minus_galerie(request, galerie, soustredeni, subgalerie): - galerie = get_object_or_404(Galerie, pk=subgalerie) - if galerie.poradi: - galerie.poradi -= 1 - else: - galerie.poradi = 1 - galerie.save() - return HttpResponseRedirect('../../') + galerie = get_object_or_404(Galerie, pk=subgalerie) + if galerie.poradi: + galerie.poradi -= 1 + else: + galerie.poradi = 1 + galerie.save() + return HttpResponseRedirect('../../') diff --git a/header_fotky/__init__.py b/header_fotky/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/header_fotky/admin.py b/header_fotky/admin.py new file mode 100644 index 00000000..35d3427b --- /dev/null +++ b/header_fotky/admin.py @@ -0,0 +1,10 @@ +from django.contrib import admin +from django.contrib.admin import ModelAdmin +import header_fotky.models as m + + +class FotkaPozadiAdmin(ModelAdmin): + readonly_fields = ['cas'] + +admin.site.register(m.FotkaHeader, FotkaPozadiAdmin) +admin.site.register(m.FotkaUrlVazba) \ No newline at end of file diff --git a/header_fotky/apps.py b/header_fotky/apps.py new file mode 100644 index 00000000..084aa955 --- /dev/null +++ b/header_fotky/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class HeaderFotkyConfig(AppConfig): + name = 'header_fotky' diff --git a/header_fotky/context_processors.py b/header_fotky/context_processors.py new file mode 100644 index 00000000..be259cbf --- /dev/null +++ b/header_fotky/context_processors.py @@ -0,0 +1,45 @@ + +from datetime import datetime, date +import random + +from django.conf import settings + +from header_fotky.models import FotkaUrlVazba + + +def vzhled(request): + ''' Podle casu prida do templatu, zdali je nebo neni noc ''' + hodin = datetime.now().hour + if (hodin <= 6) or (hodin >= 20): + noc = True + nedoba = 'den' + doba = 'noc' + else: + noc = False + nedoba = 'noc' + doba = 'den' + url = request.path + + fotky = FotkaUrlVazba.objects.exclude(denni_doba=nedoba) + fotka = None + + # TODO rychlejší patternmatch? + while (fotka is None) and (url != ''): + presne = fotky.filter(url__exact=url) + if presne.count() > 0: + presne_doba = presne.filter(denni_doba=doba) + if presne_doba.count() > 0: + fotka = random.choice(presne_doba).url_fotky() + else: + fotka = random.choice(presne).url_fotky() + + url = url[:-1] + index = url.rfind('/') + if index != -1: + url = url[:index+1] + + if fotka is None: + fotka = settings.STATIC_URL + "images/header/vikendovka.jpg" + + return {'noc': noc, 'fotka': fotka} + diff --git a/header_fotky/migrations/0001_initial.py b/header_fotky/migrations/0001_initial.py new file mode 100644 index 00000000..4b90d0c6 --- /dev/null +++ b/header_fotky/migrations/0001_initial.py @@ -0,0 +1,63 @@ +# Generated by Django 2.2.15 on 2020-09-20 09:14 + +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + +from shutil import copytree + + +def zkopiruj_fotky(apps, schema_editor): + try: + copytree("mamweb/static/images/header/", "media/header/") # FIXME: bylo tu dirs_exists_ok=True, nekompatibilní s Py 3.7 + except FileExistsError: + pass + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='FotkaHeader', + fields=[ + ('cas', models.DateTimeField(default=django.utils.timezone.now, help_text='Čas vložení fotky', + verbose_name='čas vložení fotky')), + ('nazev', + models.CharField(help_text='Název např. archiv_noc', max_length=50, primary_key=True, serialize=False, + unique=True, verbose_name='název fotky')), + ('fotka', models.ImageField(upload_to='header')), + ], + options={ + 'verbose_name': 'fotka do pozadí menu', + 'verbose_name_plural': 'fotky do pozadí menu', + 'db_table': 'fotky_header', + 'ordering': ['-cas'], + }, + ), + migrations.CreateModel( + name='FotkaUrlVazba', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('url', + models.CharField(blank=True, help_text='url prefix stránek např: /archiv/ nebo /', max_length=100, + verbose_name='URL')), + ('denni_doba', models.CharField(choices=[('den', 'Zobrazit jen ve dne'), ('noc', 'Zobrazit jen v noci'), + ('oboji', 'Zobrazovat pořád')], default='oboji', max_length=16, + verbose_name='denní doba')), + ('fotka', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='header_fotky.FotkaHeader', + verbose_name='fotka')), + ], + options={ + 'verbose_name': 'vazba url a fotky do pozadí menu', + 'verbose_name_plural': 'vazby url a fotek do pozadí menu', + 'db_table': 'fotky_url_vazby', + 'ordering': ['url'], + }, + + ), + migrations.RunPython(zkopiruj_fotky, migrations.RunPython.noop), + ] diff --git a/header_fotky/migrations/__init__.py b/header_fotky/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/header_fotky/models.py b/header_fotky/models.py new file mode 100644 index 00000000..481a652c --- /dev/null +++ b/header_fotky/models.py @@ -0,0 +1,65 @@ +from django.core.exceptions import ValidationError +from django.db import models +from django.utils import timezone + + +class FotkaHeader(models.Model): + class Meta: + ordering = ['-cas'] + db_table = 'fotky_header' + verbose_name = u'fotka do pozadí menu' + verbose_name_plural = u'fotky do pozadí menu' + + cas = models.DateTimeField(u'čas vložení fotky', default=timezone.now, help_text='Čas vložení fotky') + + nazev = models.CharField( + u'název fotky', null=False, blank=False, unique=True, primary_key=True, + max_length=50, help_text='Název např. archiv_noc' + ) + + fotka = models.ImageField(upload_to='header', null=False, blank=False) + + def __str__(self): + return self.nazev + + def clean(self): + if not self.fotka: + raise ValidationError("Chybí obrázek") + """ Kontroluje, zda sedí poměr stran """ + if abs(self.fotka.width - (self.fotka.height * 970 / 350)) > 2: + raise ValidationError("Obrázek by měl mít rozměry 970w na 350h, nebo alespoň podobný poměr stran.") + super().clean() + + +class FotkaUrlVazba(models.Model): + class Meta: + ordering = ['url'] + db_table = 'fotky_url_vazby' + verbose_name = u'vazba url a fotky do pozadí menu' + verbose_name_plural = u'vazby url a fotek do pozadí menu' + + url = models.CharField( + u'URL', blank=True, null=False, max_length=100, + help_text='url prefix stránek např: /archiv/ nebo /' + ) + + fotka = models.ForeignKey( + FotkaHeader, blank=False, null=False, verbose_name='fotka', + on_delete=models.CASCADE + ) + + DOBA_DEN = 'den' + DOBA_NOC = 'noc' + DOBA_OBOJI = 'oboji' + DOBA_CHOICES = [ + (DOBA_DEN, 'Zobrazit jen ve dne'), + (DOBA_NOC, 'Zobrazit jen v noci'), + (DOBA_OBOJI, 'Zobrazovat pořád')] + + denni_doba = models.CharField('denní doba', max_length=16, choices=DOBA_CHOICES, blank=False, default=DOBA_OBOJI) + + def __str__(self): + return self.url + + def url_fotky(self): + return self.fotka.fotka.url diff --git a/ilustrace_odmeny/jak_nahrat_do_flatpage b/ilustrace_odmeny/jak_nahrat_do_flatpage new file mode 100644 index 00000000..7e88641d --- /dev/null +++ b/ilustrace_odmeny/jak_nahrat_do_flatpage @@ -0,0 +1,7 @@ +Přidání obrázků do odměn: +admin -> flatpage odměn -> ikona přidat obrázek +záložka odeslat, vybrat obrázek, odeslat +přespočí to zpět, velikost nechat, jen ok +přepnout na html zdroj, k obrázku (dovnitř img tagu) nahradit style za: + style="display:block; margin-left: auto; margin-right: auto; width: 70%;" + pro dort méně než 70%, asi 60% či 55%, okometricky diff --git a/init_local.sh b/init_local.sh new file mode 100755 index 00000000..ab373c38 --- /dev/null +++ b/init_local.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +set -e # Spadni pokud něco spadne + +# Check venvu +# NOTE: zkontroluje i správnou složku -- existencí Makefilu +make venv_check + +# Vygenerujeme testdata +./manage.py testdata + +# Nahrajeme statický obsah modelů +./manage.py loaddata flat.json sitetree_new.json + +# Posbíráme statické soubory +./manage.py collectstatic diff --git a/korektury/admin.py b/korektury/admin.py index 25b49e4e..79dfffb1 100644 --- a/korektury/admin.py +++ b/korektury/admin.py @@ -6,21 +6,21 @@ from korektury.models import KorekturovanePDF # Register your models here. class KorekturovanePDFAdmin(VersionAdmin): - readonly_fields = ['cas', 'stran'] + readonly_fields = ['cas', 'stran'] - def get_readonly_fields(self, request, obj=None): - if obj: - return self.readonly_fields + ['pdf'] - return self.readonly_fields + def get_readonly_fields(self, request, obj=None): + if obj: + return self.readonly_fields + ['pdf'] + return self.readonly_fields - fieldsets = [ - (None, - {'fields': - ['pdf', 'cas', 'org', 'stran', 'nazev', 'komentar']}), - # (u'PDF', {'fields': ['pdf']}), - ] - list_display = ['nazev', 'cas', 'stran', 'org'] - list_filter = [] - search_fields = [] + fieldsets = [ + (None, + {'fields': + ['pdf', 'cas', 'org', 'stran', 'nazev', 'komentar']}), + # (u'PDF', {'fields': ['pdf']}), + ] + list_display = ['nazev', 'cas', 'stran', 'org'] + list_filter = [] + search_fields = [] admin.site.register(KorekturovanePDF, KorekturovanePDFAdmin) diff --git a/korektury/forms.py b/korektury/forms.py index 676d6b3a..7385e687 100644 --- a/korektury/forms.py +++ b/korektury/forms.py @@ -1,13 +1,13 @@ from django import forms class OpravaForm(forms.Form): - text = forms.CharField(max_length=256) - autor = forms.CharField(max_length=20) - x = forms.IntegerField() - y = forms.IntegerField() - scroll = forms.CharField(max_length=256) - pdf = forms.CharField(max_length=256) - img_id = forms.CharField(max_length=256) - id = forms.CharField(max_length=256) - action = forms.CharField(max_length=256) + text = forms.CharField(max_length=256) + autor = forms.CharField(max_length=20) + x = forms.IntegerField() + y = forms.IntegerField() + scroll = forms.CharField(max_length=256) + pdf = forms.CharField(max_length=256) + img_id = forms.CharField(max_length=256) + id = forms.CharField(max_length=256) + action = forms.CharField(max_length=256) diff --git a/korektury/migrations/0001_initial.py b/korektury/migrations/0001_initial.py index 22643689..e9a89d18 100644 --- a/korektury/migrations/0001_initial.py +++ b/korektury/migrations/0001_initial.py @@ -50,7 +50,7 @@ class Migration(migrations.Migration): ('cas', models.DateTimeField(help_text=b'\xc4\x8cas zad\xc3\xa1n\xc3\xad koment\xc3\xa1\xc5\x99e', verbose_name='\u010das koment\xe1\u0159e')), ('autor', models.TextField(help_text=b'Autor koment\xc3\xa1\xc5\x99e', verbose_name='autor koment\xe1\u0159e', blank=True)), ('text', models.TextField(help_text=b'Text koment\xc3\xa1\xc5\x99e', verbose_name='text koment\xe1\u0159e', blank=True)), - ('oprava', models.ForeignKey(to='korektury.Oprava')), + ('oprava', models.ForeignKey(to='korektury.Oprava', on_delete=models.CASCADE)), ], options={ 'ordering': ['cas'], diff --git a/korektury/migrations/0002_auto_20151202_2351.py b/korektury/migrations/0002_auto_20151202_2351.py index ba88f7c7..2e7a8032 100644 --- a/korektury/migrations/0002_auto_20151202_2351.py +++ b/korektury/migrations/0002_auto_20151202_2351.py @@ -19,7 +19,7 @@ class Migration(migrations.Migration): ('cas', models.DateTimeField(default=django.utils.timezone.now, help_text=b'\xc4\x8cas zad\xc3\xa1n\xc3\xad koment\xc3\xa1\xc5\x99e', verbose_name='\u010das koment\xe1\u0159e')), ('autor', models.TextField(help_text=b'Autor koment\xc3\xa1\xc5\x99e', verbose_name='autor koment\xe1\u0159e', blank=True)), ('text', models.TextField(help_text=b'Text koment\xc3\xa1\xc5\x99e', verbose_name='text koment\xe1\u0159e', blank=True)), - ('oprava', models.ForeignKey(to='korektury.Oprava')), + ('oprava', models.ForeignKey(to='korektury.Oprava', on_delete=models.CASCADE)), ], options={ 'ordering': ['cas'], diff --git a/korektury/migrations/0006_oprava_pdf.py b/korektury/migrations/0006_oprava_pdf.py index 2adf04e7..e8f81884 100644 --- a/korektury/migrations/0006_oprava_pdf.py +++ b/korektury/migrations/0006_oprava_pdf.py @@ -14,7 +14,7 @@ class Migration(migrations.Migration): migrations.AddField( model_name='oprava', name='pdf', - field=models.ForeignKey(default=-1, to='korektury.KorekturovanePDF'), + field=models.ForeignKey(default=-1, to='korektury.KorekturovanePDF', on_delete=models.CASCADE), preserve_default=True, ), ] diff --git a/korektury/migrations/0010_Pridani_odkazu_na_organizatora.py b/korektury/migrations/0010_Pridani_odkazu_na_organizatora.py index e76d5058..6b318cab 100644 --- a/korektury/migrations/0010_Pridani_odkazu_na_organizatora.py +++ b/korektury/migrations/0010_Pridani_odkazu_na_organizatora.py @@ -15,11 +15,11 @@ class Migration(migrations.Migration): migrations.AddField( model_name='komentar', name='autor_org', - field=models.ForeignKey(blank=True, to='seminar.Organizator', help_text='Autor koment\xe1\u0159e', null=True), + field=models.ForeignKey(blank=True, to='seminar.Organizator', help_text='Autor koment\xe1\u0159e', null=True, on_delete=models.CASCADE), ), migrations.AddField( model_name='oprava', name='autor_org', - field=models.ForeignKey(blank=True, to='seminar.Organizator', help_text=b'Autor opravy', null=True), + field=models.ForeignKey(blank=True, to='seminar.Organizator', help_text=b'Autor opravy', null=True, on_delete=models.CASCADE), ), ] diff --git a/korektury/migrations/0011_prevod_autora_z_charField_na_Organizator.py b/korektury/migrations/0011_prevod_autora_z_charField_na_Organizator.py index dddb07be..9f64bbd5 100644 --- a/korektury/migrations/0011_prevod_autora_z_charField_na_Organizator.py +++ b/korektury/migrations/0011_prevod_autora_z_charField_na_Organizator.py @@ -18,10 +18,10 @@ def transform_autor(apps, schema_editor): oprava.autor_org = org oprava.save() except: - print "Org nenalezen -- mažu korekturu" + print("Org nenalezen -- mažu korekturu") # oprava.delete() else: - print "Org nenalezen -- mažu korekturu" + print("Org nenalezen -- mažu korekturu") oprava.delete() # preorgovani komentaru @@ -35,10 +35,10 @@ def transform_autor(apps, schema_editor): komentar.autor_org = org komentar.save() except: - print "Org nenalezen -- mažu korekturu" + print("Org nenalezen -- mažu korekturu") # oprava.delete() else: - print "Org nenalezen -- mažu korekturu" + print("Org nenalezen -- mažu korekturu") komentar.delete() def back(apps, schema_editor): diff --git a/korektury/migrations/0014_add_org_to_pdf.py b/korektury/migrations/0014_add_org_to_pdf.py index 9c1292e4..afd939ba 100644 --- a/korektury/migrations/0014_add_org_to_pdf.py +++ b/korektury/migrations/0014_add_org_to_pdf.py @@ -16,10 +16,10 @@ class Migration(migrations.Migration): model_name='korekturovanepdf', name='org', field=models.ForeignKey(default=None, - blank=True, - to='seminar.Organizator', - help_text=b'Zodpov\xc4\x9bdn\xc3\xbd\ - organiz\xc3\xa1tor za obsah', - null=True), + blank=True, + to='seminar.Organizator', + help_text=b'Zodpov\xc4\x9bdn\xc3\xbd\ + organiz\xc3\xa1tor za obsah', + null=True, on_delete=models.CASCADE), ), ] diff --git a/korektury/migrations/0015_auto_20161004_2005.py b/korektury/migrations/0015_auto_20161004_2005.py index c087a221..36be10df 100644 --- a/korektury/migrations/0015_auto_20161004_2005.py +++ b/korektury/migrations/0015_auto_20161004_2005.py @@ -14,6 +14,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='korekturovanepdf', name='org', - field=models.ForeignKey(default=None, blank=True, to='seminar.Organizator', help_text=b'Zodpov\xc4\x9bdn\xc3\xbd organiz\xc3\xa1tor za obsah', null=True), + field=models.ForeignKey(default=None, blank=True, to='seminar.Organizator', help_text=b'Zodpov\xc4\x9bdn\xc3\xbd organiz\xc3\xa1tor za obsah', null=True, on_delete=models.CASCADE), ), ] diff --git a/korektury/migrations/0016_auto_20190430_2340.py b/korektury/migrations/0016_auto_20190430_2340.py new file mode 100644 index 00000000..f14bce2b --- /dev/null +++ b/korektury/migrations/0016_auto_20190430_2340.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-04-30 21:40 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('korektury', '0015_auto_20161004_2005'), + ] + + operations = [ + migrations.AlterField( + model_name='komentar', + name='cas', + field=models.DateTimeField(default=django.utils.timezone.now, help_text='Čas zadání komentáře', verbose_name='čas komentáře'), + ), + migrations.AlterField( + model_name='komentar', + name='text', + field=models.TextField(blank=True, help_text='Text komentáře', verbose_name='text komentáře'), + ), + migrations.AlterField( + model_name='korekturovanepdf', + name='cas', + field=models.DateTimeField(default=django.utils.timezone.now, help_text='Čas vložení PDF', verbose_name='čas vložení PDF'), + ), + migrations.AlterField( + model_name='korekturovanepdf', + name='komentar', + field=models.TextField(blank=True, help_text='Komentář ke korekturovanému PDF (např. na co se zaměřit)', verbose_name='komentář k PDF'), + ), + migrations.AlterField( + model_name='korekturovanepdf', + name='nazev', + field=models.CharField(blank=True, help_text='Název (např. 22.1 verze 4) korekturovaného PDF', max_length=50, verbose_name='název PDF'), + ), + migrations.AlterField( + model_name='korekturovanepdf', + name='org', + field=models.ForeignKey(blank=True, default=None, help_text='Zodpovědný organizátor za obsah', null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Organizator'), + ), + migrations.AlterField( + model_name='korekturovanepdf', + name='status', + field=models.CharField(choices=[('pridavani', 'Přidávání korektur'), ('zanaseni', 'Korektury jsou zanášeny'), ('zastarale', 'Stará verze, nekorigovat')], default='pridavani', max_length=16, verbose_name='stav PDF'), + ), + migrations.AlterField( + model_name='korekturovanepdf', + name='stran', + field=models.IntegerField(default=0, help_text='Počet stran PDF', verbose_name='počet stran'), + ), + migrations.AlterField( + model_name='oprava', + name='autor', + field=models.ForeignKey(blank=True, help_text='Autor opravy', null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Organizator'), + ), + migrations.AlterField( + model_name='oprava', + name='status', + field=models.CharField(choices=[('k_oprave', 'K opravě'), ('opraveno', 'Opraveno'), ('neni_chyba', 'Není chyba'), ('k_zaneseni', 'K zanesení do TeXu')], default='k_oprave', max_length=16, verbose_name='stav opravy'), + ), + migrations.AlterField( + model_name='oprava', + name='strana', + field=models.IntegerField(help_text='Strana s opravou (od 0)', verbose_name='strana s opravou'), + ), + migrations.AlterField( + model_name='oprava', + name='text', + field=models.TextField(blank=True, help_text='Text opravy', verbose_name='text opravy'), + ), + ] diff --git a/korektury/migrations/0017_auto_20190610_2358.py b/korektury/migrations/0017_auto_20190610_2358.py new file mode 100644 index 00000000..111f2f8f --- /dev/null +++ b/korektury/migrations/0017_auto_20190610_2358.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.21 on 2019-06-10 21:58 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('korektury', '0016_auto_20190430_2340'), + ] + + operations = [ + migrations.AlterField( + model_name='komentar', + name='autor', + field=models.ForeignKey(blank=True, help_text='Autor komentáře', null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Organizator'), + ), + migrations.AlterField( + model_name='korekturovanepdf', + name='org', + field=models.ForeignKey(blank=True, default=None, help_text='Zodpovědný organizátor za obsah', null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Organizator'), + ), + migrations.AlterField( + model_name='oprava', + name='autor', + field=models.ForeignKey(blank=True, help_text='Autor opravy', null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Organizator'), + ), + migrations.AlterField( + model_name='oprava', + name='pdf', + field=models.ForeignKey(default=-1, on_delete=django.db.models.deletion.PROTECT, to='korektury.KorekturovanePDF'), + ), + ] diff --git a/korektury/models.py b/korektury/models.py index e5b6e01a..37213172 100644 --- a/korektury/models.py +++ b/korektury/models.py @@ -3,8 +3,7 @@ import os from django.db import models from django.utils import timezone from django.conf import settings -from django.utils.encoding import python_2_unicode_compatible -from django.utils.encoding import force_unicode +from django.utils.encoding import force_text from django.core.exceptions import ObjectDoesNotExist from django.utils.text import get_valid_filename @@ -17,180 +16,176 @@ from unidecode import unidecode def generate_filename(self, filename): - clean = get_valid_filename( - unidecode( - filename.replace('/', '-').replace('\0', '').replace(":", "_") - ) - ) - fname = "%s_%s" % ( - timezone.now().strftime('%Y-%m-%d-%H_%M'), - clean) - return os.path.join(settings.KOREKTURY_PDF_DIR, fname) + clean = get_valid_filename( + unidecode( + filename.replace('/', '-').replace('\0', '').replace(":", "_") + ) + ) + fname = "%s_%s" % ( + timezone.now().strftime('%Y-%m-%d-%H_%M'), + clean) + return os.path.join(settings.KOREKTURY_PDF_DIR, fname) #@reversion.register(ignore_duplicates=True) -#@python_2_unicode_compatible class KorekturovanePDF(models.Model): - class Meta: - ordering = ['-cas'] - db_table = 'korekturovane_cislo' - verbose_name = u'PDF k opravám' - verbose_name_plural = u'PDF k opravám' - - #Interní ID - id = models.AutoField(primary_key = True) - - cas = models.DateTimeField(u'čas vložení PDF',default=timezone.now,help_text = 'Čas vložení PDF') - - nazev = models.CharField(u'název PDF',blank = True,max_length=50, help_text='Název (např. 22.1 verze 4) korekturovaného PDF') - - komentar = models.TextField(u'komentář k PDF',blank = True, help_text='Komentář ke korekturovanému PDF (např. na co se zaměřit)') - - pdf = models.FileField(u'PDF', upload_to = generate_filename) - - org = models.ForeignKey(Organizator, blank=True, - help_text='Zodpovědný organizátor za obsah', - null=True, - default=None) - - stran = models.IntegerField(u'počet stran', help_text='Počet stran PDF', - default=0) - STATUS_PRIDAVANI = 'pridavani' - STATUS_ZANASENI = 'zanaseni' - STATUS_ZASTARALE = 'zastarale' - STATUS_CHOICES = ( - (STATUS_PRIDAVANI, u'Přidávání korektur'), - (STATUS_ZANASENI, u'Korektury jsou zanášeny'), - (STATUS_ZASTARALE, u'Stará verze, nekorigovat'), - ) - status = models.CharField(u'stav PDF',max_length=16, choices=STATUS_CHOICES, blank=False, - default = STATUS_PRIDAVANI) - - - #TODO Nepovinný foreign key k číslu - - def get_prefix(self): - """Vrať řetězec, ke kterému se připojí číslo a .png""" - # vrátíme jméno souboru bez cesty - return os.path.basename(self.pdf.file.name) - - def convert(self): - """Vytvoří jedno png za každou stranu pdf a uloží se""" - dirname = os.path.join(settings.MEDIA_ROOT, settings.KOREKTURY_IMG_DIR) - if not os.path.exists(dirname): - os.mkdir(dirname) - self.stran = 0 - while True: - res = subprocess.call([ - #Parametry inspirovány chybovou hláškou imagemagicku - "gs", - "-sstdout=%stderr", - "-dSAFER", - "-dNOPAUSE", - "-dBATCH", - "-dNOPROMPT", - "-sDEVICE=pngalpha", - "-r180x180", - "-dFirstPage=%d" % (self.stran+1), - "-dLastPage=%d" % (self.stran+1), - "-sOutputFile="+os.path.join( - dirname, - "%s-%d.png" % (self.get_prefix(), self.stran)), - "-f%s" % (self.pdf.path) - ]) - if not os.path.exists(os.path.join( - dirname, - "%s-%d.png" % (self.get_prefix(), self.stran))): - break - self.stran += 1 - # Změnil se počet stran, ukládáme - super(KorekturovanePDF, self).save() - - def save(self): - # Pokud se nezmenilo PDF, tak nepregenerovavej nahledy - try: - original = KorekturovanePDF.objects.get(pk=self.pk) - if original.pdf == self.pdf: - super(KorekturovanePDF, self).save() - return - except ObjectDoesNotExist: - pass - # uložíme nahrávané pdf - super(KorekturovanePDF, self).save() - - # uložíme png a změněný počet stran - self.convert() + class Meta: + ordering = ['-cas'] + db_table = 'korekturovane_cislo' + verbose_name = u'PDF k opravám' + verbose_name_plural = u'PDF k opravám' + + #Interní ID + id = models.AutoField(primary_key = True) + + cas = models.DateTimeField(u'čas vložení PDF',default=timezone.now,help_text = 'Čas vložení PDF') + + nazev = models.CharField(u'název PDF',blank = True,max_length=50, help_text='Název (např. 22.1 verze 4) korekturovaného PDF') + + komentar = models.TextField(u'komentář k PDF',blank = True, help_text='Komentář ke korekturovanému PDF (např. na co se zaměřit)') + + pdf = models.FileField(u'PDF', upload_to = generate_filename) + + org = models.ForeignKey(Organizator, blank=True, + help_text='Zodpovědný organizátor za obsah', + null=True, default=None, on_delete=models.SET_NULL) + + stran = models.IntegerField(u'počet stran', help_text='Počet stran PDF', + default=0) + STATUS_PRIDAVANI = 'pridavani' + STATUS_ZANASENI = 'zanaseni' + STATUS_ZASTARALE = 'zastarale' + STATUS_CHOICES = ( + (STATUS_PRIDAVANI, u'Přidávání korektur'), + (STATUS_ZANASENI, u'Korektury jsou zanášeny'), + (STATUS_ZASTARALE, u'Stará verze, nekorigovat'), + ) + status = models.CharField(u'stav PDF',max_length=16, choices=STATUS_CHOICES, blank=False, + default = STATUS_PRIDAVANI) + + + #TODO Nepovinný foreign key k číslu + + def get_prefix(self): + """Vrať řetězec, ke kterému se připojí číslo a .png""" + # vrátíme jméno souboru bez cesty + return os.path.basename(self.pdf.file.name) + + def convert(self): + """Vytvoří jedno png za každou stranu pdf a uloží se""" + dirname = os.path.join(settings.MEDIA_ROOT, settings.KOREKTURY_IMG_DIR) + if not os.path.exists(dirname): + os.mkdir(dirname) + self.stran = 0 + while True: + res = subprocess.call([ + #Parametry inspirovány chybovou hláškou imagemagicku + "gs", + "-sstdout=%stderr", + "-dSAFER", + "-dNOPAUSE", + "-dBATCH", + "-dNOPROMPT", + "-sDEVICE=pngalpha", + "-r180x180", + "-dFirstPage=%d" % (self.stran+1), + "-dLastPage=%d" % (self.stran+1), + "-sOutputFile="+os.path.join( + dirname, + "%s-%d.png" % (self.get_prefix(), self.stran)), + "-f%s" % (self.pdf.path) + ]) + if not os.path.exists(os.path.join( + dirname, + "%s-%d.png" % (self.get_prefix(), self.stran))): + break + self.stran += 1 + # Změnil se počet stran, ukládáme + super(KorekturovanePDF, self).save() + + def save(self, **kwargs): + # Pokud se nezmenilo PDF, tak nepregenerovavej nahledy + try: + original = KorekturovanePDF.objects.get(pk=self.pk) + if original.pdf == self.pdf: + super(KorekturovanePDF, self).save() + return + except ObjectDoesNotExist: + pass + # uložíme nahrávané pdf + super(KorekturovanePDF, self).save(kwargs) + + # uložíme png a změněný počet stran + self.convert() @reversion.register(ignore_duplicates=True) -@python_2_unicode_compatible class Oprava(models.Model): - class Meta: - db_table = 'opravy' - verbose_name = u'Oprava' - verbose_name_plural = u'Opravy' - ordering = ['y','x'] - - #Interní ID - id = models.AutoField(primary_key = True) - - pdf = models.ForeignKey(KorekturovanePDF, default=-1) - - strana = models.IntegerField(u'strana s opravou', help_text='Strana s opravou (od 0)') - - x = models.IntegerField(u'x-ová souřadnice bugu') - y = models.IntegerField(u'y-ová souřadnice bugu') - - STATUS_K_OPRAVE = 'k_oprave' - STATUS_OPRAVENO = 'opraveno' - STATUS_NENI_CHYBA = 'neni_chyba' - STATUS_K_ZANESENI = 'k_zaneseni' - STATUS_CHOICES = ( - (STATUS_K_OPRAVE, u'K opravě'), - (STATUS_OPRAVENO, u'Opraveno'), - (STATUS_NENI_CHYBA, u'Není chyba'), - (STATUS_K_ZANESENI, u'K zanesení do TeXu'), - ) - status = models.CharField(u'stav opravy',max_length=16, choices=STATUS_CHOICES, blank=False, - default = STATUS_K_OPRAVE) - - autor = models.ForeignKey(Organizator, blank = True, - help_text='Autor opravy', - null = True) - - text = models.TextField(u'text opravy',blank = True, help_text='Text opravy') - -# def __init__(self,dictionary): -# for k,v in dictionary.items(): -# setattr(self,k,v) - - def __str__(self): - return force_unicode(u'%s od %s: %s'%(self.status,self.autor,self.text)) + class Meta: + db_table = 'opravy' + verbose_name = u'Oprava' + verbose_name_plural = u'Opravy' + ordering = ['y','x'] + + #Interní ID + id = models.AutoField(primary_key = True) + + pdf = models.ForeignKey(KorekturovanePDF, default=-1, on_delete=models.PROTECT) + + strana = models.IntegerField(u'strana s opravou', help_text='Strana s opravou (od 0)') + + x = models.IntegerField(u'x-ová souřadnice bugu') + y = models.IntegerField(u'y-ová souřadnice bugu') + + STATUS_K_OPRAVE = 'k_oprave' + STATUS_OPRAVENO = 'opraveno' + STATUS_NENI_CHYBA = 'neni_chyba' + STATUS_K_ZANESENI = 'k_zaneseni' + STATUS_CHOICES = ( + (STATUS_K_OPRAVE, u'K opravě'), + (STATUS_OPRAVENO, u'Opraveno'), + (STATUS_NENI_CHYBA, u'Není chyba'), + (STATUS_K_ZANESENI, u'K zanesení do TeXu'), + ) + status = models.CharField(u'stav opravy',max_length=16, choices=STATUS_CHOICES, blank=False, + default = STATUS_K_OPRAVE) + + autor = models.ForeignKey(Organizator, blank = True, + help_text='Autor opravy', + null = True, on_delete=models.SET_NULL) + + text = models.TextField(u'text opravy',blank = True, help_text='Text opravy') + +# def __init__(self,dictionary): +# for k,v in dictionary.items(): +# setattr(self,k,v) + + def __str__(self): + return '{} od {}: {}'.format(self.status,self.autor,self.text) @reversion.register(ignore_duplicates=True) -@python_2_unicode_compatible class Komentar(models.Model): - class Meta: - db_table = 'komentare' - verbose_name = u'Komentář k opravě' - verbose_name_plural = u'Komentáře k opravě' - ordering = ['cas'] - - #Interní ID - id = models.AutoField(primary_key = True) - - cas = models.DateTimeField(u'čas komentáře',default=timezone.now,help_text = 'Čas zadání komentáře') - - oprava = models.ForeignKey(Oprava) - autor = models.ForeignKey(Organizator, blank = True, - help_text = u'Autor komentáře', - null = True) - - text = models.TextField(u'text komentáře',blank = True, help_text='Text komentáře') - - def __str__(self): - return force_unicode(u'%s od %s: %s'%(self.cas,self.autor,self.text)) + class Meta: + db_table = 'komentare' + verbose_name = u'Komentář k opravě' + verbose_name_plural = u'Komentáře k opravě' + ordering = ['cas'] + + #Interní ID + id = models.AutoField(primary_key = True) + + cas = models.DateTimeField(u'čas komentáře',default=timezone.now,help_text = 'Čas zadání komentáře') + + oprava = models.ForeignKey(Oprava, on_delete=models.CASCADE) + autor = models.ForeignKey(Organizator, blank = True, + help_text = u'Autor komentáře', + null = True, on_delete=models.SET_NULL) + + text = models.TextField(u'text komentáře',blank = True, help_text='Text komentáře') + + def __str__(self): + return '{} od {}: {}'.format(self.cas,self.autor,self.text) diff --git a/korektury/static/korektury/opraf.css b/korektury/static/korektury/opraf.css index 33146e1b..4a731de4 100644 --- a/korektury/static/korektury/opraf.css +++ b/korektury/static/korektury/opraf.css @@ -13,72 +13,46 @@ body, img{background:white;} +/* Barvy korektur */ +.k_oprave { + --rgb: 255, 0, 0; +} +.opraveno { + --rgb: 0, 0, 255; +} +.neni_chyba { + --rgb: 128, 128, 128; +} +.k_zaneseni { + --rgb: 0, 255, 0; +} + .pointer-hi, -.pointer, -.pointer-wontfix, -.pointer-wontfix-hi, -.pointer-ready, -.pointer-ready-hi, -.pointer-done, -.pointer-done-hi { +.pointer{ position:absolute; /*border-bottom-left-radius: 10px; */ border-left: 2px solid yellow; border-bottom: 2px solid yellow; + border-color: rgb(var(--rgb),var(--alpha)); } -.pointer-done-hi, -.pointer-wontfix-hi, -.pointer-ready-hi, -.pointer-hi { - border-width: 3px; +.pointer { + border-width: 1px; + --alpha: 0.35; } -.pointer { - border-color: #F00; /*IE*/ - border-color: rgba(255, 0, 0, 0.35); -} .pointer-hi { - border-color: #F00; /*IE*/ - border-color: rgba(255, 0, 0, 1); -} -.pointer-done { - border-color: #00F; /*IE*/ - border-color: rgba(0, 0, 255, 0.2); -} -.pointer-done-hi { - border-color: #00F; /*IE*/ - border-color: rgba(0, 0, 255, 1); -} -.pointer-wontfix { - border-color: #000; /*IE*/ - border-color: rgba(128, 128, 128, 0.2); -} -.pointer-wontfix-hi { - border-color: #000; /*IE*/ - border-color: rgba(128, 128, 128, 1); -} -.pointer-ready { - border-color: #0F0; /*IE*/ - border-color: rgba(0, 255, 0, 0.2); -} -.pointer-ready-hi { - border-color: #0F0; /*IE*/ - border-color: rgba(0, 255, 0, 1); + border-width: 3px; + --alpha: 1; } -.box:hover, -.box-done:hover, -.box-ready:hover, -.box-wontfix:hover{ + +.box:hover{ border-width:3px; margin: 0px; } -.box, -.box-done, -.box-ready, -.box-wontfix { +.box { margin: 1px; background-color: white; width:300px; @@ -86,18 +60,7 @@ img{background:white;} padding: 3px; border: 2px solid black; border-radius: 10px; -} -.box { - border-color: red; -} -.box-done { - border-color: blue; -} -.box-ready { - border-color: rgba(0,255,0,1); -} -.box-wontfix { - border-color: grey; + border-color: rgb(var(--rgb)); } form { display:inline; diff --git a/korektury/static/korektury/opraf.js b/korektury/static/korektury/opraf.js index 5cfe02e2..760f3c6a 100644 --- a/korektury/static/korektury/opraf.js +++ b/korektury/static/korektury/opraf.js @@ -65,6 +65,12 @@ function place_comments_one_div(img_id, comments) } } +function place_comments() { + for (var i=0; i < comments.length-1; i++) { + place_comments_one_div(comments[i][0], comments[i][1]) + } +} + // ctrl-enter submits form function textarea_onkey(ev) { @@ -212,45 +218,22 @@ function show_form(img_id, dx, dy, id, text, action) { textarea.focus(); return true; - } -function box_onmouseover(box, stat) +function box_onmouseover(box) { var id = box.id; var pointer = document.getElementById(box.id + '-pointer'); - switch (stat){ - case 'done': - pointer.className = 'pointer-done-hi'; - break; - case 'wontfix': - pointer.className = 'pointer-wontfix-hi'; - break; - case 'ready': - pointer.className = 'pointer-ready-hi'; - break; - default: - pointer.className = 'pointer-hi'; - } + pointer.classList.remove('pointer'); + pointer.classList.add('pointer-hi'); } -function box_onmouseout(box, stat) +function box_onmouseout(box) { var id = box.id; var pointer = document.getElementById(box.id + '-pointer'); - switch (stat){ - case 'done': - pointer.className = 'pointer-done'; - break; - case 'wontfix': - pointer.className = 'pointer-wontfix'; - break; - case 'ready': - pointer.className = 'pointer-ready'; - break; - default: - pointer.className = 'pointer'; - } + pointer.classList.remove('pointer-hi'); + pointer.classList.add('pointer'); } function save_scroll(form) @@ -261,6 +244,33 @@ function save_scroll(form) return true; } +function toggle_corrections(aclass) +{ + var stylesheets = document.styleSheets; + var ssheet = null; + for (var i=0;i - + Korektury {{pdf.nazev}} @@ -20,6 +20,29 @@           | hlavní stránka | wiki | +
+ Zobrazit: + + + + + + + + +
@@ -81,12 +104,12 @@ {% for o in opravy %}
+ class='pointer {{o.status}}'>
+ class='box {{o.status}}' + onmouseover='box_onmouseover(this)' + onmouseout='box_onmouseout(this)'>
{{o.autor}} @@ -211,11 +234,6 @@ ["img-{{s.strana}}", [{% for o in s.op_id %}["op{{o.id}}",{{o.x}},{{o.y}}],{% endfor %}[]]], {% endfor %} []] - function place_comments() { - for (var i=0; i < comments.length-1; i++) { - place_comments_one_div(comments[i][0], comments[i][1]) - } - } {% if scroll %} window.scrollTo(0,{{scroll}}); {% endif %} diff --git a/korektury/templates/korektury/seznam.html b/korektury/templates/korektury/seznam.html index 2498fbce..57823f6e 100644 --- a/korektury/templates/korektury/seznam.html +++ b/korektury/templates/korektury/seznam.html @@ -1,10 +1,6 @@ -{% extends "korektury/base.html" %} +{% extends "base.html" %} {% load staticfiles %} -{% block submenu %} - {% include "korektury/submenu.html" %} -{% endblock %} - {% block script%} {% endblock %} @@ -21,7 +17,14 @@
    {% for pdf in object_list %} -
  • {{ pdf.nazev }} {{pdf.komentar}} {{pdf.pdf.name}}
  • +
  • + {{ pdf.nazev }} + {{pdf.komentar}} + {{pdf.pdf.name}} + (k opravě: {{pdf.k_oprave_cnt}}, + opraveno: {{pdf.opraveno_cnt}}, + není chyba: {{pdf.neni_chyba_cnt}}, + k zanesení: {{pdf.k_zaneseni_cnt}})
  • {% empty %}
  • Nejsou žádné dokumenty ke korekturování. {% endfor %} diff --git a/korektury/templates/korektury/submenu.html b/korektury/templates/korektury/submenu.html deleted file mode 100644 index 0a5ed988..00000000 --- a/korektury/templates/korektury/submenu.html +++ /dev/null @@ -1,13 +0,0 @@ -{% with "/korektury" as cesta %} - - - -{% endwith %} - - diff --git a/korektury/testpdfs/A.pdf b/korektury/testpdfs/A.pdf new file mode 100644 index 00000000..083bac6a Binary files /dev/null and b/korektury/testpdfs/A.pdf differ diff --git a/korektury/testpdfs/B.pdf b/korektury/testpdfs/B.pdf new file mode 100644 index 00000000..c0d61df6 --- /dev/null +++ b/korektury/testpdfs/B.pdf @@ -0,0 +1,5125 @@ +%PDF-1.5 +% +5 0 obj +<> +stream + + + + + image/jpeg + + + Tisk + + + 2014-02-10T11:27:01+01:00 + 2014-02-10T10:27:07Z + 2014-02-10T11:27:01+01:00 + Adobe Illustrator CC (Windows) + + + + 256 + 116 + JPEG + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAdAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7 FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7F XYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FX Yq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXY q7FXYqsNxAG4GROVaceQrX5ZHjHey4D3L8kxdirsVdirsVaLKtKkCpoK+JxVvFXYq7FXYq7FXYqo X+oWGn2kl5f3MVnaRU9W5ndYo15EKOTuQoqSBiq+3uLe5gjuLaVJreZQ8U0bB0dGFVZWFQQR0IxV a97ZpdJaPPGt1KC0duXUSMorUqleRHwnFVbFXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FVO5Li 3lMf2wjcPnTbIzvhNc1ShNM8v+YtMhuryxguPrCAszIvMN0YBx8QoajY5h48eLU4xKUQeIORg1mX H9EiPj+hi2seVNd8tg6j5YvZzZxfFNpzsZAqjuqtUMoHtUeOarVaLNphx4JHhHOPP+373d6fXYtT 6M8RxHlLl/Z9zIPJ3nGHXoTFMgg1CIVkiB+Fx05pXeniO2Z3ZnakdQKO0x+NnX9o9nHAbG8D+N2S ZtXWOxV2KpJ5q/u9L/7adp/xPFWH/wDOQOu6rpPkSNNMuGtp9TvYrGSaM8WEciSOwDDcV9Ohp2xV gum2nkLyF58h07Todcm80lvqFnc3Qi/Rs15cosaSPxeKRow0vxDtXxpirINN/OrzFqeieWEtLSzX zHrWqy6bfRSJL6ESQFTI6oJPUBVJo2NWPfbFUFrX50fmNFceaZNL0jTpNL8r3z213czGTmY/XaGL 4BKhLHjUkbe2Ko/Sfzb/ADAXX/K6a9otjbaJ5sYDTmgd2uAr8OLsxdl/3ahoUFQcVSKD8/fzCOhW /mafRNPHl5b0WN3IrSeq0hX1CIwZDxoncq2+Kqv59+d7i31hNDnTSr3TLQw3n1KZ7ppnlAJ9OZLd 0UDuA+1CMVTDzJ+bX5gad5W0zzRp9lo8Wi6hDAsFrceu901wwIkjjSOSMFVKkj2xVWGpapcfnB5C bXdOtodbutJmluXj9dWgZorpvTRTKU6bHkrHrv0xVCf8rx82f8qq/wAXfVLD9JfpX9H+j6c3oel6 PqcuPrc+Vf8AKp7YqiNU/Nr8ypNU82W+g6Rp01l5Ukma8ubgyVEEZenwiWPk5WJjt4dMVUtE/Ojz 5PqPlafVdHsYNA80XItLWSFnM/MSrC77yEKA7VAKdO+KvbcVdirsVdirsVdirsVdirsVdirsVdir sVYf5cvTpOvXfl+5PCGSQyWLHp8W4Uf6y/jmj0OXwM0sEuRNxa4mjTMM3jY808z6RL5e8wQ6ppw9 OGVjJGB9lXH20oP2WB6fRnG9p6eWkzjLj2B3+PUe56jQ6gajCcc9yPwC9C02/hv7GG8i+xMoange hU/I7Z1emzxzYxOPIvOZsRxzMT0ROXtTsVSTzV/d6X/207T/AIniqC/MjyPF508ry6O1wbWcSLcW lxTkFmjqF5DrxIYg0xViVp+XP5iax5m0LU/Our2FzZ+XpPXtIbJH9SWUFSrSFkjAPJFJpXpsN64q xP8AKjQ9N1f85Nd8w6Xzl0Cwea4s5GRkQXN5QMgVunENIPoHtirJZPyi8yNpX5g2gubP1PNl6t1p x5y8UQXLzUn/AHXwtxb9nlviqYal+WWvXT/lu0c9qB5PSJdT5PJ+8MaW6n0KRnl/vO32uPbFWN/8 qO82f8qq/wAI/W7D9JfpX9Iet6k3oel6Pp8eXo8+Vf8AJp74qmWvflV58bzJ5mu9A1PTotM81x+j ftdo7XMcbIUdIuKMKHkf2h27gYqx+3/Jn83IrrQ5n1DRbmPy6nDSrad7kwoeRfmyCAVflQ1r2Hhi rNYPInnS78/+V/NutXOnvLpNnPb6mts0o5ySC4VDCrRgceMyV5MO+KsR/wCVC+dP0f8A4W/TFj/g /wDSH6Qrwk+udOFKceP93/l9cVZXpv5Za9av+ZDST2pHnBJV0zi8n7syJcKPXrGOP+9C/Z5d8VS+ P8ovMi6V+X1obmz9TynetdaiecvF0Nyk1IP3XxNxX9rjvir1zFXYq7FXYq7FXYq7FXYq7FXYq7FX Yq7FWN+cvLUmqQJd2Xw6la7x0NC6g1417EHdTmr7T0JygSh/eR+38dGE42h/LHne3uwthqrfVdTj /dkyfAshG3enF/EfdkND2mJ+jJ6cg+39qI5L2PNN/M+mrqGjTxUrLGPVh8eSb7fMVGXdq6bxsEh1 G494/FOw0Obw8oPQ7JH5BvWUT2Dn4T+9iHv0YfqzS+zmq3liPvH6XP7WxXUx7mY51bpHYqknmr+7 0v8A7adp/wATxVR8+eYrHQfLk9zdLPK10y2dpb2jmO4lnuPgRIpAQUbvyrtTxxVIPy1/x3Zm9Xzh ZXMK+mrpqV3qEFzGEhVUWP0oQqxnjV3kp8R6nFWXWHmby3qCTvYatZ3iWq8rpoLiKURKKkmQox4j bviqReafzA0618rX2reXb+w1S4s5rSKRY5VuEUXN1HAeYhcEHi7cd+uKsjk1nSI57m3kvrdJ7OMT 3kTSoGhiIqJJQTVFI7tiqX+UfNVt5ksJr239ARLM8cSw3MVy/pg0R5fSqsbPSvDkaDvXYKsatvzE 84ajd6yujeUkv7PRr+406Sf9IpFJI9tSpWJ4f2lYEDl7VxVk/lvzdonmCwsbmzuEWe/tRex2Luou FhLcGcxg8uKyfBy6VxVFT+YvL9vay3dxqdpDaQTNbT3Ek8axpOho0TuWCq6kbqd8VYxpX5gTajrP nCGzNjeaboMFnPptwkwjjm+sQSSSerc1liCh46BgtB3xVZYfmdJqXlHUvMen6fbyLZNGkNrLqNrE XLFFkMs3xQwBSzcOTVenQVGKso1HzL5c0y4S21LVbOyuJACkNxcRROwPQhXZScVV4tY0mWC6uIr2 3kt7JnS9mWVCkLRKGkWVgaIUU1YN0GKoCHzH6/mFdOhjgk0x9NXUo9TS7hYtzlKKotwfU9Mp8Ym+ wenXFVaz81eWL1bh7PWLK5W0UyXTQ3MUgiRerSFWPEDxOKq+l63ourRNNpV/bahEh4vJazRzKp8C YywBxVG4q7FXYq7FXYq7FXYq7FXYq7FUo1rypomsfFdwUnpQXEZ4SD6eh+kHMPU6DFm+ob9/VjKA PNAWXlDUNPIWw126igXYQyKkygeADjiPoGUYuz54/oySA7tixECORY5eevo2rtElwYZI2p9ZVFJC uPtBGBU7HpnJzhLS6rY1R5+R/Y9RGPj4PMj7QnV5F+YWn1uLa8h1i3Ar6TRJG5Hsqca/Q30Z0+Qa zH6oyGQe6vu/W8sRMeaM8uedbPVpDaXEZstRWoNu52YjrxJpv/knfLtH2lHKeEjhn3JjktEeav7v S/8Atp2n/E82TYx384GFvpvl3VJeS2Ok6/p95fygEiOBC6M7f5IaRcVQ/wCbXmHSL/8ALrWrfStS tbu5MVvLJFBOsh+rG7hWV2ERZvT4MeRp0xVisvlQa7ek3uo+WdG079GXNrdPoV0S7QTGP0nkR0jQ xxyhe4+1Su4xSh/M2s3EPlDzJ5day0t9VtE0q6i1HRwiW10jahEkSzItPTkDD7PKlDUUHVVC6g13 B5I1vTdTSIeZYfMFo/mya4ZvQngmnV4JpGRea2pXgoAB4gHbfFWd/l5pN+nmzVNWeXQo4JrK3t57 DQZ3lUSJI7RzSoyIFJQsoPemKGI6PpemXZ89yXfnC78uuNd1NfqsF1DDCy0Q+q8TIZGrXieLCoFB viq38r9etk8zeWNQ1Q2+lxT+U5bO35EQxM1vqRA48z9po4+Z33rXFUNYzaNc+afL93qTQyeXrvzH 5lnWe4I+qyM3H6s5LfAatXhXvilBeYP0UNS8+roAtP0KdS8ui74ErY+n+89b1TCGpF632+IOKET5 z0m/Typ5y1Z5dCjgmsNPt57DQZ3lUSJfK0c0qMiBSULKD3pilkuh/wCCP0t5/wD8ZfU/0j+kpuf1 70/V/R3op9W9L1fipxrTj7e2KHnvl863p/l+Lyu6sJ/P9lYfVH3X0wtwbaSv+taBWPtvilln5sW1 xa+Y9dttJQx+h5KjjSOOvw26amFlG29BCG+jFCaef28nL5Bt4/K36NFq9xpv6QWMoqfUhMOJvDAG lEXMjkSCdz3xSnX5eaTfp5s1TVnl0KOCayt7eew0Gd5VEiSO0c0qMiBSULKD3pih6NirsVdirsVd irsVdirsVdirsVdirsVYV+ZGmubeLU4hUR/urin8pPwMfp2+kZzvbukuso6bH9DvOxs4s4z13CY+ Q9cXUtGWF2rc2VIpB3Kf7rb7hT6MzuydT4mIA/VHb9Tjdq6bw8tj6Zb/AK1Lzl5WF9F+k7Aenqlv 8dU2MgXft+2P2T9GQ7S0HiDxIbZI/b+3udROF7oJNdOr6NpMktPrcOp2kdwOlSH2an+UPxzI7O1f j47P1DYsoSsM0mhhmieGZFlikBWSNwGVlOxBB2IOZ7JLbDyt5Y08zGw0iytDcKUuDBbRReordVfg o5A+BxVTg8meT7dZkt9C0+FbleFwsdrAokUkNxcBByFQDQ4qqW/lXyxbWctlb6PZQ2c7I81tHbRL E7RsHRmQKFYqwqCRscVRE+i6PcTzXE9jby3FxF9XnmeJGeSGtfSdiKsld+J2xVZpWgaFpCyLpOm2 unrLT1RawxwBqVpy9NVrSuKoO48jeSrm5kurjy/ps11K5klnks4Gkd2NSzMUJLE71OKovUPLvl/U reG21HTLS8t7cUghuII5UjFAKIrqQuwHTFW7jy9oFxpyaZcabazabEQY7GSCNoFIrTjEVKClfDFV tt5b8u2tvNbWul2kFvcqI7iGKCJEkRa8VdVUBgORoD44qkHmf8tNG1Ty1c6BpMVroNrfyRG/e0tI wZI4W9QIAhioeYB5GtN9t8VT7UvLHlrVLhbnUtJsr65QBUmubeKZ1A3ADOrEYqiZ9L0ye5tbqe0h lubLkbKd40Z4eYCt6TEVTkBQ8cVbbTdOa9N81rC180P1ZroxqZTBy5ekXpy4ct+NaVxVBWnlPytZ rOlpo1jbrdKUulitoUEqncrIFUcgfA4qraVoGhaQsi6Tptrp6y09UWsMcAalacvTVa0riqPxV2Ku xV2KuxV2KuxV2KuxV2KuxV2KqdzbQXNvJbzoJIZVKSIehB2ORnASBieRZQmYkSHMPKLu31byJ5gS 9RWuNLlJTn2eM78HPRXHUf7Yzmjino8vEN4feO73vWY549fh4TtMfYe/3PUNK1bT9VskvLGYTQP3 HVT3Vh1BGdFizRyR4onZ5fPp54pcMxRYXrenHTPNVn6I42eo3ltMFHQSpMOQ/wCGJ+nNfhweFqjX 0zjfxB/b9rjAUWf5tWb568q6ymj+UPIV2bVL2WPT/MN1apOzelDNY+pOsiotKu32OROw+zQ4pZja fmB+Y11ZeXIhZaVFq3m3lPpasbgww2sEAmlecBuTMyspQIdu+KG4fzO812PmGPRtdtLBWstTttO1 i5tTKIzHqULSWcsXqNWOjpSTny+jFUTqn5ma/E+rDT7K2lH6bt/LmgmYuga7ZK3D3DBjVEbZeIH0 4qiNV8zfmLpk+j6FImkT+ZNduLgWkyLcpZxW1rCssrSIzmVnqxACtTFUuh/M7zXY+YY9G120sFay 1O207WLm1MojMepQtJZyxeo1Y6OlJOfL6MVTO488eYZx5insp9I03T9K1JNNs73VmkjjZoo63fMr IOTCQgRgce9d8VRf5Z+ebzzRHq0N49lPPpdwkS3uml/qs0ckYdWQSFmBG4O+KvPPN36D1DWPOk97 oOoeZLq1kMVhrFosn1exMdsoMB+JOBglBdjGr1rUiuKXsnlT1v8AC2j+vdC9m+o23q3oLMJm9FeU oLAMeZ+LffFCaYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FUqvG81/WX+ppYm2r+7MzzCSlP2gqk dcVUeXnb/femf8Hcf80Yq7l52/33pn/B3H/NGKu5edv996Z/wdx/zRiqlcwebrqB4Lm20qaCQUeN 2nZSPcFMjKIkKIsMoTMTcTRY1F+X3mKzvDd6RcQaXKftJbzzNGf9ZJInr8jmEOz4RNwMo+52Z7Xn OPDkjGY8xv8AZSbyaL50vZ9O/SUunyRWV1FctLH6qykRtVh9nhuPYZlxgdrN067JKJOwr4pz5k/x R+jwPLYsjqBcBjqDSrEsZVqsvoq7Fg3HY7UrvljW88m/J7WItC8s6XaXlvJ+hdO1m0uZZS6c5tVt yiGMKj/AkjmtaHj2J2xVOLzyH5ji0vyXcaVcWY1/ylbC2KXPqG0mWS1S3nHNF9QfYqp4/RiqEn/L LX9U0fzZLq93aJ5i8xtbSQNaiT6tbvYKPqvF3USfaHxNx+jFVT/lWOqx+Q9I0u3urdPMelX8es/W nDvby3yyPI/M0DlD6hWtK9MVVdT8s/mNqd3pGuzPo8HmDQric2UEbXL2kttdQiKVJXZBIr1WoKrT FUNP+WWv6po/myXV7u0TzF5ja2kga1En1a3ewUfVeLuok+0Pibj9GKrU/LPzBY+XvLS2Ethca7ot 3Nf3kd56jWdzPdK4lcsqF+SF/wB23HtiqdeSfLnnDTfMOu6rr01hKNbMMzLZmWscsCCFYwJFUFBG o+LqT2xVLB5O/MDSpvMFpoFxpUmla/eXN+Zb36wtxBJeKBKAsYZHCkfDUjFWcaFpUekaJp+lRuZI 9PtobVJCKFhDGIw1KmleOKo7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FX Yq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXY q7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq 7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7 FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FX//2Q== + + + + xmp.iid:25c354aa-a49c-cc4e-acca-855cba8252a4 + xmp.did:25c354aa-a49c-cc4e-acca-855cba8252a4 + uuid:5D20892493BFDB11914A8590D31508C8 + proof:pdf + + xmp.iid:8e6b66c4-a348-994c-aeef-f975a7d6fb7a + xmp.did:8e6b66c4-a348-994c-aeef-f975a7d6fb7a + uuid:5D20892493BFDB11914A8590D31508C8 + proof:pdf + + + + + saved + xmp.iid:3e87526c-5553-9b49-a487-443853d93c29 + 2014-02-10T11:18:18+01:00 + Adobe Illustrator CC (Windows) + / + + + saved + xmp.iid:25c354aa-a49c-cc4e-acca-855cba8252a4 + 2014-02-10T11:27:01+01:00 + Adobe Illustrator CC (Windows) + / + + + + + + + EmbedByReference + + Z:\WWW\Gymnazium Jirovcova\Logo\Logo gymji 2.jpg + xmp.did:d90990ba-a891-594f-b74d-a6e8c24a3ba4 + xmp.iid:9b17acee-8902-0f49-8f1a-d8965e1ffb40 + + + + + + + + Z:\WWW\Gymnazium Jirovcova\Logo\Logo gymji 2.jpg + xmp.did:d90990ba-a891-594f-b74d-a6e8c24a3ba4 + xmp.iid:9b17acee-8902-0f49-8f1a-d8965e1ffb40 + + + + Print + Adobe PDF library 10.01 + + + + + + + + + + + + + + + + + + + + + + + + + +endstream +endobj +6 0 obj +<> +stream +xڬuPU*)"%( JIJt( X !*)y8F@n~~ߝ;3zYy?{kΰeJBw'_ѡQa;NVωN@elϫtԠjZSꅹUjSC{nmˏHtѲ6YEzV WS +50gco,V@܍I6!<7o5[eǗ[n:_trpkvy=wZ-m}mnK@m ; - + /(DCc0]ݵqք=I{컷2Nݘ8$3H|촜cye5cBQXYR]6xTl|ݪgj~u@`[4 ?C֠Hhf;{G#ȕ1uvids)hJ]XFuT5z44ig;v- MS$'G. ?Y_?~*|2ex}Zp̝5L.hsӼ^׼sn\oy`va#OL=l Kܫcx5zݭٟ">|~ek7?c~cWO%-߸dB]:N+u_<׼_dsɚN5LLSͼ{j>j__a*sl63kaαỏ t9ay .?V6vY@N;mC,B tW%j)MB]vMƏ& HO;oh؁cc)&SϤOq#?sLrm +8{W$(n+,UXUa]*P@ PX(<C.b-q=,b%@Rsu,v"KuEAl)KvGέ>EVu5 , +6~qFds7yV-ܜ:wyzƭ],JgU{mo?p6p$gGst'%Z7"22 #>2xתݚ}nħI {ﻳց'_MzfݴO3^~ȯ9y +\y|warQNqY Z&=^>QqYՏ-AE.=#;WV0jJee-go$r<9ܿ>GINH%3 +JjqfVL[GN}pӷ0`p2p`xzØxD)i.gϢfZg5BŜK˲+ׯM[wIw>!_p __r^_`BU.?OKn~]7ߟxG__,sZbyÊ^5ǴPQ:tuy+lެ\aZF0(5뎙{^Oްrc&ҍllf616.ٝ;d9niRfG'+{z/oo:`:PT#1y·!CHGQcP]0~*a%")uo>|>$JԡTU 8\yHf츜܀<|룦8}%J +Q% +_ rth*<jVonіvuջ/?gx{ްѣcL"M?6q3{ƹ ?]62um=7x7ܶSrwƃ׏?!>׾oo-ƽohb+~d_]/[a0`aFo΍?S/w4`yY0-#0sg":W<r6r+̩PS4 Ղx2h #m]=. Zڨ8}~3hk^&PH& rhS_^|sDEO(o߃_$iiH|Tc b; !(RUef΀ciuJPI}3[{;7*U"\3YBHwhnF9~z׀c3gl~ A#ƍ{ug6HSc. x}q_\TrG4SrZ xJypc\_5d֩bJo\1Pm]` +v0qmJ4:wc0Ut\Z}Owdg59iu'Ժ@]:`i-@|/w Kv;p-'ڷ_~ oU,Z0C'~G%cvx=OP {kQ ćyȟ/lL!RKDԼ#a;<Vs;3V nd*jxʨ!X(Ç8BYD7#oQ遷aN8M2TUl-2&DC+ݫ 8MP7"v52z;z f{CU}EPM)ȒbsJȰ=R.0=&R=R v\}/X+,t%o<~ ϋXKV~= +dnamw=Bp5}MM˃."-컍rkC^N&Ƣ}EZ&A^O 5!,6Au3ud9Y\M KջB@a{wO&Jd˦`ẠU9:7/eJ}y EIh&mwUx%砼FQ@)UgB7n8>\\,b?Ƙ@ENCͰ$nTJÍu7˃O*IF +c8.ecٷH{ WPB9eU- ޯܮWj]b& +tgy;ˏrR&a_ .oJZ6v>~PSƒz{<'S&]urhQ20:Kй~A_3ߔo +*}39r.z:JtJN7 +֜D+|{۱oRPcA+|G-e$g@C<.ԋ +[@tm%]-?Zk% p;Y\4@bs]n} eKFE ۏEAwaJq"A!Q{GyWX*<]"Jt6(RSmYHj;)#Z"Fn_%$\pjVKK4*xA75wŸΓv0|D4ZꚄSrN+&T>A{O[NlݟBSTw$PtOhv%Z%cOqnSŕͪ&ʗZyn-!I l|/ T'/c@[RE.(5e~P4{wH9IDavmk[,_vqËwDrb-S:+_qMJ.._І)4e;!ܤO>WXĕJoHtkYIzpgp>u5Mg8JX,Jn{$hm2',v}xQFv˧ !AYz{p &3hvrũl9ُxn̡ܲvݥ&y~͋—P,=InzUBY@:a' D7^U5\&;d,v߸Dr E0umz\V8q2|5j%6[`mjS`c&Ic?9߲_h:=͸QƊ)f1aGU6V&#c"V7z<E5~LMB %zSWP.D^NAWꇟ&5,y>rg03оGF_w<ٵ=gB5+Vy`S!\O^?$;DUJ&c|j60մ).|d'a?Elңj?%pHb Pu~%% +S5NI~='seu4na4Z9d9-0iOt+E%LKGVjhko/T({K>%E9̭w`n`#črNm׼P[4Lsx %DnNF'W&_H cMg +҉KCFFK%ĺ6vYXؾM[I{vSS4cG*U`wJ$&G/:+GHN}"ACd3eCvb CW4aH dwcsGۀ~M]{8aQ2)FY6'~Q:$L5Ka옑ˁ8o/LjM4OQ?wA 0^=R9N<Ȫ~ ˺0?ǧ[`3؍zStYجL!vCG_ϣ9&׹e_(sh8 +~PV|A=Kg5\$|'ÎՖm|D~{mrWO[z4j帠eEWwv1qZh1 !Դ=5oMa:Gd#_[&)Ól&TGFFސhEP\U,ߊb4T%Gy$JEwM!U.Uu* &skR_(_$XɉҐ"Ḵ.2QGHAX;Ү׼Siya[IVƋk!\`ޙ YN˜Q=Us-CF-!b7~ޔj*dQ1;+׍  ʟ#~6ѻ[,nNj]|@9}.mf +L)45cL:L,|nW9g,@7v=c-1 +Rꑢ(nݴ^zh(V|fO8p.CI ~3۹7^{`#.i.U*"4=ld5pRԊ|ɬAVL+m( =9:Cig`Lb~5DO(Ѝ_em>J,11G 9{;MNP4#ʪ~Jd0i{Ohh2ÿ ]_l|?8+Kt$5;|;jU|tꎠ%Pb)6cuj$=DZ˿Iܱ'W##lhEM˼0ψ mvGKh6)kQ+F6*’&=oFԢGL<}O[x @`Bz+a޵y!=]"[hRNaMOjJхrDsD*k.SM ++c%#8>:ם*EkcJj555eZw&[$m\\w/V@ȇ'7iAhS6j7vY_Kn=i|o[m,^ݽKuO7iIL{dut:}H}f=Iތf\}]mn׵ q ^#H~BKڙ'ܺ`lʛ`U|@dUk"S6@a&.݃DmQH(ݲI#D)uZi~S'#_dk({(勬ˈFHNٺ3q36_C)v_qw(Dhd /#IC倁mx* 2pa W`!@ +i+˴Q +rWO8Rr3qsW; ~>[(7K`GWGؿJOW1\/bؤ 6hqFԄulJ_PSg=e-$5I+ѯ!> ϖOssc\'؁q)=m~[~ם ]m(r%h!TF+9.c"dqV܏!#mp?/l-0YV~.4Ѵ?AOfߪx%3SuiGke)Qݏ׉ +C8XgC"j 3ί>)%kPAe&lƨrwneBRFGtB~l/Y7L txV\츑= vt+CZߗ*s'SqɚH]:%%-8XeDlӑ7amq;MOB|)>Vɏ;ʦV߬k@<q^k%6jri=L\<7ciWWA#w!E]$H-»29kVA]?Zk+Q3*=$iPjC'-}GH4Qc\0 Dhx=_6_Q󘂾sp p%-x[hc0%1H%Z E=2=x /2iyk&@/LPExMy@ڑ2%tD@xO ۴9ƵQ~S]pApb < D`[hĉ` +zfzLz|LZG7=d^[VkiUW`j|h$\l=h(sDӗ,t?Rت^ T,S\FKGKF‡\W(PuЁq +OzQ7Z7X6ƨb|n6iT6]F(iE?"ޢ`ɴ%W%kq޵ѐؑ&x9}][[D 5U85/b ˴T2jeʮ*ӪUqjjv7snk!*f<Խ&|azfm퓵/Uol|~Z*XbR1*ʮ>ݓVj\P5#+4绑Ww >ԔN V"P8@fKph2- ΍ +_;BJpӍeyG1/67;x!p.6Hapb)LGG܃p2xq<, Xvpcom|5ra` ^̾CZЇ;h-78t3փrQ ? )^fP6~!Gm[):PLNY݊  \?B=,ː'y!tddGs2&`^ Lںd{bF"] y.:RVwv$ 3!ڂ"  M[1-1j 'C`!cAAȁ$Khx +,46͐ n/ aZ}{KU~A)ؽ\ vS=ZhӅLK+؛d +&CoASno=`K2h@]zԞ 4(A/ .9q,<%fwdnkS(P0bR6D{+Wdn.QrAqr\t+a>xPP9zH *M_/vB@!!=z.@΢b r{%*>zs..B@zv@$6ҁVH" vEނV Cn4nށs5a=`CL e~~Qȷ$i7LAˮ[NcW~t`qAh8ֆuSlGy_F Qw&"nra"9~5n1IQSK$j#PD#u?u:DS-EaꄿvWD F ;,wOAD̖x20v;v fmX2[6ݪB +!\m(L!ԙ݉rz(ܟE%/t6KM-I%ep,irx{8'NoewЁ]dmIriD fhDlGi+سzn+\&gýŧî D<Ŗл,ÓY%qTPi9d\_"o+?mUcUr`{*>AްB[ n9 avԪn?"*=[^/kK<2#5%aA[GDE ,ۓ{sJ<4Ntm /R;qvWVخ Ѕˁh"ߑZ]n°<>Wt^/&W_~"W"`=6.Xj@!㳟hд5ԵF]2;Kra в +=ڔeB'xQ`(< g0JY S'Ao CNƽF]>ʍoŽ$ah(L=}?HjnX_ -D=}Yi3uK9ϓL!E˜6v#d,v>rl$i@K Cxno%ˈ`dAE/CS* dj3D%n&AW&JOvpLAjZ]twӮ7,v./NȘvn4YZg܈Je(‹0RAFqW{*f"-qx2yٰbF?Mrhac>צmevԿc)cbXMɉ^c^;mDqWnl.qU}U`Km9;)f/1|ԋqVucq9bry%tv +U|!fҠ(ӁЇĽctE{=7#UR##!:5ETW4o22BP"l&zpKG# +^'į1g7$ZeI#O2 e`- +ZhEA~CCbP,x{X*qؐۉi9Aϋp`8 J +PAWHHE[B?2> Z@:9fu/!Yh}>13n)Q[Ne`O1 +1'7ql9?%sam`JZZ I%ˉ;|_ ֛p*?Z7x1I" +B +4p3T:X|X`Ora'[`4}9Yo#\D_@|V=B([W˄gxZ3e f6^ cL]7Cql淜 ڵL3^ʔA6H,O8_#ಸ'}F0oV4d^m:PGf6[ Ҕt[U'nVPһq"OΧ\F(x؍eJC(] +_M? +i|>>7|;#{lya}2_Q5ŌD^H=os_AXû !iAI*1EלB(WyuWX❪9Pc[PC N^xl1`.X팫łq:xY)ErB,ʯ#9Ǚ!5aw"/tڍuϤxAfoB+~(3ȁl(CUpذ + iﵖtioNAVm%3қQF*G:+>KJ@]C)꘧PL - wu\$aݙԻl!=M9r%&m?ZIDb/U?ze-&W*(-ܿ4,1.y dd~2Qo!lљ\f%ϒVN`uM-:hZv\UIW@n7KL?Z=t +u*dPy4z髭xOrLΪ.n! +>$ 7벼؃퉢swI> V6z?oi 4:n \˖_',zNQ#>5[v=AD~$ _VQmhh#\,^1oο5Ks^_+ӿRU dyp=U{Խ/XcoQ2T9,7;s&1,~W׺PQFbp`]Qׁ +DZI܊^Dle&a<*(T) ZWN{<fw?ݮ ~EQzެ6]>ȲHK?*LL!q쳐;2qt[4ؠvR,( PGIȬc rK7vjb1蟗׮{i zwb 2AR'.f_0wo:]xnVl*ka!>DZ00:ބ;Yr3&FK2&D(w 22JuC l .8=X׿t2xݨ{,~%ٔ/|WJ(.P(ٔ^(=TϖӻRrQ"U.<>O-ő=Ǿ;ʴeܠ\B(;ioHeX][\d!IلRԐ$*NBؼqQ2]"fL +i[9.jK G9X V[|޷:"#>DhJ4EQ6c[ p|}c9 E ͚;( UIU:ĥ,Ze_ QDȷq!FXa5fΌ-_2n7 <'lh}VY( +paGXž"2"҉nDa1L)̋aQiUP*N`@J:u]+utf4[,MTD&[ٽXH:]ަKkjCl"kysߒGtQu!92UL:1s=h[e6Bp}aI(\ŒOsNIwh +Dm A=oPbFm?*yL*  C_6+<=YfVJjj_'/[ ۍUߪ߬?JT)L쒐.qW-g>O;0h9f)LRg% fCuMԯ]vպu/2y6էg!{u+R92&Y,vHyuf9KT'A7ky1Ҍk:yH`oQQN۴=ƹпq\fDm-T@4;Lu +bebE*U%-ըC4kVwN&{j +k^Bp+>ѣaف)<^>܎Wk6[PAt\) +72a4;zG0Bv$|e['5 r]Y'wI.! S7_e"ksfPv$~_B lt"AiEʁi,fV/Gbitb6p0\mpYEEpaX%DT,B T:TDAJaę``.>}^g='4aBu|o)qmKGG]L?JU, +۫&3*%O勾Қ`e\QOĺ_^@I0(sw^ѵrC>r7r W\$bhGX b`BS1Qm)o*g VwE3CUՂ %0[p+~S 4..nWWj_=tzfƆAEso[[۰^V.r)/.z*O>x =dw7>ijT?Wא&!n\vdbEw9>d/'Эݎ]`UI.߯Ѩ0PK8DՙI% .~"Oy4NDj@|ǃ"zQyMw;GRcm;F5C*6\eHc4G]V /*rXkU+CrF}k ;S_ckZllC~SsrwM) ΄!8Ol`7F`O~G|}uWb4f8yOSl\d|91`E." l!Y&7Q 3Ivͺe_U㠅M 1XLF&t` ]^}vcpw mIRmS*3F\MuJm\fh)ǗQ5Mrn#ɑ`=7 apx-'!d81ɦ͗:&i;I24 +FJFIY)/WH%N,H؜˅/Q颿5rzT?f_\1G^K?gV%u=P{BvS Y}o7;ۉ[[K[ BV`s} {:_b\.H`1fXHpa᥺'_4.GoPS҇պC%N x~s?6P2448{Sel2(NxX*KX0)6a0e}Ccjw8nhݑtf0?j԰)L{AL90<Uۙ. {PPZ}W]jI8jRo8dpGT\AZ+>fk.Zo~16NG!ΗkG弘@BAԡ4z4}844kCZu sdO?ϖ2֚IXii~x fD=#;&zmkCC6Lm0iyk̵'zG_ep|?Ic g˗yv#B>ʆ]Z: oQ 8t-f5JF#s0Ѿ{1Wn`W`>)XD j:б lL@>zА`<՘jy6#6w\G iCDQH!ސH!ySu:*wui@g>F] :82"q~-i17ْg/qj-ɸ%FD.>ŨOv(2Ὰ*.\> AB/;1iN,avCe_O@fmr?=|BxЃX!ƒgI b.bj#!?8Dr. 'fvH:Wt@p@so6g!Aln6yZT|0jTгn2DZB;c#ON^[vmnk9dm/?kzCJҲdx|:RKNC\9GnΩr x5a~ȳw:aka-Kqnpᤌȕ[kj=1QfՕN G &tB1к9e>݃08+j7LG\\ <{~D +sE_K|`驁{B7>~qdwZOT t +}x(]9x'`rfy3P2Ok_.=o0!bn |'qX 6ybp[qv\2]v;@{;@d;{ ܸq3Bq|s_yGfꓱV;s?JT ))"@U!*p~x[B~Ac`79L"çsJ1wi@J'֓g`K(tWX<-_5EKlEKczR~b t%{)Zğ~]Wc칂a2O=Üa{R0wl>er\e =u%R]UOQ~tN +tnƜ&, ÙҎ_|܂946Ԣ<66*ZnErس.S&j9u: T@l@_P ]HK3QDdMcg$oA_[R0kgc` +*) 3JH|] !oqL3p7u.ن=E9ꆧ:[@BD2Muf_v.U5KWEݷL$.lsm5Ԡ] w=jG4Ϊs\jj :-/p_=laYSG^uCdd'*ܮ.cΪR_&A*utsLb.,$N_N^-e=Y ^,ŞIBbgRg9agM`WX1G5}Hnn # 0fB o0zSxv. q3>|BB=qY`,> +0w`,F~h31QU8vޝYd1J` pǬ@/@M㢑sPcD!HX[ADrGE[9P?D4'>f^=9B&mzMK>[ERC|Mlc,?X]*TX(=R6ɐZ\, +N|!rHz%GRXh.q\qYqZ$Өط"j@֜kAoFzGEm Ne167m^8Ȃ-FaR?gKݻ8Sa,<$si#`H^' ,7+8*\w,v|L[8=׋Iտmզħԋ)B(B+[JI3&BFo:E*=TS-u'pC t{x?4n>;T?Il}G*Y[pq[3WOMvě΁j#6k2W|s~2)ưlZFsRI +8?sR-u䧋냐F&K^^[_=gFKlȋŸ}7ʒ9R,_~%ͤhi6 +0D.{fZ Ōt%N? k =ZU7N& <("L l ×=I 8g &KٟgW_g+bRm;5)zjCkm|W.%{ev',@jY.eҗ*X fј$K02S/ m#j`%7CFP%K7P5s,i[.q+sY䊳UL՗esxoqbHuzq^9EK73ɌusrV]IxQ$WJa޴IT.6`E[9\ +]ϸʞBoj2kTO1;ߵU<+шǞ{$i[3J ~,T}ļ!pXyN~E1}ݢcizM6QvpFW6]V1KđK;-(kDK>.5[Uk5RI}˜hIcgߤXs38kT5k/Τ^XĀ/)LQҡ:$D>)HJ9 w.% rV#틵 +%iyw,A6%S>FKDrscg]XHM> +)M3J$F9Jync,b_E'po."'F_ +lhG!듐+5kP:;jj1M!st <[*ҍ`<Tڢ1Y6N6CEnn8sbG|TK!Ji  ȅ`Xj$hS-+5KHXΪj«cUP>ZIWW$<}MEIӖl!Rn[>;"6żb'E֍d4fq컩$'$ٛ#6yU<2㖝^f~n X݊`i5ȬTɭV"υv]On +r޻~q3fEg"C6.TMuZ0(I\x *Qmw .3Ʒ8i~maS:\CR}2~P { ?7i+]4n#!ng>ו0U9+ a5—^|/Q$ӮU1>Oᓷcư. 5uA3USiO䒖;OHMaK Oy53]9&aWrsfKDja;lwcA7 i['5vz/#-%L (g"Q ]݈[6.<gA#y[ ՛0|)|V6HGp I~=䀾YoHJ$bؐ{r@o.P=|^YB=Zi; ]N"v< W,l9 o RvIG-Jh#9+e_`֚Y$7g?+ +aʬ.igr{&;x[}r7:jӂJ$?uÓV#[9ǻޞݷP-dlR0K3=VD|Қ̪BRqcvfXch&n6I )VoCu$Z0qC['a6M?FzAv~oRSK˛K}tҵBD\\&^Y7!qV }y -t{?ݥoʂƶe7,j߿!CӛdbUֲKuXAR2B*l[3M#]}ے֌ϦY fDZ 1  C:HqU :kk`h`eۏ,l3iCQ?՚8o΋WR ]wrB[Ւ;tFVy;{nj6աMuV}!9]h֮00{s,Gn9QF˭(}OCPDC!>rˁ3鹝4]֭h ~G,cv)خѬYj$EL*ـہ7@X+X `E ~z=~ qJFh#XpVg+;+ HɖSi`^ jƥ!p[)𘪆xf@'^.5>lE>i:} w0ܪR nԪ79(QtAO=:"N9f c+bC/z"`1wjof%+.1fN;dEm>xwX#۫ ̼CGn>psܜl9T'wD@뭷>W`K^_]("jŬ1gFSc N#h9mϩF!Kbo\ μrYݜEp? +9m .| \E e%ڧp)tٯblS;0ϛ͢7Y^F\^Y99%?=:"J<"$F0/{Qp]J_8%+VjA[kBaE*m&W+G+Hi=e]IGԎvxsK LzCp DƯ[ҡ,[fH2Ln1yDe Lg&P +P꣬۾ʟj!}.D4omEB\F#d|'5Ȼvе%-e`Umn_]OZh >].,$`”$tITa2~612ݶ-mE1=DȞ9 iru|럨@Z tkKC;n`ؑl}V1 klFTZb ĜKK~cTϥ@ Eщf/\N#O@Q-~O.'DrL|,+̕MNH#*;]:\!O[J7BKx-0;/|Ѽ& ͈C]M$Pug{ F~u;giόzqw: @R%S8}눕F>vVP,v4K߻惠E7Δw= qGá^^捔JcO8 + ":m; W %nzVlT4jںja2=z3:i2#m_[/Wn9?ʿ)+Phw1wTD)O/ +i<ᾜ -}&+ۻ;>Vl}]iv&bgJ;"Pf&'Bһ?`vհ^ABr!Ƙ82jxe{{orPg}QÖ;=u捙zRP1|[Xja$̅|~{9SQmQ꽃50LV`դ@H,4Tw{L@f/Lf/:| PX=>T[GPլNMkHIo]Y硄 {%>fMeT +&ڡ&_#seÜfпE[I=89CmRq :0A\xĨkPR4u oQ0s1á;)k`w`l2T˹, G /@|%+j/<u +gvפSO!B?4L5M?}&1=Z ?I?֚H]E\~*iu0K= +<#|21ztH]d"V t #2Yʄ༣D"l8!r1:31WmMCQR3lP'@S+,^d9HY`%ͽybs9M8v`~ Gņq&@='a'مF("7 /C6a QCِ~4UYjh`;_7nk[!"@0 qPnDU,BeҎꠇ{ClLѐ|4oEg\3B ox_oD$h~ɹj0ni^ϏǾA&x _/ఀ?k`[w'趹EX#\}}75Ky-t\Zvf\V +!,@ %,kU(51X|Gg_>Kۀ_ASxS7K6 p4N) EЉTyX +ry@0jmDœ{q!4a7zM¹RqNLD>Zs&f=Gv.傉2µSj킣'Y8~icl v&6Cư઱Ik&1'Fgeai@U*uv:{<7fA(Vw`ҟj#_g`dIl#f7's!g /@ cF<:3[3)Jm: Uڏ`bHb6cJv;0 gqo. =l݉Gs0m]hܬ21=hWDl%z@9+~'ގx'0W.h 2}pdg͖_B(a4~ Tn{W,OCĢ)֟ЩeCWPc cs\vڏAutDFaJШͫסo+@k@*\İ (ZTT'**CQ޼(fGiZ+jX7_uTqJT#xzֳSʽKYLwmt%%.,<@/`۷p8hx +Gz5o7 M^E[ ն̥$. +#FlB- /C-] +bo_#HL4ϛ*4 ~S(=8߸ 9KqGjJeGgm(le9ކВ +S\MIC{#P8Bze!(񿂥{3);~_G|E(y yL4ׁz"`e~df|S_RbvRqa/.cj&gs"h1%bV?z}7ś>H'<9s5r!WuXEP҆eT$FQ6_OD&Dwy%Ŝa#)}iHay̽I]ް6|QZ6yb(^Yi. X.^dsfs5QWDy%-m6&(Dg2SRMN!c)f~S)75Oen2f X +.TtˏdTSҾ ?EjfodP?}^ 괧G؂:t$L-pow?*I%+COI[BFe#Q9/XI׉J$QkUUQ5I-;zsk;x As8ϞE[a霥 Dad#,_ _[ϐKwY(L7Gc%;0=+n! O| g Ob0=AW氱9 b{ +ukwkvng+DH <IN+x vfyqKDWXL!OK1g5DLT?0>s12 y.&HM;VLN΄Sv(nSʹ`ԧ9`魂" ؽ ~"Yd?cs0^˘]iy%Zj$RF{7gt\&'8Rn#wU{-μ' aglϤ;r_=)/.f$Y ~Ujpzn zdV66Mk> + +VxΥl 8X| o"YY`eyMfNXÝj{ƜIKJ:`ϯƜ3ʹ mݘzuV>pG5Il anEu7Ew^.p%EpF7U}״lX)f͐IEsپrpu4ώIԛޠ+( iE*V>?BiAۻKB/.VGnQw}wޫq9qd3ZJjX9<[>ZdTtqgǠxcI`?vc9G}Nb0E?yxA->Nԗۿ#@$`srH߱Z:VwRCXݨ(.SEr| +B2"> rmM P^ɪ!v6w…Lsg p5S!^BDӔS.O$^bGfoLus< +Vy +FZa S)2>,kG mkQmR.1rUY03rMs" ,¿wl +m9]SƼmB }Ӗ<٣LZeZ.`ɺl @N(ў^V|(zTUZBCλE^땒`T,Gi7.m]q]LRةl7̅$zN1j! LVL [|Q9@]k[Z>vEb[MP EJѮ h%KzUT,Wp{O xo{f#kƋjZ,]ؾZ~d +S $2`Xe%K8DDl8ED_h{H]^K(fhf\M~ 8Qq䔀2'1LkUG{Dڡm9:j)nǼkaI2|"o(k)n.JvF SIrMH;#T\+WxQ9PɏM7sr#I#Ǭ;xQ+ʿ%bJR$1XKn/ +Kw٫H+y`$sgο9XdzZGڎүk\d4vBQE(eg$Boy31fTpmoΫ6v4Zӯ7mS_#dE~GxG)gG= ql$W5fA_3j4v+7?-ҽ#GYE0\AE)AJ@@%3̞Acww=Ok]׺aAj&=rYCpr35ڹ%5q滨\Wu= `P’%Du6g{ؑjQM"n3y-(m#34Hf10Q,g(RACNy*#eo.1]v(Tֱ-93{kl5z&q5)\YmfRgB)ٽs#q#7%VgplVhBҘg<@Voi]1z6K~GĕDHc8}v3kw(!yZHWk|*\iBgu8lQx-4D`$D3/C-e3yq? z2Fzez'i?B_Ia}jߖYK63ZN-#i>I/ÚӕDntM,+O 2|_k' :R/cYZ]tw sdґcCf 13B&ցXf2,||~B":YizTn{Cz)fй>T$PDžYx* +K}<ފoH9@D+v# &CΞjy?e!Sm؟h|jiLhe;A+N {vx54- g E:/E5\9uC,1$x4]{CLJꗎ.v`nϣNז9,KI*ݧ8y^ m2'/kN*nh2{qZs2C^ȉNiS"ތ:ÂXc%i+覺>Lwm4n*8PePݕ{:cD>Ś"pTar?'[EGunޟ!tb f]K$܃:Y48'}#ZiXŚfJ-N#58M25g[(id!}b(lۊԙ8ljaI+͋[_)dpmW ]5PU&%a+$&cȁr-4¡Q]K`*zbm% t&n>-{2)M]]Ql'PW%1d#t!CD,_YCaҿ3Qeϱj(IOd}eL Yij,H&hOt(9z_&w@3)O$G$o h&aُ@hcE]HI%!L_mف()(>AHK$ S_x$7>@MGgcz8];5'q۔׊[[RQbx{.8GBru{ȈPf[?Ev9\֥V4)Df;H{g|&l0Bj P!-;Ev7M*;M0fNNF%SBUf%\Z!"woǂ)؅}Op;fDxO3.^-qd~jh[:cvaP1x%ZZ3:s goM?7|:8D\ly3mDsы32H)"!z.ŴXV.FMϦELS3Ho20iǺ%)OM]q gP{`b6E+eNTuO4R<3S0J[F6̥ +Yk)&p+R{suFq>67n+aU TSY +/_I~"$췟B*6Rj|P܏nv&ۉ7oI(Æd3-"TmQE^.϶"=}íL._m/ꇗ`^V= tWfvL&Œma\ Gi`@6yyСwÐK[1轪d Ķ^ěΘ$a[Dd_@Oz췍Yz*z D2ތrQCO_;4SæBnIPu dC9x˯C[h& nl~·\<߂䕡

    YY3E$& ]~c=lf2*PlaTRƣ72.!͌pYMF'l #]o2`FtV*#/NeZT8g~SmMZmCLJdПq`lZX_Ba*,WK3Nz-ҕ%)BjV<=LPO^ϫvl7X5Cn+pD%8kbi +CX +heeCLΔ] ``DdZ d mmmGJWwwdaoIluq+ EJCB".<\ch;mi'3!fmzln.KҤ . I͢4Վ#sDv=1No&sï]뛤e={Jji~]H㋕5'4GQ-{-tXUN9D6YDzE}95K GQ񟩯:㢃V[{]tnB'd47 SWZn4?#wrh/vlʥGܧL3`YgѬ^Rp-b|Vqp(9Ȇ73g6a3w]LIƺ̬cjp`)ksytڊg~kŵ^DsX7a!'^^ obklc?BlL5wcGX]Sm2)M: #%DH)g"x,pia $jVBּC +ljkLK~Vƞ2DžZYƿPy3R6µ 11hT~ca?S-,pz\6jR6&U!zOYRs&C:cyQ5S7cOda;bR!r૶Xo_0jݣ1AՓO݌XI.:Ҿbl.\j~IB G/:ue;R>2m+[NzmZ_F? X5?XwX~r`| u +1Y@3I1U32t 嗭G8i*:pk6H*&"G VЂSOصQoD5'P1G])6 n2?z%%a;nqքwDLo/|i/22)< ?d ۤˉO/8i]TM|" S(Oo lZn1]QKX^Ě~HdEZA>|3F <ƍȵH\!ک|8}=tSI Ox|2*)-8xZ~{4_^vmw55z;:T-X5iq +|N*ҒEgos<"W_n-p3T7,h;E6.'4) $ E1y](Jf97~r +^k_W6Api#km)a^$n gM + VAkhR.O:V>m>,\a+ְzˣ BNh3i&ށϮ0g(_PXUNB X~`p.<5\n l}} SaZ)샆#}z4|%i5&p oY#o`ag9.麴3q%|%9҆{2L0X([ }Xa1ͫ3 -C?)MR6g q8!gS1YLQ#~2{}(&~[ߤ4bW 7Y⟭'!¶L"w~bc +vNGXhT=,:D]$$2_Ub5,\G n){qN2&CF 1gUUz>DiVTHU,|j#OG`%b/R'4 BLOSOo{G}6ied*(R2d'*RHog91Q)?{-n>2(~}@*;_\v{Mؑ*(qt /ᕾˈ!ЦnJ]1$olg<^i m!ۋ,Ny)CRZIB܀y1!l"9q +Uy1@@vؠf6%Qe0h8u4^GHxI 3qveP]g| u9qeO }B"O>%?QxSycVΙ%KhQ@ Õ Д U=Iu0\LW^Jc;Hg[-z2G&u+t&K +4 iJj2(+$>wsjC(2u:41#o_7CF3fVxm%ğ8nODXСX 맖OOkfiLoo5I02VF!E Jyin(xzj?ZBl۠ߥ&.)U r5selDByU -vgLMaeRF~uMUC"DS$YvE8)#E݊jz‘[+{8ȥ]4%&/ʟOfɏ^H'Пi?/]$t[$p_p |,Y eG3-)ۥ?D:  9:KANkbᆺ?/7U^P;Q-ivR01nצ..IȷTٓfOE } +yU_9j^n49)s"`Ct7U֪n2VJs[&R+wgU~zF*mPR!\ZD+T;*mv UMS> AGTycG_ڬhnN{Ek8P#o43d_csqnly%? +!+ݶ2-d׸Ԑ ٬*!Y@(7M98XS$XsORG^oS[WzgOT~FSں@nLz/TOJ.k}Nɭl@4Wnbgvoiu7j]?>z?WT -PPpe4b IdABCN]mUߎ]mWfO-2XmSTiMSE9ۈb{])k@A͙mmnYUpg^rGGD\*30|K{4[؏ ++a杓CʱƂ--zn#Gvv᠝)ڨs'[m(+FNˀ[#T.Cym\6Tfٟx{0` QKxyՇ5L w[;-hf",ò7 g&e`\zoEbg"CDudA@W:2/IF;oMUͮ g7˩ *̇Q{ fҼӗ):Qtz+y<9-E-6~L)o ;m@& +0Cϵ q +`yrvm -{68߭o=Ggꪎ-Hz>W/{>|λ:ʬ[͝x&YY`(;oW'4>Z/zv4A\d|i;|mM0ofԞkĽvW(n{ˎ;;WJ#~ũ'Ր詓r[I| TjxLw׳A:S}U1b(J.sPP6^Q*zf;[\ǥuE۟dM>*X?bj\emDZwu@Ur(lDR 7lȥȐwIIUî/9sMחt|mp1<"X?ܚ١czU{Sr$Qb-<ET nܝuEʤQ-c֌d!{B H7ƅ%}s4.Sffm{P2]FJ˳iV1>z?BӬ3mk:5+]2^HO!<_hh;Bz>cytEg[2XFtTfXt鉛1&~naތ焀`fS,xnQ1ju4*àcf5-Wiƪ`~!>7 w]tږwg0Š7Ńyn(|o5Zm$$O {_cBj^-fgn֡Frku +lI9>oAYpftFbܠdqo2qsh`~ݥV")yekƧIiKFWHP<؃Y4*]dEZji͸0갴~m>;N涵ۼpeߢ9{]Ųmz+6K͊E&N!3]]+k=K0/ '5v; u~Ի7Y;!l"+Fᙘe :ܴXK?"i>H:yy+؍~AbXhc9_^G Ȉŧrb y%)fgID +(040ɊսQMO RKr)[z΅݊o@aeNC$)B&1gi Z2GO2w{+qZ&9iq[CƏĘ4'JzxŌRGrQg86]cXg_poWPdžjMvR%KIbfi&*>#"EZ=Tot1_ #ex<(GU2FjZ:v W5iM*fu St$?TcBgqrrJounfᛆZƟi[%@|@ao\Eid8z Z)Iq7_qӡꄑ3bzd$IN͡ƑM- 9hH'j*ëm!OǗH4[yFuFfQf74}jKSu3۬"ݘ+͜O^?pjپ55uI$hA9xwoB<y UZgfRjS\Hub3 /v 'jbG|Rt}{-_Q:nCkNM/ uhR&^y.s2 W|Y<*XvHTkEC@E^\ /9iE24;(/VP-X&n+Ў@<Ύjxil%Z4A0ѧ +&)j%MF̈D{WtcA1aQA1c9;Fmfؕ-[->,jB$ JI^&×+jCpǎ5d[/;+0Zv:t7ơ0LsTdWlARvU>CPV=pusKQ-D$J5ѴsؼF` 8?":m 6ICprj1ۂ<6R\ kR)B:/:0% C5Bnru@ &s B!` D$!"]G~B'pT{B9M Gqhz@{1>^,}Epsej"~*!n0]b!'egl9ض(pڅ>ZAfo'e}YM%!Rr+9dSC5o IZ#0osOE轸].T<_ XCዳxUc!>$k'Ωe]?GۤY)|5W^G +[,AYq9ZF* .;C| `Bģ1}0؇Gv\ҍÌU4OG4eø9Mk eb$ϵ"R:]9z"Zw#UE`$-XB)._o3|vfF"jaB& ZgrY 2ۊvF4]Kc; CmkW·SoB4W_ym#);!UFnGmH!EFcbQ%غޤq*|xup;jW+>rHv`aU>_[ϼ]Oi܁b 3sV!Uf&y'f5༅يkYK*MlfLk?ͰF6Qw-|a!ǭ,` Is 0SgwWSq'|2/ (&9Ȁd +"~}1xP}U,,<B$FRS圢>V;44pAwIG{Low*mgMvfugl7P j=XNJLE }eCA:Z ^ THEy"v$%(I{)* شXj<7l ,tN[SiJ8G%&)Anr$Se뮐K:6YRѩF$VJ"Zzv^A9{hz&yB|nPH:O)N^*,L%+U뿓XR٥'F8;S܅|kE:,} NZx$WY?ln*l%.p7l<\"ǥ1VkQѓl¿ut=_3M'_7EcaSLf!8Vjp uY%{B 8t@N~\Xoa?7n--ˀ/@f-%dVAg )7ӣ;=p? :]=tj&DT&`⩟PSZnU=ͷl`0j9=yszɜ~PmA&w̅Fi $E+PQeS-ef@>ɫ]6ɯ| iI2sX`ssRϵ2S(/Y3N&ab )Y`ʶQ1Z #N_a}ӟ OJ(K=L:]OZz~I{lN?o[UI +lkzZJWD*Giה4gIr0,""@iܘdGfvshWҎ.h-L'uPU66Zp6,1rE4MeJ f H3 02g e!4DKBQ'-@fEah9g JN?Z9S1nA7m`v!\ Z#]ȯ[lmG3*zBw$;(JJnA5'rTjT m$]'{&Tv)ыJ0. d|sВϛ FbAnQ4E1~nXca{X*,;F{`pdcy~'"CL='K%γMI s;V'Kc>^-?+iWX3x35GTHPe ,XHhC_Cl3Ȍw\Vs/`8q5pz#J~|Q}xM +nZjoDjR|_7=`'kϔymq.vzkDWуe)KsZTS@X!_<.e;1>3speo!łzezUˊj Cej;G?i!G/7IrGgF0Ş;r^;`I+A{{(s 5n oK !1yŝ[!G;KdF<2$H^uߪf˩ͅ_JܸboY)!lg^e=]oc"IrKBWz,]q zp7S\- s H}N8 Tf+7e8yyq*!rWX{Qp%~C1h cA% C㚆%WWqNnh50nl' ǻ x-N;([cML[fl% ơ^>ƻMFԜBWfPJ0&:"Sty7twQʩsXrPprp I gQ]j)G9 G?}7&7gG8lUfNvC_3L,"?n+9'"M -y gZ)ȝ๸^/6NqȜ,RbEOHhAlc/ZY4s^t.DSX"oԷ`-+.VޣOغC2~-+TS\$ plv=kn'D;t~C'crNEeNrriE—5So"nɞ9DaV߮#\mG MT7 /&iinYqUPKۼk05|ڡjԊ%IJƈBNR+=mǐNqϢ&imc q{u-PeM(2(c* (H#je\?^HjnIwORE|"L 6ZW1SoXEnKa!m&Y#T's7 b~%TIZ\yCm =$)yKϨ+ \SgtZKhdhBf,!R'm_U ]UТh_L`x:/y͠X.d\{, sd׃/Q%Mj"PidGc[9J_ʔ΅_YzkY]d_ ^6kE¥k:Nj[NW\_"MKT C8 |CR_%-vh#$W7RYeK@H.iN Xy=K. Ta1 +ݜJP\W:VDk/,Y=g8wxYp tpJ֜2==UxB㻼YVUw˥KKg,©T*NvWܒt<똵Glw:amrGA^7Õ}/#_%WuN,v0~g0l\ۚ׼* )d :T"cY7W:T;ErMAgODY )+hWBV༼)7;NW#mfH>P ^F9 y4BƆ%I;%g7pY#QS\ߐB[1T?Ba Ib|?K9-|36AͬJ 5 VpA'S!ukNN^Ɗ,|I$Z|6|m.TyO7׶o1eWjy +CGlHORW,K +y*8PZ% %wwm^"= }6I2@ҶΩ㵔Eb]՞ג{J;_ Rn/=r+l^i{ hg!T'ڶ>P~F-6j6D޲e@~59c@|[ͳlEOs]㒕:Mͫ O"j*Qnn&qv}8}JB; VJa-34VjsWL +twcw۴ae[UmaQIQ sٝL[_[~l]?:6鸾+ +a3 r:F5F))ğ0 +3n)ZO4pYg c뎑> K.(NIUO[,\f;}_=zKPnNې{z`7EMuqUmcZ}I׳*޼8`Ǥ.J_ᮾ`Q-ђ0aj~,(݉j^Rf9[$aE 7A.V` N"ƚԙ٢n+nxnq@VoPLsݑUkG񦋧 +]ֽq3FɩXwM gƧxDBjdx8Qp=(y.}==ti +AL~Ed\nT9w1i?{~3`vi8Y0(\曬8QV Ifnx8w0p,v}keK70?`y>d8N A׈ûMq\^wiw xvfe[ܛIp`Yp!67F+}fO0b,]hz(YnP4 :vv]fh6h.!Sv3/vR6'wⰴnQd&9d+&)\<ӭT. $cmXcRa_g0# ˰9kՉEOTE+(8oŗN(_%11/e뎷UNyKVJ"Zrxo]NjJRy0[xPڻΣ797uF7?ޘpek߶?Tl3V蹪[sy2+slܐ ~H[ֽ[q}PEaŲ.E2p +sScGHbcMu&UM{ lz>59"J(05./9]I3OG'!QXC((nYRB"Jbr5=YE)/E/V۴822~;`X`!#;y O Fpf_'0&"+f?b!wΔl 6 a^p%zBOmDZ j/w1\mD ]; H<\Tnh(TaMBh !:. /|jǜyפuG}6ƫ:)?Hi6j Wf#'6d/PK` L7=N,\o{޳΍M-&f4- yACm^M|I9ppx 4X'xvԣHg(Wj)^'a𖨁57@5&c\7 65MZuѰDo绰(vKD + o=>N|}J5;6n)1ͧN6ZD&!B ¿o(!Kbk gS+Їc=1y%s7;0Dk.0bB;VNF4Q$p +&?H{,Q?1ά_w2 CP ٔ3o1qY)Y!ψ D)M{tA7SnSG7w. uKlTs a_r-RBR;0ʕ tNX~ZdXԍ} a("wЭ"ESP ,⌗ x7tM}-wiJXaT1!ʜz!J!V+[Ί߻p+o\;AwHu2I5meuǐ=hzU#L-s/Yʲ~@d㒱MךO%OZǠ}("<{9 uYߘDTkGb)Xzi7:P~ogGS{`k"y"nuBh_'{(掺Ⱥ[nLNvXHF+zZk7r1,p"-HcsKng Bg$D&gCg _d +6=G+AUԗЖ Qhѻ n +bVf|@h=y{)@G|a6fPW0[(/8I!>XvﺞnIYb>̥厊pVXJc?ĖK#FS$R+قјdE>vUFO3Ϩb>ѧa i.D#M55ĭޤ#LD|fgU抢Y4`5֢U 0 +ef<\R]v+2k) `MF‰_C(1` VC +oTU19˂+I24`qf΅}k_#p6Ԍʙ W|9wZcB.F~ ~{Fw˅T8߻w7lK{QӔ;޾n lWY|J|3 $&ɞ.%ZQ +{`aM~dR_R%U'"[>7!n|wU͎fBՑP(n)n(r-Aq` BL⁦{1{Ʋwف{-WS)PӵΖi'zc `?CLzBԨK0CYfѾ"e?~WZ$_N3ve? =dC34 +jzUW`HCҸ5p]p`r|ݳFŁy0F*Xq)d`˲fw` V:olr{_bB# RCw%NmH23s)> 153 lxGY iY@zIAʦk:#n/Ձ\Kgޡ]e lØ_טЏ3M1'4eqX5|SyVf\cBiH -.lIeE gQįJ _pԗxS2)oi_A3w6nM0Rn*FB*F/4HҫMfɵ^J~t|j('py}Om#WuP|ָ~UI(ݖPFm.P2wIuB]ѿMP]Gscg}$l_SL&#&F5ej\et Ȧ,,igGkpK +{c +DEh+cY%ٸ_6B+q:Oe +.l42CN!c Dozm"t]~ IUNHE `X]mVo~nodn,hq(| /`}[xwn5"V['t:"~SunnDzR>#b3 $| $CpL,9ռdN 4%Dj9ф+9U=t2"SD9k̩^vr4>E+lgo1af&uVbݧ/Ye6? +c}fy"vSa~N/fLF=7'3 +bSS]y[SZ88V$3*;t97Lŀt/=Y`I_!3Z~rU>c-gcC%}-gKD6-;/48$FρFЙ=e׊KO3] 8#0wˡTXrY؅ؓ'tD 1{=Lm<&,3"R9q=#\$c gĦTdKMVtiv;a#^}JO-,T`'-b'7mJc3ęy8rHp/ʳj^!gz~oGAy x=N+Ծ,.&XF+~q^;m{+Nu߾y[zUbbde6/bM ,P}%,v*V]X+=GKs0VSemRZߪ7;UT\h+h.؈i'+/nEs,$R[Z j҆+[﷼Q-n]r W"9CeJr+&)i*QPFcW'%2-cK +לwHҎO+EH割)vnUsI,ZܓЃY7nUJ\r#)VQ/E]N,sz97;HܟTG]3šΉw0V1scECVcX9QՂ։'v[!;oo?@&([15>J Z#:)pqr㍗ 'q;GDM5: w + | )|Ph)l X(nܷmO5C +/Qr="S8xP&x,3csZlYMTK 0.]&~j.\CC_ +w u|Ps/39jR.P- e/m1Go#%d z`݇OtEexM{ğJ4&;J-Ve‹B"ݡ%ux~8mǽcZnHO 5іʡINst!j 0ACtOtӣ~,#mybW&|u'sq+WZnKG.$:_nE֮НIj2uJA V\Ñ}g r:qUZC3 LTOATB_[}vm.A]wFuS+On\l"ˌɢiw$I]1mO]<D }Ijp(/>-eA%qVOpOL9/Pbt t{7ʙWd܃4ݵ"-"k>X ChllFSGdmϭ4vSc:>w$K^ +촷Or=ŋ22V;QZr7TiРT΁6_T}GQݚ6Ѷ^d-`F J\wb'+a.;Č3bK 0>vǶJh +c?tyr5QJyXyG8pMX ަЎ'|+s6cc(ޏ,5&r#ݲ +skh|eȒ'2l e?zKɾllu^|/jHL*^]1 2 u["K0Vpg z4hW/ 8M G՝J"%"S%Y&$JWD_%&R r`zCҞP\קi%gԩ|ZKyf2'S9 Bu!G:_y5] ;U}ʿ=ï˽[J <$w}ߖ{HaQ$ZL^*h`HGʛ-Vb׃oFvt]E\.'4Vwf0jQ&zU6{m!P_ng$U~nD7ҕ_f;ca5r_68ݔ0b=p]ž{\{Axw(c^8H?d/zO"t,'qZO<VNNsf\Y|*.&-6 G=<}&>IW]me2m\iXH;+$C^BDe;u4yM>v`4 +{s:8]/jU;@?Rs V,\8hʭ,pC=?;+Ad6z_ P9c&qwڊKyW#$OZZTm_+ZÈ}>jDOUBQbBhf^*Nw\ + *_M*鰕Gk.;P;.nyS{\H0ЊV>i&vk'Yjܣ6uÊs>U/T6_+d$DŽ/ cy rޝ]%VunxVU?^qJiWUi\/*jUjB xW%7 ؔ Mb}&؅ mztV9oZ{-kՔ&X ?mgXf +dtG̗`+rߟ!+6zfGaqZUB +0To˅ ^dL*c%*#DTb35'jQz9 +~`噷pɛF>,K +LCqEۄ1JL< 0(@O;=2ɓdX e*&fA(hӽfLM^iRXr. +fˌ CƟ+1VCeO/q,ߑ ;о. er[M% 0h GүEr0>b yv%,,L?gYwMz={q]=;̄ צ΁ LR/޴0iV׎%1}iJG:ǯsA"wn9?#:%t) (E#jߤ%*Btn\ VxNڣ9GUb%~;2kh/86\His^{[W@hzڶmVsr:*Ry{Ova!G ׵A!%J\$z +׋掟yzDK8xIk3uasJIΖ"p܇,pl7kBD(J<~'m'(s7z6p)To=5iY߆66tY&zU,y9IŻ1~#Q m ?3T- $`y)EA;O'CX1S,tvF0-D5ە97zr)֝482 ~C_+p0}{!ST4皻/j88pʧ@bU覜X)rekp1C7[EЍ}|Mx j9(ݣv!*ʢ?(u7hVs#u{%kD(}TԒnR wuP #uKAN-It|:!uK^Y] rǂKvtxV>c2jwF^?ۉ5i-:~4_**n!c=+;[$F> gW.3Y6YyÞ<sCAp0ju:.U40Xi4kShNLChc5Ƽco%Z#QA۠:kR}SӚr5za7[LufvSxSغ|ABo &Mag\>ᗚ'툈 _S lg"¬F~@@ y]8={`bF$J+I5 2ouAH_1'qMH)|C|%M'ǁO+VTkzu}QrHLޡh1Cnu X#Fr\![%PXm8A5ԒHb^(`]J8܆ _ނ 㤺:c9>DNڃB6!QiDBv|MUr|fm"0ZKtVzXn&l*V'\]w 0*ǿm6}-nHrz.@yY!\!Z j|7BVnrqYQh5ɱ2lk^E|@7G݋:/*hZkeRec׷%^=; >hLV5)K}A7Q6:'یʳQx2B-N!s$ +w# L%a(tvNzK6 ˻\`+k'3d-:> |I9^Mݶ6~5MsEoOT2^'yf#՟! }d 8#d++KTZ^a1l(vzNG͎S{8 +_Z{a!,y5ǐGy% }ĚsE_h*<u6_Jy4ʒߥ藰{~V3(EK#6dNptJ..\Mx)tRI%٣Je 0l'qa9>Dpww(T(t^{Z=HťC]QSyʧ~[ +',CFЪlp6%>TB[[{݄wgGvI"?QhOk8}_XA6չuKS>SKo[nxUC/KEb |P:9}Ĵ)RH[5U]HǠhM0ÖԢt6m-+b(r!D`Z`;1lU7HOv983bOy$muZO̗JHS"ΤHV|>A $AEVbzjoq)۩Ćjo2ḿK)&a7sOFJ:\&_, !)wVIPꕈ5tC;u5C|ࣝe4~;hqw3?B Zs +VrY/k,8%hf#7 |EDa;zl?x7)I`gx!iIg@6r,2=CCH8s⯄RUao^/Ғ7^|j/`|+mp`5Ize|ܢEk[*orYn(.SLŃ0A )#.w;'nyS?П/XlӏC.NT\Dk֬ö&]T9(Ɩ|%4ʕ'Y7SDJh`3=P6CV<#*2]kVb~$!p1Z%զ'2Cm2!反c5O#;o<=s;{pSgg`OfǬ${N}>}ii54g$C*dѻ31whi7LL%39ղbU?1"!B1SY:$uNe/"}V}s FCctzԢ;eXI8c>&aH'ex2w.Zsע9T4AfLA}9N~ 3WL0F\lp43𴆈k/!4$vY!-h"v.i&~-mG{; nT",Y;ggגMxZL2Ond` j>wN]\3xo3<TX/o97mu-WFlX nd=ź}H-Ӽvtϛ_{X+U$Ds象6  c&Df 78tL0W\9g ZSv^+P)h; qg},#{Og7U&6@}7W&k/0θ-Qq5p^T+4[rK+sGqz8L;2QJsNo'TqY!d8/w/g4ՏL*Ҝ}Wʧ(6kػWߐaFk&H{\4f{bt] ~@tY]\^ֆ7c;B#5W@YT>XJ 7I`u^a΅fntfm9Paϛf;%iY7,)$lgh0*|a~nbA۪ 5q6۩JdC,R +e;vPGOy,50ߢmlNl)V~~o>)d޽Jzbi#Т@􈄛Xm52QYGn2[U 3G)`ϬEޠ<"I,F4*0+2QQjk1%'d9Z }D!.'zHnP􎓢x7xFA)ݲOvREd/8{PRb*C-/_''z}  +1[Y s)'zoM$Z(2NdFUB C3KUgس/s,<p8 _QbkoѰh%Jd%8˗Uo'o/r4l#EWDU׊]Y:i3*#xCp /U@oy {L\UH~%'gv&2_<C!x |'ζ| 1|y6>:4bAv\s73]6ɎU<ĽrTq+^}EEipTme q`scM gggA/߮#k ^}iecn'6{qUꅎʁWx( Xi֖ jC~5zs4Ԣ*Ai >[#i}DWQ=lCGf7z*v^Ht5:+Lj]tGXCr\8pRmr,zZV!8 QaBB +f֡},]s-[SyuMeE8ʗ0/4Z?_~-Id-PefC>]OXXy@\3%VVّű)=!w,ꦥ_e86x(}=Kq읐^:+r>W՚jQ"}lIqQk!]2y,[渚G @Al^UR9MClU2PR+-v. )ň)hkcN N (RM+oRgbI+!K%( +1-D$ٿv7m68Ǖ;g /*ҥmYd9)ysW1$[$>IRGb%_*9_ )V+,Y2@?C VY|TFoi"m%G.NPkX0j?^Dv@(Tv(Jw*&A\}< .\,,S?v3*1K-aQ<tY+ni !t@K6!ۨ$H8>[k_i>!NJyVd퇑Udkm%8'Z^mQ^K +<dx %vMg3hB82Tk;V`{ e:!wւv6S"ߘW~4l`f6y3^3S$ħVw0Vheseڥށ b;gjEeW +HLɾBݟՆDžk73%0y=0Ȝro"<+ +OY٭YGW qZ]){gXfl#g +d87+m@Z( +>A!(L/ t{^p\6&,X=£,3VmvW`y9|-Dr`7/0,tm?)ҶW<ӾgǙh2?Tņvrڙ+mO +L D`\^i\7ؒZ+Jcag7ꀃlyl췳X#^yp9`y#˺y)yXjF: P +OU^_d@gD*%^ &`7oʪԩ_/N$IgF5F^^vTPQ2t$E-lQXa9kSk'T)oព#ӃN0%C}둞 1'-+ij1[8 ꘲U6 ܆ ǢҖz.cV躉[>/`e9;FN4"`#k0k ;:03=qwO6nw͒cU]s9U}UsR-TL""n']:R5seL|]gNq$Ń5Sω_nuF+<Т@{]ϒ]pfr_ ,ALP.Č6=v Z8iLp\lԓ̥>REAYmɻ̜w!T0oM؈[+`PZ_Z]P+r +X"R&bGVCeC0ڿd ]<vzo<+ JO +gY9blB̞wA*> + 6PiP99Ѱ^`ʎZXȞM +S_ ,Sj*ddjZ!PUJTcHfsnj ;N +'JX|̜yn=I^9p0oi؟f&gLm* 8oY_,VϚ4*p5}>=Z.x2fzb=ym +96/eҢ(grhn XeTۆh@;c1WnP=nD) zPVv>vĮT3~'(ܾ=os1zjχ(-ܡ?FCuH֋`R'OM:9dOa V-٢8gPECx)$S9[VKeLk1( sȱGh% (u29ߡ[qoDpѺʗweƴ/_0Ʊ;7B9mB}2CF¾ɒڟ!_*Q۲0̘ N׊o:t3怍^կxDUJҞfٱN;zIڞ}S_9jZ~4Eb78'}ulMMрPgfx0j0u&^)"1ςiOG_(4+{͎Pjt>l6i`2#[BnM+ m*>>`[uv+eWy-h^$Q2@?@v<h.7wʲDGA1:.!UyuiZ-7BQ9BZ3oagx2}500oxZ>߼w.TxQyW4>~ 50iE糜I%cw!4sˤg(*^{"H˹:%'ӟ6Ĉ0Cm9>=}^# ēob5Sx!ԳȑǧŁ~ÛK ї"1~iV +=f i)ÝJs5I{yO, ~],SܑۥK@= V +6#ޠ ӛiB+ TŇ(VE"̇Grߴ`Ȧnћ=t=2k75[1aGi(\t/U?'vدg.o ;n} /6tpZih?D8S:w7,XܠX0l? FA\XHXa5xx*J???s4T!qDUw5M=vxZ"s#]WkwY]@J}5x->qC'C\9GNj6kR RH(gǐY^lv.]Xg%Ӛ;ʵ.$1i]q*!?A!Ha;e."0BR0糿:=z4A gA#&3_;ɋ!EfŮ!r"eCr̘2~y*vvˑF/Wt )Xs+_&4`1[K^X4(z +o%KʸE}֡ټm4,D`[!#G!6;zSTC_)"٦p熐=`-* fu /Jqz^PN,@rI>O^+9=ہgmC/GF,U3Ѧ|-E-W:c(~Ԩp?f7O2@Z*XSms*jwL\whb` C!WwTZUk?9]#iSJR~eWit QТKnnQtV%saa:?3'Cm<RL]KAWojG,x!B:O=KFSPv_C05_kqľ)I IЭL(SuFl[ŐQۢ˄:ǖp6vwh;U]F<4 x@wY +C~V%SՌc53nAc؇`:8bk5 ʻs}Nna|(8FuBbV6w0*Tf){8QEΙC.MNf}纭1Jn Zz8 zLNrl=ˈ&8A0f6gs yxBYK& ^Sn2[^ҙt-d%%MB43wqrsz@(UL#Ke6xh +D#aRJ!:XS 4^&(속G&lᠼ6>p)JZe?r[;Cx3/bV"^ 0c <ϳ4zB>,JFϲXOɺSk8W'f{@L܀(^ aDĕrIL(>fh+1--K$ΣYI {ih$ˍ}A< vJ}I%6AY@&݊| +DLcY@#s +C:+ 4X]-!syV ok~`9VK +6 vNz 2*>. a ]d1suk8Cr^("^0L9! [` xB*HS@.ni' 1w4#GUXIsL@9M,vu q2J>T"4!WV/=$ :m,7(Cy}1 +Fw9GxpB)J%[*2Q%?mu 3Eco%*&J&v7S47h&)sLJXXú!{F4 `xw-kKD*z5F!v g7s zݨMg);/N${^}}/ #2TMyq%-,`A. v6ak9x"tfR˰X{O:_VXy[)3!,!j†K0p<˹JpM0#_j{W+mb/`JVx] +D]TPsTrfJW>)mb{)59$/Ψe8{[1%KjHDyg^ud*3’W0l[[NiE9z+dJ!S D!i@zw_N*dBz.g+X5mco}B g +=e'GT`}#mXCM%u똻,E0' =E΋pKacrd:= 1[S<"vg(+~!Xyc % b :vYahy.߆z[_NDy6>XBgP!ZNn,."Hב(xZ!n\ht9)TqF퐢isOH - LVNP-l'JYݡ5)喤zd7Z2N(`ae/|`y8p>̢fǰh@̀52wVq۬ M?7,N\K J~Sfc@TbNF?ysI]«<\s(_VyF*%/ؒ":#E@hbqI?@y61I!8$>\.$i߄$Cap(vegw8i%\CTNW4VRD j6i+cKׂcg43lUfL0 q~ױxγJoNh~_oQ;XP4UdxaȔ"_rн"Yphsq!-oe ̇AA>SP[ynHqjȰ'n<*mշ9͎5\6fcz_T$tW}i2$yi2 o eh-7BKEˢ2;p0<2FKftɪ=$}>6YH;Fj`5őէ+(AFe""d:m4>o5XL5Tω̱UuOF,Gwo1vCTˤ U_T ѫOeOT2K~'kp`"mFi'wRB7Ɩ{ +ݥfp9m,F:nsC)>b퍧+w-us Æ#YO7ा?أi=|MCZw;-@v?F~ymU qDZ u㖍b7I!vzf:_ FK6o@x=&4%th2Syƭ Zsj`a۽~u]ʴsy{VJ|LZ8_#'FOSrGv`' +l}j~}׳i #؃Ng0bI!^R:3Re,T{oڙFRa0rQN>+Bi3.Ke@4)TZf(~1mJ G>}xI*ԲC7rvy.Um"HtmRploF*Oj?_ 9'5XzoQ};xHY0KWlSX&MТi6[]µ94tܔ Nt/fr )qJ{W϶eiIa`~#UEP}9Gs) 91&RiO[!}; \}dd H2ڤ`- 3l^f%^e}QqXfZEa IT2'RY.iU-JWE< +5:*뱕g΢6C#?4G,/ց1,WZF>Uء9F dߠRlͨ+[\ٝrpNLez.1!M)ߍW W:X9bT-Q{i\Ѽy~C]:Hnf>wl>vBddvL6JaL9^zsK>| ^>s( 4f ?XחLdzzn'9QLh[z8B<0fh4|8gĠVV^s6=hovV1Z=hxg&:&kh9X"tūr'{ҴXru|"uz_00$`{/~^pXKΓVY7W?1Wݻ֟zLaX} c>_p=UEfVO +3A*vƑbJ/Ȋ͍1GY}uq&°o`¿yP7(tpR($|/7;rNRS[Cq Dְ2B =?j!ηU$mbIa 5ۊVi9FP`h04˰ú 3I uL^\/nCe Ȥaz )1r +הG Ŝ&YkUUzz*gORlR,mL +\Тbqfq}w&y\Us?l]={ԟwTl.䅓tR74%+_ƭ)Zm5Ɔ+~xU!K %M/OR|.wN +eEqJr\Om:unٵ&"s$891[n^3޶bHeml`q2$ +: ~"c#ƾGqP#.?^^ khRh~mZ|sddnѬxIy/IhFׂ{,eo,ī(bΩX0MAG;K 6NL0orN29r+BӤ -/'Yg?A^4657៴c{AlA? !B~ '9BmzGШ#ce_#iq a3ws AGMn=P> +#|?@[yC6rD͕:cĝ淆o/T{<oMGWNZ.NL +G. +Wf' )=d)nm`U⎠IgE2*p±CC[}TΖ~' 5UiMJt8m_,=|ԼK%hI-@sW +lrwIwM$k2UvJL{*ߛW;-79A0CZW'os,k⿪ v F#8cz_̕zpi>=h1R⛭'`9Zd2Y2PZ,!=zVü'h$yޏ^؍n`#ϗZfЈ/$Jw=v,zqz\Q= yFb-:x&}#`xL[!gtebd~]E\ב#@F鰋8mOM&0J#qL>o9K`B9P)IsmrD:]r,BLKhl: mNpBS4Ժa2tJo'SxAg*oy.~g:x" AyHl6Wt}E*@\345 OqqwGDot`k B$KvXо+(TR~^~ԄVZ(hH¢]LyX*lG8Q.kތ)c̼"Mu)7+W\0jg<~th>XVϥfRKT3_a AfyzPa9j`\}?^m\7{R!I]]O,iX4%˲rVm&u[oC_6imKWYv +zE]q=·PtsJBɊ"٢ʥ:S;PSzVgwkn&a5?D#DVRONkӮLnw"67Bzy X>#?*0B.GK]M1R\m:x˸[bsd{BOzCBp z-,)gOfDˡMidf/Sak c5,~]\d%h'plBIdW%0cwZ% 'l3 +IښD̎kؠKWˡ'57ؖtM^`TD8-qޫAi rh-G˭_Bd[r6a! HңRwB=эҵNK>؁5[4z>RDw.o릠U_4U]njzޯ۪eIdrPUnO RllzCŇQumR F_IT9ӔŐ S[zTR'"Ai<+f;3~1'n^;ͭbUo]V콞feLjMv^cO;`w%Rv, RJUOE>hZ0fjsjsR2t,O0`Lj?1gxn֬0~L\Q<~o7G k{q'!v{&j<=/#N8EݼȥV) }pC?\Ecڪ=8Xn'9!z4k m6+&+f3ᏄPD+LԘ[HD⊛.26g)KMrq-[p@t_ X* %э@cf^U8kB92 ;.h+-N伲F +L} ? +c`,)iƢfpd >AndZ HtUl?- +pķ6n 콐ٴ>*ۆz(vm}F6j#pf.4 o#I!)6,j=!M(C^Ykq +NM|' +NجG@YĖ6!I:F_zQDmQ"␘ŊA+qӶ\FTЌbAzDxfsEZJguq Z#;uMC ܝ־#9 w4匸iꋫC=5Vhm՜}Zgc‚\eXؾ{sC&dށ˙o}o*Qs{+ޣͦGH9:gV]i_F]@huiix+4!=3޳ab気r-Sm@K\fd=UE| Aq0AYh@}.N>ʈf L#R@ +rvjwk2FXS"aiN$Y"}&NѠQڪ`F#k*T[iDuhz+ZJ.$P`G4MX7 +9##K`EcNճ~s6YB[if7%9:]ȌHj؈vFtK@uOPn| p"B?sQ>tJFڛ||F;5QR.QB+Z2 `Z +6$Ig]7%0d$ۆw%^Lɦԓ v"S6Tridxk`*ǭRQH *oDorsgUYګ8]y@jp7Q6pb|)8!ypkջUmC +okkS;w4HsќQr=^}2y&{K"hJ܆UUr0Cw֜+GbA$Slox-.ŌטE0itGԖXVg><+&uVl(N4F’Qϔ0 mzBbWU0zOBI3?(afZo1ǝ*sMqߎ=;Fb76NP)u6jh>D'6y7vrvuqXτnMX /)B"1P629|etth][8OU@2HӡsaF03=I3~!(4`CXmKK9E@H$~B"m +4tîVoīǥXbxVR$^KX*hS6 B +/,? K>_}˞'$NQ2e'|ǨYoSXexN5(8vQ`.i>jʲID3)DB.U]Dz4k+K#}ׂH9Ƽ}gI]z]R=lDd7Ptb^fGn%O13&Y 5HC;K<1r~%VxdBN2VF d[ 7tPnՕ\!WEX^ }-؉S{Ui_$7+wMū<Ҟ{u6Ut lEqׂ I^ypZ 5HfTޱ-NRgij }t )H"6鷤SucQ$؍Nx?j8N%? "DR6'`r'swa7n{ߓ}| +,iK9cRw:R ρ^Y5Izx YXstVTt$2QSZZĦ(t7ze [vo"(l((ؖѱY|\/뒖\7*a +IcI^X! uWR^k0v@ GUf9;EGq_H ÀXe5t_;d=Ϳpwk`߫^:qwKL_/IY% `#>Pɞiɯ"3 "fUI0?6;G%C#|NbM#m*IƎ.DŹw) +)Xc}(P.3e|_A,w5d}pr/9ϓUI:eC%^^(\e.YLjI6֩$O0_ˠ Ug'hMK=)B`6myP@Hx[ MZ@ѩ nRzʀ')ḭ*15{[e$˷&+z9 Ui\UZ#jxƮ r3BEy-|5pWpv0 y?QC*Y&ɥ @TkU6' ƅ ?'M\f 'ɊТ9KfV_ykJxK3sgܔ|fl=4t CroI ]<Ym8MGrY64$7&׆z8EBY-;_>"^ jbmLT=cO8NTNǬa`XfS;/NۯoLSE\tnIXxkz]ebILT{12cu<6N/tk];m¥ +Z2l *,j.ck[i6;?&#!;l6&to#u:/L+A{8zqNkocD48nwݥC(d_v }Yۊ5]&9}Uߣ4XR^g>I{Τ(ʺdtFӌL Q_خ&gѤqXu&esg rɨjFY&;Q9 ۔kIJͬTFr)4E""Κ?7K*w3DWj]\2"U.b(fXn^Hy [S{zNMkVP¼?ePƮtOYKlKbn޷)a +_Q8(FS'2_ TP=yCEMSjii6M`p?%ޒ8%0%,o,h?فLBIk{aQeW=h􄟟n@ vH=:Z֩ϰ}'R ꞿ,cu%@R<&j >f 0HIn_),)c2MZA O5A]3k~WT~7xކ|SGuL?pXɎ|&X~Dw9 +M k3Yi!ܪPI4,Q\t6G(m]X`܉ E~)P4^#E$dY^j3ٹk59WAG*/?X#(*qVxqJeF(RɻۡZ;/C%^2 *@^P~W*iv~I"i ;ܩdIPBEqŸ`Gf9VL 2,#PzGéFj%eMGdM s(r}cENV^8LZ1DV,6H?(;'%BeqiY,msZ:GI`3S(բ<7꿜JUKFd g}O*[_E3*d蜮niχ??lz&a]JԞ9ײ==p~}GQF& @0%mƅ~ο+  m'_/?T + xY_[ITL2GPvE &MhNH jZ-TVA +FU;`[D8 yfy9;aZ_ U h{z<5ǚ$x;a67 +^ z %@=K|~beF6!aiD5I0"mFRHzWƹД祏KeV*r`#]?K<]!BlOO)꼾).TlVd_E/dw(?ӝPAjNDhY!Dzkj&{rL}J`E* }Yhʌux>vA.CwlKDLt +cZl65M jz6854m攵 <R EuD?,A&]@Q!43̙y_u_9g, 3vtT܉O0qMȓ!jUg)c`~r7$9uW (,m\p`z~xTGjG_`yylOis DǪYVh;ٻHsJؘ/?d/q(=UƙBӉlP_$*D4Y){")ʡ(#Q4RĩE22Sge'3*%չM~< +2|J٪,5x"韚f4EZ'|SS6ҳ]]5}}O^բ{8E( +NBN>?[/'K|$71;$lgFj@Q(Sy|Z߆E8'P&Z$L .MO,:Gj+NaDz3cSߪZoQ LF#bj]}sΕ)JHaBonju>(G!<H-.hHMXTŏ(fEs +;!ş3KGfߖ)ͬԋyxXƪiXfVLbn|u Y8JI3}m:lgEBj# + Q_|ӕPô9EpT;z +4\1 } T#~ey"&C՛-q#`Z +:jwL}YAcI?«·_>4y5h>Z~YX?HAeV#֐X7˜; s-)>ؐPVc >~4O_RHبIZM. +6' kH@S*G/n$N&C T!]. 4m& ++PRe cj:*|()C1*1]-a)86e>H L}k?לzT|Z +و; ޼љtT[5{0za_r2VIbNjˁʑhM;J /t}3j>>9Vd.iqe'eq+K:XbT#(!~xʓM%B"~nM C2M9%>b? HmY#Nʛ)h{\i +5i"=M? A{mMpͥ~8$,T3)24}8٪*==M>+s$s;nDd 幱MW: z@%OFneTόR\\ ܑd;^^(>Ͳ*C6]5vW"+ѦxxZ*ofaXu,)f!QRpRT _/މH|Uխq@V0$֢TZWƚJh׬Hy‚mmKmh5Z0 L IqD)O'A^G{EGg<(^r#`4c"(we BGQmBޏ'@ Lxp D׀,["m%q5( i"#Rƚ;ȫ8'D?'NMҤDVRToUӺ<i +/`%@quKhb$R9KNnJgB1} hV"Z#bn2V̸){@Q2ĪQg_*kTżQ}Jp0%r*2@-͟6SϞ:ly?3TB PDcjLy +" <8(Qg;H] + qfwQpb<I܉(Cܳ=s( +ezKrke3K߅]y\3ۡ+jH4RO]aVxx}: =0/5`4*u HTȬ(P+;K)yd9}Er}7dsFQEFbM&G Ʀ%(Hc%V´E{O9ŁYn {PƙS*a:юEްq/%VJ"Y^UU'{^xЕpj^ߺ3t BJ,,;z8 Qq'&&G5 o o-Qy5ijRzBY تG@[gmXr:3U 2z=mGPTqx޾ +^f`‚˃`*1dD邈’E śK +lKVΗ!=>UC`!&A)4j;C803$_*QRNb`ZĒXԃP nꀜ_? k^VÐȊǕU99鈜$t޾3EkuU?hW[fDB1t] ++,Hur?*B + -nKOdd~´%.P:y߰]Mq8; *nYRǘdwu#/ +eUˤby< ړjONK"]k@zBr,LazOfKOuEe)e{)g5?e̗i ۄgJzf.]ߝYJ{hUvDXH{L]MTP&Eij|̊^nBAzșsdzv٫LA8 k jވɿ9@/(= IKJ$,;=+uOڥ+,:+]e(=袬M$`PIaOPH~J袬0re1 .<^i7kHP?@y$ cZjk;?PTUey\ի [Kae,'.l;Tp z(S.3;2/١SI=ߖCW-CT /Ch++\𦈳|vv6/ju({Q|8vyOI;Qq !kU/#V!%V@>ĔjC;]! ޷Ű.OV|#8 + :97rAa'R:U*F,FxS +ѐ($šwM9uݠY{q}NΘ|CΫFE'?.@m];݊boCp#{jC"n(3?W騗29"ٞ|!{wN&Xr`'jD RE$z]+M<| +ŷ ٲծy۪?\D:lD77 \hݚ[Jd⓪t]>#no~06Jl>OUoƛ=Am߁^ߢV:JBPYrw+tJ/|é1;*T/AG 㐿jFc`x. :p5.#B~AW|Yn`U {W[yÈͨ *[tZsKUצ$, 1R&}JE'=ɶwQ"Z'Q;_ouԃe2?{g '//9WB.[ ,qt]IjPu[rL[QЌ<\ yBL!Hk{4kI +dՍ-7~dVby=:&cw#f&sUtڅvеca7r1 "]0vL}]MSl'~W3Pm݇ȭ0Orux&Nj-*{#Lu +jLcnHIPO10;WRi0tA@ڣOUUkb^A6k` D> ;y|rB Ώ یuҭ,k[mEhUd]FD6SjRb#x,BV?4Ǟ +@2TX5"6Q6DUO}3#Kݴ?!3;OʮmJLd{>n _PU(fDjP *K[UV`i\^@y/?ғ"}Fp2M]Mڎ:D[S#__KZ'X 2=—R3{" ixR_LDUu%'t)#ڔ7BOaT48vlpg*,UGg tU Dp}:A["6o_;ĸ"6 [fFX6禷?H_x saB? 9 +K6C'{.Ta6 +ul/ [ FџHG@şRJT]'8 SDubf";lEݦ(0XO5n(7s@ooag("LD6ـPߛy"Whś:9 mRq!|[1?{38UV!YfUs45N5<0@O=#Hwvʼn' G6Y<d +֕ hk@囜~H˨2& +ny֧әy]#`}GZ,ZD*Ƹ 6hJ4Mh=eEW9p&u+F ^_nJ=1{e\d9v2[or~3(#-4(PW(bB9OkRpq we䬡 +eJ6E7kؚg5Iz +r]BM5'AoLF3EY64"f`n'4TLH9?6ۣW|7ﶥ07x;bd99p7S;TP:'zdcב۝)eX @= 2Q36nŕ|r2Zq]dP>@{aW9sc OT1C+3ec26Y{w1DP8Lnlp)lL?`q^J>\H"-/\xXj*?UT|.dS9msj#%qVN6-xzC)MRjW)i2ƽF:\"8l{V|>{̢Et-o$/2*ӳփ~hU(a:!C+X7{iOqE`MW+|lI_tI!`2 p?Mܪ +dNe75y%RYΫ2/GV>m>{6DT+i#xޤ#7dɇS\5쭅]A{ZTJ3UpnBJKŕP{i#~a݂8*m1Al =GԪJ^Fzqz+:RI$#Wv|OSUn@OD޶XO;6ZMQzWi(%2.“U>o@w U16$lp__ ~ =Dcb S()u: l:)$O șbOQt{Vr*u`+r><@>(GxC~EBԑm| 5 b@{I3 u$Jc_DO3H]ٲW~g+gY۪%ҦA&ooiW J&f.z[X*Z~zg5 N-<̶B(7wwcUw=ӱW;++Capr3R%?0x:R'~effdzeJ`l)*Ae->H.\%Mc;/*a#тLigt2gYK\ =?NW$_j׺`†MOZ[ڼړ;`ܮ +C#ѺvM؝8#m;6wp>R9eHь1'qYso`hyvmW\ݮ]sM[mX޵gr'G=c?/{W_^_m;}чVT?|o?"~FnAhI*r(U[5ug45+ihos{ Yz5m:qKAWLL%f$ |duzMo_leC%y)nOvڑ`9HgZR>y-j1T؃qgfgfJ=v(P̣Y'\ʽ0M"Іb'Oi8$*gW4G+# WW1X.@O'RM_d|a9B ΉI׺%↉ƥO-mE܎J=};CkGJGNԙr3 34sjٜ>6:t cϜ|tؙʳ?[\{u)rÕW\WY1v3Vm]=}üG!m}g׼|om~W>Gŏ>|~~ f?J~cwC,(*+{R^IPo 8HYc摵Z%:Z:ͭlpڨހ>~Sf͟2h54 +6dd njadubehNMt,7Ow+=O_zsriaa )3?8)$4'920R7jM?1b?Ľ(^)S-_θy-fݜG.YR+)6+x@+@0!ګƑ՗P߱kqxoB<L)KÚ*c 8˼o#NQX$-YXg#K5t5ְSz{}5 d2&W& s{zϽٵ{wA5?v!Ñ#}G/;n"$3?ϙyHعWˊW^Yq6"Wn=b)*vQk;k'/uh o[kC9^:/|h% +/Hw^Uv(5%w؅xaBubVRpSTOi/e,dnRPЂ´PpO6u1dc&T m# +|bW݂9 +ė@|R9 dQsht0IJl);;ʿ*x)RoJck ^ +Ḿ-OVw[=Gˏe&'Ms,o﮹[Uxj?|'4O&q\ .n_"]ZڝsmCޣ[O2zRu>T\~Y+#}S4/?(R ]zFP&)ʔn* +(EFQ 8/s/*g`tE>p?pZA6bdH.9,&p=;c2jxA'Z_v;C HfR)+ ^%!9.֗9f%~{gcf# %_ZE[uB|9VTH'{LH}PR>3Z|ݻ3qK=v}!PlÈjZJiK#|y[bn>}Oxxn:6r{\B~&aI4BS[6qNV>~M'[fO&tD#|~/sѱ2Mnߎw:c+Gѿ{5tۃ } +RW6KoN,f/9ə2:|-s/;R@gCS݆f*vmQ<}ܮc\\ɬV1aezڙV5|])fti7 cSDo.]0_"ȔV t4@**$q}]Qdz|=-QP¦ l=@Yy\]EixRBY%w'ca}|Ԃ2207/`FN@jâRrSݹ| +ES3@~"H%["X]=E6O&wGF +(\J`*&B)ĸ%bAj/uų@Wg6ȱX`F'>v%o'9q*yG-[F(J@ș}pxi;Ho3{><4>M'g #,v}dVr4>B:+1%K 5@ҙfZ"rc3J6CnHe3I;$~'e]7uu(g {FiwJ %ÈBkyېk6n$gكwBbP}υ02pq; +1IgMoW3gHyI?i?wfh5F݅2~w3FP ~p`>A7r1 j/ K5wU&=&}?(ۜSͲX0VٌLG9C;H2)TKm  +s^2Mүba )<~~MY-61!V):{}ڃS1s۴UTST1 ;`;驢lsZiK}S:V@ On`= VOgG9Cjΐ6uQ9YnYpvv$*8BR^sMc76bw}`tH$r=mg.So +#©6b_oţpׂؑ9_޽%넠"pXWIBv@i-!TnV3j9`iJq$]9`z~jyrv{nt*DJ#h}/F'1CbU޳$%,Ls>zl0Ì.Bz42 2VP{{2€F@`ƓDܴ#_^Udj-uB{XQ"oTkpmxJﱏp ӦYLVe eZ0=B`8Ҩڠ|{gYd eiPWF#̽zuQsSdGۮBvF]نiwO%t!5]9pr/p[*QWޗ̏u%*<ރ.nj[ƀ}]gQdWS5V!e+"/ ǻ`i(9h .}=t;ImLْg3}qG<}n {1âkLj ୴ ܆eRmK"Jzv 1\߃w6J/P4ba6I,OQEi5A; / D"4>œwc^e,2 t#⛭kez4ic,}DPp#@'ʂ" mE,g6~vwk_в$q:5JOkm +VJ 9׬Ǽ&o8LaƁ ;٣nMr}lu8|ɍ6[V-X}Jf7Ԫ %yPI[ Z 8;jFċ  + [vpU#g|lrOP룚ϓk%ÏI|cX@K%OuSujE ,S[9Gvm^r@G4L$Wr ؇um>tơ3 ˲,<<*_NrG5rnq{G`&>e6JzzwxDnȓLX+u"ܴo""X6NHqn25.\cEzlq\xV3@ioe-Ϲ/vV~>P\yԛͱBG{#8CϚ.TX!^fLyHCxę1VSȤ3myhK9E4EQYy zVnc_%ap?OCjҸQ p ocV9?03c{tY5Zu˞7j9 2\AX\Y))fo( 'ܟΦl\q[y׶j}qf9v|XLU,EHf.Al#WKq^~fOvrz[!:#Y}sMpT=N6_}͵49fɸ,btWP'l~ONuM&>}^V +ofʉ[&iaUђsvs=sʱ|:?u6)|LA7Ea$kQn![|"U8 +ŇTZg.@ܧz(ZAIIDO9asۭEF 'v^faNDhg֑7}MVsGheOjl͗1pI` 6=]Xei5GS\t2õ?>*s10Ntx^\k(aK a>=@CF*ȑ|>&I>'L8ʝ}mc Q lwl|Dm饼)D]wV>"Cp +3c_ꍆ sT۱ IJnG'ի` Z4t2\4:Da#L#~#vC3b}.QMWHl{WԌAMP*;"_c2-x\<`Ȱٲا\(Z_NKLȦ6ACHޭp7`r2MgY!m3=WӍdf ]9$U+RwLe-yE:'wAUfM?2;Q +@owӝެμդíͻߛ +eKucOk0VϻƁϑqY2MYN G4X=4yC|Ӛ 5`YFhOl 3]¼5:Ǖky0uױW˹;$n+{6Z'ݐ^nBu^f(M02aMϟ= '-T4BN3^v.&eK- gi#]Zg[oޠӑԞ8{n%-&~T4+&~&_ 5n2jurifpVa~ n&^P^u`6D8!Bdv#)k/M7}uOo ǡ*VYB_&ez˚+p"L@Sʧ+cPm"ΘrݨawؘZa{H)&N0@;9^PTzapR](]s$vG@M8ʹSD;jv wQ|wLcz2z'αᖇ'Y'jO1/y2'O\r -:zD)s4 +Aw 9-EtΩNg8i0;Ll"ï]sroˌD4I9 u{־8t(Kwes߈q +v\zsMxF&Yvmd3hזǨӍ=k~q@=IBiP{jv< galM|.9"鳠UR6iWoXtfHA.=l|͚hANL-##1mnж o.6ןK\Eqx_LbvTɍ3;#S_4:cLI_lQ&NnHedI]8Pjb7O>h*840NXunĬ2)m}ckgԢ!Ƀ"ԭѵ ^v19 T<0AN)/WApXf]sjm=ߐE%!P\_8Eiʉsm/v? Xvk5?0ܬkSZFy- gsvcatf|tXX)*;ɈJ+R_*hMy Ct'7՚ߴ'gDXZ& ^2#ɱm'#Ԏ?}[ ƩI݉g7Dig '60Of< |Xoʍ'yϩԹOLI(Lc=+`R1[t9uyڲ1~CZ͂Gg&`HpyG:G? ; fǽ׮3mt^$6H `=̷ 4j푵 +׹NK6;9z&Jl*LM^qf.alkGCA֍o{bS2Y5$?Y# |l>&>5,qEƓ];{Oܓ_Av&RBVTwJZ#Y/|c/řX?%f[w}a\ y=nzǫóYΊMeF8<ν7"wgI|0)7a,تJ(1%%҈"%-" ! ϽKPns߰^[5/˨;`D`#&G&g3fЭ-r~k T ץ"{3I? Oa^#O3v:#>lQ#z]_VWxT>3FaYPLVpN/{Xb]v-D5'fc.ĆMe+­ \iM3N8[LkiY_) fy*ϋ8jI.m0&zp)hڃ盥7ԯ۳ubPBq=hE<u݊bH^Icd 6cq|`&ښѼϢ„C͕zۀ(n_T6ѱ^<,ۖrfx1k\ǟ}ޑj?~3Vu"`^!̹LߙVKC,q6Qzw 4}o0;h .M|N]_+׹YvKl\yw +<8PiTk/iHJ:F.jzx.ch׭U)V7<|YRñ^ެ)}:0־NoA95VX[az{:ݪ\,ELE3ԣqDHM)}>ȳy4.`Gc_&XU)DE,ة8i#wQ9wwRz'' !G.|^T^pK9ץ(W"g=grt$\;-GzjI7W|Kk?8D{AytVD@9.ͨ^MF 3f}PzG~aqQ?`=`~`P{$*?O}UN},b!~QpF'c)m VZ΅qǗR:Oyi[c~%ϧG{賑vI=;i] /PƋ)L"# ognt5:߫\R@t^{(9D3Âܭ4P\d{ٛ(eǩaB(2-.%"$ryk_Huˏn Uik$µqb!GTzrUz?C/"G'oDiBΖ>bGWrC#7H6MKZki䍕+䋺#%)y*Y·h^!;wكC1rsˇVؓBZHAl9j[ enVJjJ8.q!_ Z -;pb#CaMIz(msQKM4`~p9Tp.v}\_\v`Ȧwnb|k:=@sd?],}JgnWM?{N=pAI`nzgJV(}ӟ +L_40Gl4:j}.vҊBv&:`+r4M1у_9;d2c"}FN-*O~!\I}2ҟo,(GK)$V,&OiN^~!!-}0 q7I̺l*Z%@̜fO͙2< f1x2o^F}7.t&v?$}) oD *?$?;|54f-+2['ƏP7%N#%B9*(M^'\" q5X%J3KHze5kZ xJ7E'ZPmcRȷ5#ˌ7ۦ: +|Һ{[;HY3n˘ +bMs2uj~=2ݮ~-pAn+%\UȢZ*3w\_1=9[lJ,Y$c4@T$sY\}[vDwyX&p93NOx+l +04DH.mwX"uzyZܫ*z9Aj6 0H9;xzdK3됳tY3Yⶥg0Y?w`kǶR~ε !$gv\\<ݰ<;SaY3Ze^cٱxbxu(ϻ&梫6}OtL6YOyn/[ Od8G>@ma{iVJOsiG3Wwaiao~ȪK+Ȩ$7|wgɹÛJGR9ުrEBI(>gATcZWOEҥ1ep;is'eWe0qa/>F`")X+L;Pңӥoa-57z_|$;W:Ί+a_dڎ~+GNUiSmEtԯ8?lteཱུ^LſvjFڗ_ 1.!ko&h'B΅ڨPWt=V zӌv9&7l!|پs)ױ mΌBu#~0褰0Z-^cU!/-;[KU,#I80\\dAJs咩ۢ7hGtSNlcŪH&1Ttg0J0Fob2`8^0cVu * +boP3,י +O4)ҤO Cp1˿O͛s6Aw &їuN +0r-{EOn..M֙sx LF߉_#R:-XPd0 FkrpUPk(fu(9\3C>9ID:}!He;X k^,f4Q jmSr}ľ551Y~$K|9Yp6"_k'Q.ygׯ"qݪ>c3TWua6""fZ%RhdjŁ:",wՒTW~۾/'T7[#K$IP:7~.'y]]?˿pZ'稉G*MǦCZ'YMegߗu57U\#dYyaJZsa52l:wS +GDu#@۩0\+-FLcLC+f1H[|)xR V @/3|h!G˘;9i.GB7˃$!0ژ+X~};@C- mgK+䚉 >&4;^#ğ|r{~P æwB(#1xu]lP @قue+h0;+ނ? | ⯽g%XC*拼_5~S[v5G *PYlGK8b/1)<&dd!t6׍?)tZ'"fS*gՠ1JC~G:#QTdy.KEqyN!/w6;%"WAPYOU7^EDUc;XG &Vޒm nfDng*b% %6oټ[kI[ XD"*ʿ[4P> `oVz^ #\UU%ҰH}PZ7K}%HBn2+!X~/H J|Wx a4qH[5ůkR~<΍}ucdJc_#5;cqgtA01 |ͪ `qzsPY]\ӝ$-VӋNjDCg!?f1x=𼶣۫VgpJt-7J.K>.12@^3~*> Z[j}ߕC)dA*{s82pt;"Y* y?a`yTÒ?g)BJ}l% 쎕A藘_b]WET-8-o5y+~qҟbL<ƒ}%i3FU-ъlF-8~S"?RT`[xpa,;2P+VVݒhq%]q ++Y{JL4Ld+$+8.ߵ0Zd#n4Ψ4T 'uI +CO!?MUL)<#9wE`_}=c_ [㌌E*M卽crc:IfqTDa &quock/c<˂`w zDfm[桲/E{m>U$01jNs NUka~ ױF> +ie;U-stuO,ů+#+ot[_ݣd^E+unSQӼ H/W='e4&oߕu8̧&/yv\1j:^\lA{o2eMܯZLG A5TFJDq/ U,ۉOrD+UZ +]aAnX;_u:˨(E09b HA/ʴuaQhwq]AOp<%[߮?6oFteu9S$S äkc (Oki{|WIN3&.5&2NThHw-;u-tUWTV5;͸QL Vf(ҁ6OL[[C[fX + @rlLQu൚9`MA08̰⻃E@9_҃mՄ}x>ۺ"ZFw tItζ UB{A>S0̽)g+z,q&[7Īx7Y@F467I2ὼn\JnKKģ9kÅEcru +^R*S$C|t6㡶L~t&nqݳm6ҙs95d++(1st+)/+(wSp={f 9ϻz+2[.4NО~^SN-ݬm.R6.SԂa!fNabﮂCVF͎c 7,{'77k``?!Ip 2mrA̟ vٷ2z4(mȨ=5R}rWq5XrA~fH+Tf;>13FCĹ 3V7efEWCGvWzF45qu$N%f#5tػ\D1-)=H_2ۮkCRjJZN3rkuZ$d+9f/R8DПۂ1/ZO o{kRes`Vo,9YG{CSrtAV{ήPX; KA#[=8Izp67Y1 y1er|CmK63>m ^'{G*@Hk;Ad; I}6| Oqg6|squưvdz<#X_2nGBLt58"t$^dIUZppF\grʹa+r*%!pKLt)J''^wUݏRZ]ت +T0M+p*b)!扰ZSw\?h<\ӭYdtWPvb| ֡Zzo6-Wt׵ve=1mg=IFZMnȾi5gzAC+~ȭ!uX6_TW641#C laS+ָָ_o1D~_ӋX2ǼӿænwKs۾T$atD}5r79VosJ5eIq-t?|5aaφ.(!qv=kԺE@CرiuU1N ZYq!xv=Dq%Ī& ~a[,ZPU>kue-Bs[ +E)+8%>!o;tq+@pzNN䷖o NGoZVr#5Bq_9Ⱦ%[dzF_„N >0 |Ċ5J)Ěl;d)ALf["&伣{Tљ*Mx Io^&|hW~r̙F6<&pbM2 r9ڀo};ɵMtQQ?Wjŵ#26#6#S#x<^_~H9b'5$Qj/]P3jew"6{Ձe5vE*2s7:#i,W{o=U$}I]rY +^Ks_Z.gMg[1KӑCyCB7Bp!eާY/qݳJ1qXdJ_M?Iվn5tOA~UF%ROCz7IɌgk5cI3ɀili(W`rRfGh?^3Ol'3O7_"dD#߂+F񩟨PG/Oh3}Lbq</V~._i(/*I=^/"2u&Eaa$t=B{~xdv_%_T1~7 2CLHG +yWxmkg}o;@+K(Ψ!(^_RW=ޤlf]~\\ vK.'n)Y\{Ofm&|gil<^R_~)2J*.Kjyrhu!7'0Gnl]碌%uű],)l-ѐ%)/P*({`]~A4( IyQ{w>Ph`VhꬒvxGiQ'ʋweK`o"VC_gO..ztlP;]UB;.J((e>MK[Ur'Mׯ &}Q?ɫRܬ)ӞXYs.?nRYPe膐_jxV6=+/I+C0RG,zɩC_ңpfva,81v{1&q:A}H}Ov->8$iZ  3 { B-XA?/f6|U5j1+@Pś%!7m!?(7F&$h93A~3z4f796bV9oDN)0h^duTGP ?Ih79n"F\eO"\ruӊ#ȯ.RTwQ ]n- ujʑY&h$T};.9CW ?"mh|΁L NܢZjS9re7gm䴇ػ o i}[ɩRd%>[cB9s5@9HIn3h640I^Nf"y{V|rSk92$N!WS>j/3l:i{s$XMqGe&qR+t QK%Q: ߨl!fξ,:v 9R2m;Co'r@󩷡`R"η !Pns/*el9>r6Ai\~ȟ6)7S`} g'8s&,rKqn1_WMw!8$ ]W?xRch +9E'X@4n3ܲ5/K3Ueu +>^A?Oc8 +g!FE!R4,v4iD,d,3zNXCaJXŮJ f`˽әLk7"; 5Vs +HO|]VPaZɛLԱl ": bjK ] ž[#17(.̽U_j2'2>ФlUK7׀]#p/gk-(4:O~t k~U8L1JR5 7ƨiƐcFչ![2v`⣧$]Ѯ+U`[dI"U-h)(t#`),1bŁ,/lØ3Gzv6ء3J`zox?}DiMEkj1bLy2is +`n%"EcWأ]cgϺlXNѯVO>F@?%s +Ӭceoݽ\%biRpYًfrbi1j׆<]KW'cN1t̠.ZB\⒥x %k'mn9:7f<1llXmL,yaȴÁx @`MXo E[笫i߬H8%!3xhz˲^^)ik?36"VX>CWiX~a4ٍըh74s: +@-Q,DpɹոxNQ`z@X k8^ 5j>0IZV&CvC"V#Ocp'8TO$#3_!w8C5 +sk"Ud6X-{Q#vcE1'{0뿠Ug^] sLP[g`k{VOi*3+{`9֧T!1 $RnC[rmUI_'LVR3.9? pƣvÓ3EÉ І>SWk5X bФn>,mr< [c"}dS +lşw +,x KМxDrxvyzx3y3P"tV^y6++l&C'L bgwQ&4GυVł,ؾXCUqߢ%yӤ|qw DaoKpb'BǼ^'([Eg}o >@8kԄ‹9)KK +ٙKdu}-BJEr8. 2Pm ,ho4>ոBGٕz߄߬-r'/ +yy>JF@q} s +[} QXh\wF!7'oB:a +0sh6T$:DW +9}Yʚ=UQwW3(bEw p2o٪L^Ԙ)1ܧ-|81xRceKqۑUp-ڳ1Z&9谏ue7bjӠ6p~JYT!"V2 4Vz,13~WsSb : &qƓoAfW"SY!u)|z cpyR?x!jVh'p󐩱f0)ȅ y h L5_M9"dIsB`AG'2c9R9(ъD9{1 g'"XK\hGE /m+ ۆ#H.ZfÇ4 +~&3A&]!!/R݅\ht5C ~{s:iO-OȑJ"&_V(=S3 QB;킼S_'1:vV4zC\}$$ VVEm)`0( 7+jstRr7"Ӷ.aG>Z4叺Kxȶ[hN*YGR>>Z@4cdN=aF+wE7>pC{A|Qjћ;`R y~^T]\$NLgq*EHxhaqՉ Ϫ>IL" -~M&Z)۟b!]~2،xA>% 5lN_Wy$}4~ +miOz&JgJ%oAJRF +p1[37*.Cz#p/S0JjD27D^02 byd#15,XEZtLP;@գ2;+G 'W)YkZqƩq3HCx/Ί{6.MQ9٧sWx6Ί c%۸ot4$u C@GÈ4JֲfjD+{Ԗ0qH2#.0W,]a>7(k2*rWX'IG$D0)6_7Nw=BMkWEd UFcC7KyW{ffdbj^xH)jrQEj=EDnWb-!Izll*憧Փ pi= utiuQiqv.^/؊o_7plEFKt,*VT)2}O>?beՂřo9?-AlDxOj W誉:Lu͚[)wl2quppڦPa^6ξ͢YjڂZZyjN8߆{9P+OQڪHoェ_ ɜܦիWь7g;jӕp(Wϊm6W=j˧z[lpaG6F35p5_:Gv`1}MSNOͥ&ݪJMQ6z3yV1eN۬^]9 [/+޸$/ u/ʨ\] 7!lMS^rbg~~:J:[@xuD'$7䓯d $>G-n]=r_,hf@yf #v&PZ6eWrՀ JstYܾj]}dX:i߃Dj +\<25"=JBsIݎFpM~cᵿk{W&ԈYo9( G}M{ HOtQ?U_Y˿_Gɝ-_jbH|^ƿXC&o0n*:ȿesj^KF2\*y'{kTst˗s<7qf CuHSw6'0-Kus*X%_V#:gmaMQKT򤪈PnݬU0VwjuYҡ-MY}RΘ $f +!?Iռ QY5\dR(ߕ#Mx $<>fMM0%ʹ_iajMݸ4czkQ%E}ݿVx Ģ+|?}"be1%U]V$cj颔͛l?^'( XtދbzM%g6pF +*"paoOV\3Y>M9mb!)d.an[:aKP^qyz[l=ؐ=f +'i՜T!}HZ>s)>_͚nᷲVڱYw E&uv-Z 05OP{1"i v 4Ϟ*/,+ !8Bd,r^%Lj3cꫭ1C}V3u5K<{\t|V #ͮQh(De%7}KZ_+9gGE4y&ȴnMSm6Q݉=[UkgD5UlԆhJ+阫D)g*+)%آ⺣9Y%SHKGvw)EOގ5s^n1UZ~bN-EFLeqkw-))!"H* l=gOe.}mv{{y >qd(y_/Vȷ`dkV]敚oRl} ވ@ ȥ\yE{n(M ^fb^yq^׎p%Mwb׊,]>bNiPa(M?hF>f9sY=8Sx\95Bx]Ƙ|lJ_!O?AxhƮ{1K6 Gȭ"L~ArWB ԙH7dd3>\ձ_%ZؾZx {\儉q\բD2 G|Ẍ!4_(?F}'•sYܵEwO+aXF'P]e= Ȩ[OZ*`gzA_'Eυ.k.Ie?ICfqX+b^-޻g{ĿMyێ k tBLyjCu5GR +8\On>!m+ܦ6oH _UQ +L㳧.-.)\[-~ƑwLmsh*cvOeUǺ0(FTcv^U +-l4ډu{8nQsB"a<3 bvFoa1řGs;r*l4GS#ZF'Ao3ʡ$q:._BPyUŠU3E`avk%X`R ޼4\vƢ_0иGhR58Ȇ~_| N[p̽z(*Biݼ\$wRBSUzP*ݔ12]l/cV)ÍG4^uï*kMqUtWoB5WN*yCKiArqiO;!1wC:7U}z.ψrɝ93>ư>1[cXa~~`{8@oE{ȝ`= s_^XhPF?e4?Efq\gp~sB^^a_xОـcܰ$-tKrCdB>q`A/΄UݧS{z!C)xĸ"d#,'L <|hRQCk3,8T3UXGN MK _nrx$/.heJ풦JDªNΣ}'-(v\v4,%6 j>X5KT?d*˷3y=jx?T ,=3;ܨ:j*ZlP5}MC*LV2vjw%>f*CodS=DُPʜKA_Ԍ~z6DIۖHQٍ{(ZL2gMUaffc6=[?P'=QvQZV/2ݤzMƌ7KˡA:s,c %,<к2Zub17m[JHn5%A= ,֖䳬lOB{b:Vax`gt2SWDP%MKR{ܒ +vsChNj v$1T0 XSy_Y/yyi ,BK){+Ry[Ox;Tyao 8oy0@n!Y40 Q6v(!]s]fsPN}e-nO= ;m;xˡD4!_N k:IR,dPJQyC/s&q +Z8?`f%!MuՀHOC׭oL43d]/pU~:Yz.ۉ&//u} YZ"͏ oKkK+rAH +TnøR}TQZًId3zhGGuDh熰>'Vg6рv#*yZsMGz>M`;Xlvnssy,[^=ӈPoTZ +,W>XlnuuGk{D}=3@]cQفg0 ^ovau17̒eՎ/ Mcx9ցR1P LUv&Y}DkYP_@EZ\k+NHcr2w :0pE$ 8c d? D39z@bJ(d f@P_|_aQCcHt}HByb7?.|ɼʏ"B7[!ڤ*_m4ڹD %h=hg5c{xN/c?4!3. mwDMSa3q98 N;|= 7uNx> Dd"~&,r.o-\Y|JnrB!!`0K mWbgʗOiלx!Dk5p?k@9:#_?`fϼ_x;uQb +ymoD,r1<o6Qڨ#4Y3༶푼 ڥQ<[m_Cr)7\z?aJ&OYw(k3K3ixT?Ϟ۩*Y["ai],4*=#[Uޠr*RՕohYTOkS |hl;WNrM}d_͒銃dX,CJ&3NlOHSEX {vtω8s͹z% +8Y$ZaAf5R|⇵smVD}t.ZmRr5T`ҋz#O+ƥ +2E|ٜ(2euM0#^{[1Xi2rgڔg_PPYg=pyG*=)2oq'ŷӸaec܍nmZ8 ՞r?x㚔)y,e9|ǰSW]-4nzZu,Z"!-26H(9(+$6IIBL%Cp1[F`l6L98%K~X.13Ze\l? x=#yc-F|Z\WM叢Rǭ_T!n`EMVx׳5\?`5^+Mf/[]P{bد:MإݚDf!t]Y~  VS`y%@N`=6W^< [%fF[9.%ɻ IBD֕=kŵ~1O:AU]+f/D퇦t Og Yhr[-fuݽҝuUrި~"3|RRE)Q}cnUK #Q +M!,Yƻܙ½kj!-*M_RLjMfojaaAAV!-lN3YmekbꎰU~N++4q~(gVjd.Ovy,!mC4W- U!V{CDЎ Y4)aBmHj4EW@k^Sթ*Zs?KQq'XvbDj(<=[Dx5Kf. I&a_V>Εw _%Sľ~q -#;rZl&t~*?U:o-9aռ|EN^JU" + %o!C`eۀ0i0\}gև#Ś?oꖲT'uQ,PB% HcVLK,7RjcP}k,+TAe)[Kl4QE>3e&+ⅶbab*+ty!ֱӟo\r_őM#^[LС a-vðifQۨ$N1sd顦ÉOŒ:$NH6vbd[2Vaz?'u<*}[r-ͷɣ"H[d,V{AuodGDtnX;A> vQR+gQU.cO& fGR:ےka9>kffla/X_*'@ZqGsŷWt*D>/$Z#CS +mT_Jm-/S@]ΉA6ۉ̘B'ZDxRc9z]*l?GlAs穨/yv+2a +^c|=̿i,]h8!T5v¡ޚ3Df7||%޼d sij9~ 07Y,!P2Cvei"$g6(yza⿉."iē&l4 /U3*kj7M۪/))>.ϒ9J:JD,bHi&1JF4MXzF7NMf:QS}=M.Z9**ZX|hx䡋/ 2i¸ +ލD&VOH5ɵ_ikb+"*'ѰexM fOMF">x%ӱVwVyl{S"`z?y56ZcB緂}.nr^/ *Ԟ y风슣9A- U1ɇޑlbԆS?^|%ȩR^zb9! 9n ߚvۊ:4=fYEHݴ&I՞dymW9qd9ű\m 7Lߵ-Mvhgt/ޣS4o8xE+I\.K2I@#w;P:PVM8؝^gNVς5Fl/g 줐AVGPkܧ=AJu,8Coghx&lW<ު#f^N*I5cU&W^qsWz颞3 Ĺ-5:WP<wVBK4uYCg), eC_wI׬GiGEJTHL[uCƛ~D ZM + j(s7>zIAKYՉ+%eW Ǟ# ,0sEϚr۞^K\Rm4)e[=Kėd$K r +])n=VzԦ ˷եM訾S=g&O3;V9EW$'r:<1PNҊ+ +6lmZ7sB\,fQ`bLB(8 _HX]a #mʴ|}+RwUg6Q7~Yjw﹛{gU0;\/11DSSʜbɹٽi՝ksbrDg1 c25$ԒEn/-#/ M`*`Jh瑞݁BĨo:ࠬ_3K*]vYHt8QmFOнhK΁M{*2/u,EkՃC/Tξk4y>[?,>!砹ز*z=Z39;|)uk6קU mчjF|gjײX}/I>M UY0| +/z-ô.xY% +>w_Ltz9-dxֿ|xOA>}y&k*+g(J{GgJO5rZ\P|ђmt9U$G]i^Y:*Jz>oxj#@dtdwE-vF6vu,['yjB ܥz^Eb040A#D:ى柀 +zoN|-fvJ}Vj=mJCO$umnU75-6@q#̘f"+ɘxD؞E_Kz;Կ2;s-(*2󆪲;(s4ԝ,k>s ;}>"tgj[rIz^O5](*6y*5$z{ RT|tsRk㎀~4k{E[Ov穢KcpxL%*mlmLxHN[H]9\&c Χ,E{ve.U+{ZytGY9+dqA0/ ew +-h|y4-JRu:Li4 F=T1'/YCK_ .N;-@|}'R}vIo( *]^39q>kw({o `;62|њAٍxʩ]eMSTr#" $!o)anlB,OǡŕRኪc!T92($񃩃DJ6(`VcE~Ç, Hڛw+Ϫ5EU=P_ʟ@(_e++ W"N2F4,en>,}f5] <@W8FL&$mRW Q+ i 8؍G-eL^^5߾ X)h^)j?[A>RnQ^h{g3 { 0qʓ[gs!AW>R]G央*öD9)4R\yUm'QO 2e\1KEZkwy᮹=/I̱MAgS厙1NN8CDE tdZH\Yق˧{fVWseB.^4W1ze3&(bk"bjsj;Upp_)c@wgIF WUF5p,pW]RQm"ɺ=I7v!(ht!D弛=\L>pXOHs9K~N6SX7g/sCw <å{\܋Eσ.{k6 +})V$ 3=;pq¸Fi&DEWc oTv `!ߵl+pb|DHW +bi, xcg>L'NF ni.kk[.{f P0egge1_ H,aΔgMg2kFրo)v'q~ԡg8Np;ٺ6-=FSkGyŌ#mLH²zod="x ryVٚJkުN_k6j4nWyV_Ŷ;/ -%賡<>agc?vw4>-`Pk3ݴXVaOp;&Hm(j p\!wZ +7[O;֋)~z{e1Ux[ +*NTs㰧U6BРNl7H&#[Xa@Q[H7FZu*nlpv14AX2ywl[&a5 WpǃX9+|e}"ÉK?4pxr8\8/3p!"Z/EAQ'Pi ۅ"$2[ywkVMcJc1V:C7fޅ=o8zW:A|, +>7cot+5-8#ܘDXǛ-a~8vܫ Cn$׌=]hm R!?ʇ>_3G朑7lVB]"U5ȟU ;Df1$nlmy}ZQzQCѵy&) -/;րYBK7?^SؾH7x#_èIuEy)m@ͯ8xIy!X"xosXokܟ/ZGw=Y)ÅV!n2FԁKIv?/[_1\|W뤷b/uPIWU[V%($n3>~DϱƯZP!-UR\ix;]uTQ:p}Jl#?X,1_Tte +?Vϐ=.3h'YƜG*<*ҽvJ0`섍=~8"a#y*m̖ +I`=WdiIϧ@Fx%i,#+˻t.<7WAxNIj%RT$2D]*!A3z/nRc)0DC`$ 槚.;'gHU~ahuUQ83:"Xi&z +_9- Ѕv diT)_TgR}8-W1U+$)UXxY2"=BMx +:bZ bӚX=L,QCT2:zK2z V`HHͅ.Φ*p ]-&:ؼ% _ʳNŜV4Y g;DhLt(Kvi#@Zu~bεʤUQ6j5 [+֒ Kip&MWyl >iv#VR"rv= We= >2ϻݭ_TW+&e UOySi%)PƩؘ"(Zb1f#_.`i~% w5JYZ$eϔWR3K)F+!=vM?n \6|I 'ihtZ/١t +mgJ%a>FC< 8mb1,(FBQ*נ<ɕVp _y~̈́%oȵgmAq/pO]HaN~I Gt +_K|+|C=Ưa>J}Bx\%t8ۉ"Y(c?Ra.c~WhkL_a3+]!#g*,IX۪enᾈNb{ /ÿg5334$_,?lT* Rm)Wn!z-ě ]PD@)|YBu9&Pc&hيu!E_%>n"@ps qD~Q`#k$K\! p Ť jFʳmل|Ůt1 V|?UdlIh_|d.H ?bA(Ey{¶baӅqLjpְk +܅$Klw g܀bQBѸXQWSiC~>&vU~U}6KF9c H;1^X٫ CF\(CUy5ԷjT> $E4+Xřd= +5Q?3.so2S,21K.+gkOKfkvNը {([7hX l_,k8&8yCN*AG];0XfԈA Y6`in$k)sMv|6UwH_VIDgXe_z]H?ݧpdr*mbD諐H! +F 2XaqW62՟%tU{I)HšM dZ`4!\[&pĦYOp+˩]aP%Ř g'1/ѭRWpWuM;ֶ( 2^NoMKmyDI_tHȼ幜$/WJxRdCT[[3|Q 4Z\QF'lx^D.*_YWm)=uBҫ^TGxJ8}>MaA>$U| 1uS󌌣Lհ(taPL)x-tֆH)n/ gV~~dnϲ[5<"MM0ɬN&H4kE@?gf3 q0vM'U8U<+lz]Y?J>?TãD"iJ62ddvoNG*GuDi 6g&vK`dzk5;B-В.g.jYi Hs6ﮦq6hb><@V^_\{nq@İlH[5eo^b%Aޚ]́zԆjtſYC75߱kսID6֍@[AL`H"QtA#us7a9_[7 f_7kU{ m}jE =+IkFJ,]f#}萉֤okFW7$7έM0.jVo? ,E>EeRa8çJ{_>}n/moȗE-zT%yHD ]v nJ싍 Qs)/5f冶ǪAiSEVX҃R\;PR%KL}%: 6?!FˑϒݵmGi7>Ǒv&e}v<{!%}!}!BFbd~KSENN[TԓM)NUGnx_~t(x}W'Hgg?BNſ 襂 RĎeϢS{IBc;*j_ϧs XoD2iUDw TlڶlԹ$YFΥ|MX`X'&q0GWOSn>|HϤo^9tM[&3Wx%v]>k;8 U(^gI[ѡE}aԓS@K/yƆ[آ%[Wx L]]3 cs[n`GT9pOȝ #߂Qh?G}­ #t_/,7;3jb`? IBnFUCf6]q^md=pNF`D / N'wwCDMuuؐ[ulS - \0}#F `Mha#U6ay]Ũym*$HXkXJ?B?*n6yR.& +㾋,VJRuwM㞙L(w]{Rp!*;7\6.X#2HW\O)uL@7M>^5f!Vv!~&G;ȱVe~2vâF.5YѴ0I1ӻwSMN*OqdF͖5}ɃV2"x^_`mCW }l tGm[rG[_S=G.nKKs)sa3+KݸYZ>A;˝^ekVvK(ON1=lbql$=ߔDd9rgrMEJt۵&aZuktBĴ!1@k7 nň!6称MtajP'Mf<&b2W)EV +ˢ[Nٞ"Of~WiL ΥiIM ^Å&@:uJ3+|3ogD*s|+Jlw^]weџJΥ9woo1Z6|c}4[9zn8>ciPCnp4{qǨl\IP&C{Og\Yx?Ni(,LS{Ai4t1jUtY=iP?;sӁzonfS_BXhoM|vċGO)I2_&<̒K b N\mUx]ZX|^ P? ɬLh|JJP9B_.Bį{Դws%)mv'#MS&iگ3U +=r? ]im$]uIxK6G+}Ԋ.Enʹl #1.y jܜĠ"?4Ҏ[@ʲ~ +}_JIG2e +'Cv?^-w +cOazWSJ"\BVZǸ_qAFe:J8elI62’Q>alPn#*SXmBK!wFQ{d0>HJn!'up;6O\f#@^M:.!XK1Op-ifg#TCUh_r@p}]8Z':_q#/ (daY*8ekEIM^1 s@Ed2:2,PKoSR;]:8@88U$fcxWT}ª]ӑm ܆&)ӚUl"\aN(%ױk9UK߇raPO:ˑkH;3HqnCU}$RVhffꙉʨ@D&omH]≭^ gh~-][X!Xx=j8'B:4K U־J>'"]fEG̒vn}G8'Ջm\W{vxZ|{Ert/^t.}kdP۞L'{SA>ch1k6&ZߗFX- KSRWR)W>.?V>כרX}= JeQ@ݿ|:1 aC##> 2'rd5L^|(0ݐ@ܠSoDJC[7&멸Ll$`f j9Տ+g +U6IY*_$4] &@W鄅X`]]n>ZPGWTWE/ +*ぎgr5- O >~:H$!k%$R7F"|$GhT/$o+ax\Z<-=G΍=,mE!d0cO$`'P{[ƈCS9Dc%U?ANIc ȿCFmXx}y64 YbRVNP)NWQ6ȮeI˥bG~t+>ťgT!l, y!zYcbιZ^}&R[K^SbqR czȧ. h #cpkK\nR\F^fi9[v(-Sd6;&UGv}w)ZuTH\*8eQTGŦxyYZs@^lMI5-ނK NctmwB٥񗝵y%wzTbm^R%~j=JE#A=އ|emU8o=(6+7 Y@)puJz4M `f[X˒8Qܟz/:>XM#o}2YY[ꖙ9Jj,L'%_ȳWE=3dwAG'kdUK,nQ3jjL‚~,E]GUDH/[S,YANId$j^¦*ȋ`5mF{h}[_D8IH%}rV^v,B'*_]EMyx=Ŕ[W5a"4XMRj)qUQ~ 5{=3ȣID+c1_4Y|mu)(?I '<ԍ7`Gb+^4zV?.kf?92Hb~Ɠ6?^СꧢnE 0a%NJݷusJۼsܚQ9њX0h m֒ {I=Vt*`ڡA6QR`yX`u{r{J Є&*H9d uHiHUn\*MoX࿐,:Թ Rs_8~y '8폹cPg;enZl4 ُ&XQhp]YG͢67C6gm5'?11Zdou>ۢxw5$ttLmۏҬ:4n{:ҒԜPڼ\Yk2$ wihB*s|`rEs0h+¶QpF*/ Wo}IFX 1&~ja}JQvW^,ݥiGJo/?M XܩưLpfRJ6ͧs#PWϥ]N01{.4=ᨧ,L\!6ӚNVTz6pEz(y%-aB{w ^9%Xi<*ukZ$.5I5pm?Zp/?͙V6~q5]lG@A}-P#s[|3j&< Ne!ӼD=811=o 4 av`番Xitleя.NPekV;S?7t#A?]m~Mc/f'T^2kPWvQ4u{uպJ<}9Je,-uKm*??#|Qvn\qatQW+Ss1biNlZl8qy'M!]b)-/x[6Ƙ.Sj$v 35c3tfSW]L;V5t>h>6zve]ETyz~niHWX&٦rzCz9JPk?ڰ00NK?:3}>i9~ ޾qlo>E)8Pg_Ze[eq7SQ%Z0ގkC OoW Lk~vԷ_/n hޘ2v( cr>u4.Ұ~Qk%YYy̺x@ճxcj1?=zoP.SMua?nBR]r'Z|~Ő5S]񾹚5X@&go 朣$5~^)ed3agaa 7fMz~-ϼQH&1җ +1԰+xǽ9b53"iWy`!e4kZ_B!r/Z#GC{<ރ_)V2!J W(ou_=d jlh"wR6&&_p/Ɵ e{dн5k] 麟L,j9hnj_y,3r1#DTKxHW " WWUuf+C >MƙCOҫ5IwاqKgst~CDn:RxåvaC::ne'ؾЋ r {4B;}Yycfں2ц$ucak`5c&ݡ͜r/.8ya$2rʀ[@Uim_Wt~MRrʁ'fXo_#E7 zMw.@ +U[`ze>JP2z*0Xc~UsP8:|đ[,ZW?yQLY91x_oŽ]|C+hŬ2] ^s>R +撯O@_CX?\=Օ> PFUnA 6* .*vqaoӜ :$a4s_@ +Xܜ B?NE/Q8/%$Hx{WASPه 4sss&UNgdG &ZX`c6TRќ˸'̈́|\$xoba (Gi2TN_' R0gIgP,_1Ly8U5x + w +d +Y׽\HIh4YB=cIcOIg(WlᬑEJW!zpxH}ץm<1okz@Q Vѫ )7/uJ>*C\8w4ϒex4nD9NtϪs-3~u-( %J}clnb)v{ +$һGES)p}pnv×X{PETZHG?nQ2Y<<=۴0s^ IU=E;u֯Ҧ5#ѷ+?S+71~,-APTEWa+ꦂK +hup8n.o[:MZ|'4)6*g!qt7X+Y#-J]_,:^Sk&ڴԒ?bEԘk ޸KnT$f.?̤‚3 lф?ٿdb/`.oW2`"΁_EPq'8Ŋےy5Y|Kss*ۺB"P]nj?`wY@zV ]]+1Nrϑ/X yZ/ KEaZ=0^d7Y48D’D.FN`~}M cF/E/n p|Ud(cRBrB #SͯmO,Q'dgQ a&cO7ӴI1_` \Sf甮{Bs.; +/*E1I _IܘD]7p;mfݹH65#vkY0r|"pS'knFY Tz!$V+I0ǰ4P-]:Pa#U-TSfc*CCQe8*[(Xjw'}#ʜ8SH/S+4R[Z(F/V0PvCCsX*59?tD,1HwR$?l} ~!j824ݕ_<{X<-,d 7r݁\WT}/XЯ̥]$GKe"$yvIN$I-,.+7FTJB}ݵFi#o9"|XO։Q V,^YY&߁2UH Bŋ]/6$Aq(ޅA7h @H_އ.f[J,ō=cOYIv"P8hV{, śA>T+;RWb;T(FPWL| 6B<3d_"§nbMe_ݎܗ>oi.Ll=d8ewL#Hx c>ooAQGQ8z9+n-?3T +y X $W^pY>W_葈=(Q Kp ZG!3ɇ A$f IFpS@4&$ɯ驒dhII/)a,{)IülhkD$0~_C5J`ͤlIj{hI&FW,U2K)Z2M}'޹C76&L$M;x$Qފy|hqZ5Ԯ;2+߄ |A2G>KN9 ɒ5Ӊ {7B*졸yc S`$S=䮝 꽟C '\z {i}h:-gsI=w)׋o_6[ƨW5&b.-YeB/Jyھ +MƩU~Iu)Wi=(Έ']zyTq&r.b/5J_G.tsSV1WEH/&7BDVpWBdS~7+1nY˷(9dI)s2+Gy^D=N>0ъ>Azhy@ifgJddpKrUU7NRl4j'& +̇.UfYK@uj2Y<(B*jyFa751K!4Wrz4 +V"~wHA-GjЋHCt& aGn"1s7Gʜ!;z8' +ץctԡfB/^HHL9hO#`8p5a/= ϱrK( hW'KUk&"=Sq3sS~Zɛ>Y6JPArDCK1 S~%Jfb$:1_V77+q2|%ceF]wk韢-D HTP8;p@?S_^r[gyU:_8,Qi?E8ůB,o`rI__,3EKZ4>{ͪ!@֤Cue]~P?:%۬04Onoa4+?W++ +fr|?LtHU# ւj_XMnS9͏$@,F;z/ѕV:E_UFUtR7s&+ɧvbJK'vЯMam( {ku ¢M?kUKJ4UrZB@+$*$Ze~8Ez}Hr3߄2Vzڴf[ܮ6dSR{l m"\UTvsCHwE0+{UqՠrvKLZt"#5vI?5?+}@|R$W::&&4i؝JbB/ &'Rw4T;Tŋ2eR=jp#JFǂinrf,S*\TVY0aA!No6**43hM 5qג 얨I{ܚfF~OR#õDN=*-7/8@ Q]KB,4gp5:艇to[#Wkv +UzD>&i:(rC"h1 +MŠ;& ђ cb&?2_)7s}|; {W > 9dYuurhqY6ΰO$%'i#y4Uq}ҩu{a, +Uަ|@uS83I߫X 4nXBmfTY Bn"hWc8Z_hKӍu +Y@z^O(W3WJ!xXLL  *+K4s0J֨< .}lPJ:芨WܑKeq>҉["qLJDako$&rĺ)z^_ugTK4 "*8+)x&w>n_HcFDVCƒWf'V6⛔{oށy2'+Sdbu wHIOW|2uYtZ,s\j `Mh%Ƌd>ƙ~{o3%h!K*h5xAwouݍǻSӨ1.-,zgfs# 8ml>_U#39cҼWDv\Jf<EL.%i -X|Fp ?-LІ%ܮT6cv&|5j_UTH\ƏPޒ <]cd'ƛ˿Q.ֶ972"pYw%jDk~.*L˲r$kx YWS|mWjc[ +u (_hǼ5antmt+括PkeƼk +k^-W_9CԻbiM6<& +Ǹha?lUj*󤫱Fr.qɣnjYD&v;-gB~"ZpLӌ([qEy1`{TξdNB Kv5VoaQNlpDS>[!r._Iz vEwu +-h&0|O/h]*M΂x_nP98;#d'%uD;b^ֹ{Zh0GHY)yZ+l0 2A.Z FO27lsG17Z";LGZ6}&ҾhrFщ#壞 uhAɁB~׏pJ|5?vGC6$u <^]vs R)VyE>\as(9钞yyN٦qeB:5Dw9`uv;mg˱.L3Ojz"Q*%O) +à<ٻC![j $.!w,ݰR|bSCi_=ЎDm!4ts?`S4/QeNZ6h%0$l.^eFTv%\lZ`Q1Wz:Nzο~20:}/l-śj mʨxP__mW[h[W 6RҒS3E ~V-gUg=oy{A^$j0-Ck /ֳj/qf7Fpkh6&3{k^ Un~qߢV~Mc(4nNwwwwתu׮! AH 4H5^Bq-˸\8*YL0*R')Ns᫃uQKh;|K/"[ZWV]k2f,|ǿ\sz%͇MkU5.蔦@a u2ir6&B2Ej/MB?:Inkꯪ4P%dDb ȢlR6.ح)Μޠz %96b3Kbઋe{W9w7t׊;/4i/k>gYGd(+f736g2+y;Ly߽xޥ }+#{kAwNlٝԒ)A[:2Yz&~ YIck%?@ʩկ *yዃy3D[nP7:Jh; GF\n?]@h]CK[D=o7ꂪk؃W-9ġ(J]i^};~qG]ƈQliVzuNoz˹xy ᯣAy% f|/+:þAJ(,@?8:+ʞ^AJ7|0iws7/4y3J3i"itd'Y#x +l]fY8'gWM`bRGɊ2$s+|u2ૣV,i/RIHm `Jlyh[mަ+x8f_\QRXJRq=ebN%t1)HK"ET(>ҥNqܮ(? @J#v׈VV!~؍sH}OE|Â}%h B>.Y0eu7zgOȡBnvO^)Ћ9Q*ހjl17qҷNp,Jwe=>"69&&;}]^R=pL]uAxq|& zd\-(eH1xKUB^Al]Y,1x;}ϯŎL7Ӻeȋ\vYP]W'Y2J(# ވb!ĀGYE (^|7˕3)s_"@+'$]-3@0pA8 'ӿL+1XB >Ν*͠vɲk/D@^"=_͑ʇ hS8/8|gְnr[;~$4=?_ Q6gCš$o,i> hcgh||7|>V ZVry{yXaR')G4Ro-jvSg-6Mԓ"9y|zl~Wqˎ šm-ϿR+p%x m5>*[(-&n8 Κ}hٽۭnLfj0e{@%cg~[+7.O,SBi{ %Tj=Ddreb `&j?ɺClꬎ#]/ :#ukn3cwb{E Ryڐ8Y)I; ݐGvKhnH"g4iW8$p+r@klEhB IRISΒu;CGsԡ +5g#wOؼ[IRJM%|xWVV*^\$I1{䷵)@pxg(ERtȎJ% eٹ]rǀ*mOXۯ+oopQ̑ⓊEuоi\ZYI.)ď@,A= :™&:;}{rNxi!] tG;Jψ,(@2[.E\0:"W:=6m֠\oY:>ZAZ'0G4n$[=g޳O@8`c?zڐ]gĎl;×>ޖwZ+P3ފ\ N'uJ귞~w#93t朁us3zYyfSN\k;tno&u# 8-mA 2RxUpuQ; ~o 0}(V<|DW7GH^u = .5!&>zߺ<%#N`)$㑙.+tbjhz2”U~]0__@;$lcv >ةVJWWo{A(U!7%5@dgi{n)^[ŀ{(,vb{OIJ&l8Na`8|S\*8L0ndQ~2F\h|ACOy!P@5;k3 + +~yt ?)TaByY|I?RrIEʆ5w3+FoI:BC͞YMDS:Wl ԤKwQ3ej40Vޯ~بZkQP wJbǰM|ac'ORs-#ٺtdWKYo}n\M9[qΣ&(iLϻU b61'wvRrcSv`6ۛ AP:<"xhh )ѹ$w[{4Eb`.bjhZ$K;" qH: F#HXnڋЀC^ZNH.T7>э2.G@7]IQӈ p2z=j> + >K|L@_oS&6{8rbGh*( +?Q^k+h88((!'ABhK@~S$+D2nTFFφ&!a*k-G6N~PO[O:/E$1wf[j|Rxr,RR^i wo!x}0+oa״jy fjDѠM8x wdKpvq=ʽ~UYT-p[渚M{r ˲%z-NV"(SUYvMxl9"A=+;5|^P|ec%Ĵ.!xe Î+P]ߟL8r"2;sRZj@gZYyZ>_>%a.`1DŽTx~jjO{qC֐\MЏ[D=}xYHFBt{j8|$W|3HX_7ivCf;)Z:UΘPKdY2 +\8=924E^A<]aTܗLUO9ͧU.U\Z#%q cJY RF9u, `!z mosutдlc|R}2|.[ }=/ ]M₃#kt\㢄JInm:[# nGyuY +k]6A /1ESo`1$Cbu &1YeV/Rע<߭+V)ɭUkHyaM1.]@Bs>%渋VeA~jsX}wLI19i#4~}37 +s*5&3M/]g= ZV4M0Rz -z[$]{k1U)lx[˚E1쑦~јפ꿰oם˶vJڦF~Pg~6^cHy>(̏ "^q5OVC/gdKz,9(E/@v6ӰAhs?'ߎUm\ը³FW_3M:+AD!{6Amj>FV |j?K@‹#]emA@xh\OZac0hr 'u+U -3'&hE$C`wPW4*.Bt#zIBتRVGf< Hđ;[kX ++]9 #S[k$MW1 ~BN\/h#\/2qvbq!b'xݩ:c!ak?ËZPے#Sb"`.{b8ЋU":Ck8WI<q$=mp/gT}QUW _ٱ) m8 XSh^^H|A5V ƾkO)%h=!2RncҴFs~_S?eVy2E[Ϣ&Z.BiFUܶ1>|&v"ta`ߺrzrbiC6Pftuӂk;u%,,ge?)w  u'~k%(:'Z;9զkܫw,G$M.|Iԡ9ڥCE>E Ii]mjm+YuR,N,0(kR&ˮlk~}@Q ijmY/_XjpNeŻnpm\kl ۯ_ G +`|d=qS2xV^CXPTk`g=D&%˵lM:bV}@GF~?#Z|* +# VF-r";MG&GinOc|[5U2EݿGFblh(0*&i 5%Y*MD/QuSu?\5o$бF~a +.b}iZ=f&Z}^OՁc?[U!Hwpv*fyiRհinv &6VZJm!-Dd|iLMSi`\9I?isZG3TvG?knPVlnw_ pcpie[Q˫ i)k`I.U3?u>"}"gx7c\KO]4 U?g>/W۞3]lwcoGtˀS)K-4Z\G+ٯ^qs|Tj 8m'DR4h-u/]35+U[Lug巅%9E߻?9;O#ci5o27M6L~y[W߾|]K8+=dE0rMbQ| +6F&]WjB:p .y늷@W·^>4p@O A޻5Ha0 &NzZ';ply6)+lv5a;AlgH2lZ;1V)+; +9갬,z՛+:*b8 +#~Ҽ#OGˡ7t-qX8m/ 0ԽH~h|efiSt zKMX6XK9pID#ڏ/-id9SpmySVƤIcL3Qpg~ݥJsQ n3$́Ķ6qh)1x{r҆tR{%5]xeđtࣽ1,M +8UD[+}g >{Q`g[81_E)+[d/SGY#9B^{.[Km+=|L'.N{`>(2x bʮKXu$ +nvOw"n!6GLi;Eh&PC-aY ?K=G3x5?gi'&whu]/F&_~sv/B3H 4$"4g朠 + +:.7d%wl ͠QO7ɉZ%3 =ej8C1erC kD_;_4f>ahZ0[uWP[&MĿ! KH?z[I;&׆;tIZ!.):IvHW?fKme:fП8G TRR6lX]wR )i<Є(G+0T;ӿyj9peFoI=A8씾{ˑڱ/ػ!)x< y2HFUqiy#7Չ8Wm*?ZIv'"^#5'tհ;Qޢ\WL51HbcEXct*|^Bjm"̙ʨEjpcoe~_~Mq=[*-#y½G\[qT;C\۝լtJ_KmōRSV-BC@0nr(~#&O8nJ[%+m>wHij骨PP 'M8Ǣ~pԹx'oH"+_VZ~R1:rIZG,oxy +?j@9FJex4KI&=~efC +fԍGTQ-:_&'qv,_x'D쎀̥ˋY?Y;i2򖷗ҺeTU|H-yۥDO<}ǥU;Z[ Ut/Yg3pc dyL6CpXx6>QtU|v(y&=+/_j \SmK(\e+;E{%qWLl[񂲫p92/}w[[ [0&QG8ˈjBAY*k%ήWO7n`.2gsEtV/O*N%,p;*3=#ʧGƤn^M`_yj\j lTɺoμȭELǞ,1T12XJ"Զ#'5k 5 +1/cXg$ =P&[k= svCScz#sj<-(0)_&Y>&һԇvM>moNgQMÒl/؅ϚWՓ=wMd<i\{Y'G^P1g]8b wW_ dY~n)?l\#!tDEufƄ3p:$F J9%iX0^miA]0ڿv!4U&rbEi%,!'zH^Lˤ bEѫ2^p,U#lUb_jd"^a#~;H뢫$eL@{XnףأzO;(>3nJWHOh9e~GPДM4B=S|.u% vN@oJ&/٨IqxIcbP6J*)`-$y|#6+q`O05 z$αY uRl\c9{l?%S^:`Lf`;y-=SEW\O*A )SOKfE4Y 7JrY x s +E*ہ _jKS~UGODoޜnj"oaz1,+Jڄrҕ$)230uQ,ݮR(q2gb~MF[^RC֗}S$L#, $ ׿*nA^,]8@ +F*URDA]V<(e58;u|=T"Dg] QUa%<]*D>^>n#jά؀N4S4[9wFveҘi3[`/h׬㼵l*m6=ȼ-g&\>a~פ-TM-I3sѽp'u1GYSĩ*zn?K5~ ;&y~J}5dOTဂ`%3<jKaWPki`uE y>䈀G'ZE+~ʵuVT$2JZ#(uzĠ腖6^p!A^$q^> FN)xJ eW[PG0U[nS]SZV!},PtYFF /%V$]s>g? *د",Nccْ!m7YOr508`s zdJ:MƦ]2oJ;t8(R,>]yPblSv:CkUB/PxCrXXMR| ӴrMl9$C~O78 mʭgca!1QC¬-Q!@)d?v q|z< AnVT aj\X%2*[CLWH!ۍ-?gtw.ƴ}¦x_ \Z SP]>WV7!/Z|V;>,^fz<4g]:RP=APR@H &(rQnʁPp]3lL(&6!*W+dnnPm [e+UBqjG.Ii<*_ M6|ifoJ,U]" Vd UjG+a66>Q6J{GA˭ghi3 jnA!Bc#Df*bi4Y۰\zônQpU>݀fЧ$|t##*&jVTlQy5e@n W^tMmvI;tDa"iOy÷"{\US]'Fe*1?rs-ÿ^[6:iZzFUGk*iΫ[Y%JRr0!x'`UHdn#6bV7˻Jۣ6ӏN>ނ% xAߐXmŋ$fS7K_2u=#_J "sQI˫)k1$}p{4ZOd15! "_4|xD,n$Gf'JW`\ܿct`{l28ѺE/հ [A@q|pko6]:v3&~}9 I9r@Si1 Q7fby-6BnJnX>ZAf䣲99V!p+4 0 /B+ks\ )r(36 +aBB p +HFlWG YiD]w"*28> _f;inlrhl@Ou{b@_;%{PgWgTeKUcl(!tl EEQ }7:G6XlohPE 8}mv'?Xa(I eCjS{P!5xZJDv {JܲMЌfT&}A_1kG%'AQ;JHkVsWo;f1[t;ꛨ*:+ؤͺ@jO!umk}PWQ|3x;9 uB$xLW@uLbmoEv˧XM#{uf2,ܲ:=4}~sILș)τ>C.%W+^`ߠQCOK%,Zt0'a+2@CZ!I&eGe@ fZm^@n wK9/̽ ij9J(9DpB3y8z8$UDbȥjHծs*A Y|E *|m: vIbk#n4wf^ ԈM_i~ ,Zko竸H~jr+":9?HF~Ff75v-a(ѱi\V? !'FO]H"ǽv( +z|h>քœ0D~a*^E8koh S͚͘:!6ڡb( Mf.|x"|iv!qhjUt"P7 _9/;lBa5lN|tW$MR¡JMVt3gW]fh۫_KW~?xcTs %+qg֘hwq!Mn3TwFr KmQȕ!r Z[|&?nIXa4G=2؄l73ij-(lT-rS̜/񧲴GoȽ>JgY/&|6qE-2 +CTy5$ZMK0eqUm_9[myۚ>ќ"%3n͍0t<)ſZsA>SN;?%l;AS~1pM|G蜷V1xGr3Ahh)O Ֆ?U}NqسGUbKW=tmobw4 !?Ɗ.VJxo4$^mվ9~Sնu%z}"#Si\#~glTEdoW Y[#Z>Lq{ypQ݁lWz@FY{Iv͕/H8-w!L[ &pk]O蠓Pe o}H!{gNѩ:㗶]UvE@>!o[Kax.FzV +ZZYU둾9RfT5״ }K but8!vxX]CaD!e}Rrf|y 9/q-,q-pO`bW"k%#ẽr̲Ss$~鞦 :d u_$<^ + +jʨu[K\\`OI +~&{ PqtיrvY,e@sp<Ǿ[VUt&]d$]{x$Hp 3W53_sOeUm11T+mĜi h{ĦѼ6762ٹu#텩\Z(E*f4quiG$CQe2DpؿXW| ,w@sߌ>)_NZZ^RTȇxƈW$/$ +Ny [5=hE/˯5$cq:D缟UlzaB!ͩB$M );.#Ti5I /ƿ/ ++-F4մ.doWSN^*D|y~RhMV[zīgLW XR-gJ @}eeuL蓒]G,NG%(0rjzqQE+K LgԪ!BEHt_#N6:+p +j=jWrWk(ɾ>C55ּ:TL^}Nc#"ʯBy@]Ҿ}XeU41Z^DVNa[m)5 ]|d>Akr.:c:\,6wpK&VxV87yQUS'FGL1#] +g>S 7'9sWȏ:8'JӴ?I?pu_Pc qQJa c㽴-˚ً?7-Ћ7hXչfMy*bw\PB:+&i!frOTR'^ʸ!-`J'q}î*i>6T8>G-V[z#ӻt1X1HCkh{\8WH 8[b*XFM\,A cY ɣX,WPf^y1oΜ"IbT6L/+'Fr& +ftH]Fg0l17EY?Y,Iy/" ]/fQQpZA?$D [?hS ս}[IbufgGU< +.ܮY3D:ԠȠ^jB~j3\.nR +[^4fUU(YY6s˲6/>nV8CgIY\20%"9GCKSuj[aH|U=(^6h]ᎊ)xt# +൴?|;.O.e&jE1ciO<,\&WiS+spBr1%3Gme^iF ;E jDIMUYl|b\)b֪!z,w! xqEsrlaO|@Yf&Tʌ?`b~ +R#|GH4M CXy҇gᬪ R1D>,Eb +6z5Q5 taW]\n l^Ȏr}Nd(ٜ*O1r W dkz'IՐL )n40I9'TQ2RrZ>],\;48{}[mœɫeSOK%r`cK1e\2˫%keٶY2j~d#xüHp +r")cL)ONtb 9MQԎOJͪ_&#<^j||$(qH0]MCrtU$׉h)Rnfaw^EfxJf ?"2SWWlgp##T?qz.|p &$##!2H"+UZL.Y^yjhրV.HPӥiH|u<^QLs&AlL03d\&U3A&_^R|_ڥ +O? Fժ'!% ;g[D,,˫eYe;&3JۦWۀJ<"VCluxh%V l4i'i..*uy+?#EDIDEL @E{%Ű 9f3L Rx!*'tSe7v*&jkCZ՚ ;+:muJo>yGE2D6:H:ܛgMijqWx<<uʙ\z0Yg~YI?lT+^%Ejx!-AmŽGVV +U +ԕ$fOр_ڼ%Erf)Jɪˡu>^rmҡAUfZM-W%*ӊjWWkcNh桐,侈&EmPЬ|9ӑ[ʥ'QTVK5YJi6j Y}.I:\"Iz+>9 T{-/Ɵqnda/w=SȌM /HL>[F)*/Y-!6Ö+{h*m$*`c"Q+l$%i"MavCÞ @qn>[ L?<V x7LTZ&!;UU`Se9(}sƶCXY,^. _į0 j ߂! HGn&P˱ݳNtA3=>h-}NGs苌ǶGC +\W oC`Fb z7ajfh4Gu'!! ߯NV_DPuKӔz ZK<(_~{?r=`ĐϦ4[oʥS3˩dj%j:Z}we}O=owZ\YkS #Tf,݂*f]/H᷆:xkVMv5ܠUCM^|'=EN<4Jz݌}-*o&kZ[&Gc>IĠ |_EXT~$mr?S̵;,LGhkdV&'93#X[T84Xg/}~@_t*ҭVҮe9pI=!N$]+z9F7p#ӫ'u* b`J.M}A]LnRLtZI`l^yk)o PZ.яPmk Nk4 fڇYܠ:Sr~:6t+n'h1=t`G N}9^{=?ij>)뵜Fc|ҙؘOVAc(/dgm +5]ho1Rbל>gv&dkB| vHI=4Bb25a5DbZBM܉b2لL.K"֒,ՄazLpc +MFcCm՜ IhN2Na DßxYL(4;1 \J~RҦPG `cF"/Vw}o6EoKf;⟵?~Kߠ1I_\7vĂ'Ž)3&P953Ū˾an)h5vt$oAN)3{8ƶ ٫j ~[wOt>h-o?~lmp>C*h7.s}1mታ) VoD3_H6#ҫj? g zhٌ谄ws|~?;(m]8ӵnbc$iݬ_ 2OEMk-П cK[}ea= W$}o4N{.-@xPa}V ̛h ]S}JHt3, [X6p{C{n36x>p޵tzڥLFlfj8Nhk ^}Ԓ`gZrOߎw uQM„;4nUiaz,pQJ8CuBmh<ӦNcBZP uSgomB*֛XH`}bÞ:bvFMz$\ -jZHSzbsTc0,и)WߧJ٦ָ&kRg'Sg{6ȇ--diY Wvoiv** ߧ:n +-}i;Dm9)<@|0M9ŒņGes^ +Rem4 b)gzչǠڟ" < V$2LfB_&o\$.GZ:jVӱIy|Oz01 b,p#7l(8i4}8~9s ~Ws6nDta0Ah!+ٟߥ67~tҰ5qG\UO"oXj÷YPk?d) Lz\"X Ļyy+sT|d f[YHaV[UWnVqdw06_,^ޓƻǟ#J1- +_5jǂʩȵYZ^Qˎ-KaeV|<l~.0Wx eLX9\zTElS4 ˜\q {B9p +4T:l"ى u`fB,kvm$u)Z2V&1JG eQՂi`I#[U%C%'Д킴ܺoyVK}63_6J!hy|H$h.+TT&>`vAr.-cnԦEqxzi\9cR큐24X>h}r^MΈ]I7_v2(057]oWAm8"gNg[{)&jk5Lg5>7Wd/.pJWl̰:-I` exgUd#y({_XiYbAYË=clVoV0H̝)qp{'<>+/L( Op*bt)#dY2{SiCxdբei?o_ +2,D0X,Jήһ+dHH)UͬS +3giB5at8<'VI{ +Tsa:u5zB'zZ%0gy| E=h#`!,)ț`+>C+腨sL?(N:PrWcV+2|4!9QXTo}MSČ䣨,[rU`(OD +=Ek(nY'h_UNN\etƦbÖܕ:$Ss`.6߳Zd18S',&Sjv3iJfeڦ)e5ͩKq^U s#<;tsMߵVʫwbr@'#͛94glϲe^Q皃STv8ԧs[piN`\>21?' xR^ZCbrUB-Ug&K;cDq*<팬񱻮˕h }@.$OF] Ci#;7ܰTIңK_PMS6f03`/?KMS)OݱW)ʩRK7|"Y}{cSNJy+2ڈ5M` g5Y1b+cNk[("[ʀM*6o>]_v`ĝ '7-QA#%Y9ۥ*eI/ K?w)q MJS|#f.5r#Ҭrkm} +X$j˿[XP=IRSPsC)AѯǁsKwٯڪh(^oPTVv%[sܘSY.~#-5 ,G3\(@ֶ>ySKh/%?ؗ[|BGyj,.;|$Gw׈Ǫܒt7cL9Oxoe6"9rՈ\,X E]Y"qZ\g t*65Ģ4#sI[f_Z̨`Fg'0vnt>g~N0_;U\ɵPFkoIhQ_8Hẖ153hJn wK} #]%v%ʋJmjf1Su.[8E̬/2n\}ReF[[l72?)-o4uo8KdgrE +7[37#QUQc:K1|g!Nש"+N@]*.*NRe-̻ &c7ݞw>')tVqBMӧ;˟?f 휠U^8]90!?B&*/ɢ=g{0p7nN$ ǚZ7JͿ,"I/"N"} BVϣ@rnpcn0G(&Dr<}B#ӓ3UVrw72poEOjv5Yȼə6=m⽄kA*xT@R<~aUsoߨ؁/Vc&%ui-pbgc5|3I_pMÿ,T|s<]5C.VS{r2ִlk,4 53N8"R#fɟιK>ԹEsmrLeU0ޡ. ܱF}BlxTzmBNͰ}!% M;QRcii9E wT\Fuh=*%}DLR6K?$o {ngun2q"mTB|XrV+ԼpS.մ9v4AQsK ,CJXhK8kIQAV;h Y>[p<jZ5;#VsI?>5WKV@/#ϕ(&7v +Z3Rn(Lo2:[|RXR/7mg5NOo*Q(u'/tI6y+7/; +_lHVi㬑f}x9jYp%޹Jc^R6e2RT` {Of(>( +~ Fݑ2w~]&YP`b[:mƧmzhE1q29IiO 3jH!{z.ye|ۃ\Rey=,|ʋIxx| 4;F}x#}MN*G+di4{c pN~-Ē$yӱMlmc[T9 +7UT`B襉~ fi`hVohW-LjMG\4TX|"4CL` 1q02rVIܖ/=^ך +Y!/l֙X7>TǧכAf-uUiap@͊M^z+݈|.R{F(i̕Y 6 U2{f0MPK^ٷܦY+0y=k& +:2C%v}Vժfڳ E=ie]Zn7?vWq[a]>J?ZQsNLVBjA[ {џݖ9tjNM4 Y=Մ) +0[ŵE^uNnVsj;;(7U$R/&=gJkwӵ^w5;Uj Q~( iR1QD\-楹I##a]Aք[?G⿉iPY&wm^x+57~25BCDaF0h: 2I Ž>:/m4O?VcmacES>h߿w,5tA!C 1r1cǍIL6}̀аȨظĤԴ̬ܼ¢ҲrZE%QU]d9\_ %R\Tj huzu9ms_p%K-_ѱr5k׭߰q-[;mݳs={?pP#G?w3gϝp+W]q;w'O=7o߽/_}? T e/_2?C~0`Qjm:|wZnŭ {{w`/uj?lo\n1ƚ'=U>xgW= ||lp}V_;~u0l``4|^9u}{V~uA{vw/nӽ$?CC~l?wx~bcݷNU?>wѽ]ȣC=]ۉw6v$?߷k,n_ٲWG)~4ȩGJS=}x`'}f;gwb#WCw)iOI˛ޒONv\}TcGy{ɯ޿߳ }zzo;gfV"pʼn9V])ޣszWnهݺ|zxIGBugQ$ys$O\nkN^{c³{+/9]߶_}{^e݊w)I35|9S9͛sN\wb}k9.>^Օ ;n/'۶Wv]!?{ +>)\x~Vʺ}Jzva铜<&=BGCkmD7[o|ߕ`mwJȏ jLO6&ْlڦyӋ;q^E"@"@.TPAA1j)6z31x/;W3]P]f6ףl?s/yQT5N/4).AUq: Yiv݉ v}QbrsJ7+UW&oڴJHIm*oYt[VuZ-bZ-["[Ú;Bl;*e>ۭR /;2zY}}Ͷ,Nĝ6)3bf KczM*"MCHq@Y_EN'۵rWo^\Us]]Ӊ͟MOɋe8!}~Ao?L퇋K)"R0a =ƸrHZ%e;2v:W4{45tUU>ee s/d<71"xNQF#"a*y|It;V׵aZ*Eu~C^)垳YREA+~ƒ[?-1tݫ=.#"Sƍ%.VLѻ+ʮvKtN N zٞN6aODN;kͰ~)mra߲ӡNt1f\:_6[;W''ŪW@[XlB~Au3<9Y?bȮv: ZZM.]Yq!xkG^6qRm-v-ۑq؆i͜#Zr94g5;H螸zti D QbM + &59i6VH붭t'ڴ6۴G4v60/QG*KՕթ)I6+z9QA3׼<ۼa^nфkl li hooqz鞖H*e;377Е;JA+ZY̜ Ci΍4*&{L*վ]N:NkW';(\zCnүړu,Q dd-%MkFCFC[6_7a]#aľa|0@Wd@KLAKo@Wn` )61>u)YyLC;BB3z#Zcuqԡ3hW>_ TPtl Cu.q]e%tƱȾ!Bƒvbް8.o">o% <70 Cd`:>;8ZvlgqK7<˫|/ŷFtc9c9% 9 t8ax{aߑ<:bw(iwr@rx83t&C!Q`\ՠ&0cS!uQ-b8@Mc6 8 +:] +[)b2Q?\1͞,:s , 2pacShD-XL[G Y3jJj-nmi n}\MXHMhXuHjrvXoWa~(6t]0qA "b:f3P'admumMjt!݆5Q>.}i LDzNxр$4򆭸>; UІjhFu!Gp#;ɿ D7G94䞖j=ZT4\VohEM +En|uK` ~ool h j hş9 <' J5ّqIeyeE02}¤2$ KzM+]f5bvFvFlϙE7=(Tf͉!݋uɣt)QXaĐ!7`$3.AVzWa1PU̙[8*Spq777mc6mk Ǖ2>kk}Tup/G2i@:H'ݖn6 ++Jf*e$ĒFɒVNђ~ђ[h╎ިbp#nkEH>|p+o#dHoP.B|K)pK%J0Ԁ"ojG5u K> k + Or-rbw($Wj'gW2񉨛򊫟"5Lye6NyS|X c~E AnwqC6dȀ Y0kĀ|'v;9id$bo\hpx6qқ44S4i +,j5- rn=3Ȑ HW@ +xJz\Hu]#c +|sQA0_t6u'u— ii ԟ\Ȑ2!C>0A QL4\ c9ݛ?P>R7DlMii/lZ춺V{ <7j(YBSg=bل1)4 m%Ǔ/NF6'w vvvEvG2;K![Sa {̱oɛ4bO, W5ԃl&=FOy᝱ C.`3"KAm"tCs: XcyIa͑Д갼>Q$O@qi}3 @.d`B")ߚ+K8e13D (o'4GtF ")EĂVLS@.dȿsC`"Aɳ3CYm]º)} 3!d2}sHaXb?HRs ؆h̓3R娘*a-)d;Yq9丼g= C chrM\JM}[7QˍαY}U.2Ԟڟ563;7|@dB*dijnDh[zTmրϷcF;PR߻VߖO$%E&rG2045A ~Xlh/2rةB`6-;|)M̲:!̽6mM( ̋ 掄e -6( ~ׇ=v+ਭ:6 k)$s"זou(ֹԤD +{CE1C>x&uObg}noXD=K +hw4|X[gQo`ml<6adӷn]5H+ {Pv~͎^M^]^Maͤl ݧ,=7!2D:juGu Zk&19 Ƹ=cȚkSaSۆnƶ54SԦ +.0~ +wdv+5֚5&4ԑ:n5 +F DVָ)#qȌg^eYa[ف {wajC潯G-^3kV55JYKxv1#IQcZml׸u`}{B{+`\`XvqʕvS>VF 4}؛K3zYQ4;{ ]D}eN}h(ȹ߯Թw@\/Xofxw+wk +UМ=m߼MBʲvRԜVnJ'g\>v6:<0CzGUwyC2dH i!$2DB{/s!x)ggKpѵdʣdػdH AH60[@AeTqa[z0 *ZJ\Ee.ee nєGh[^_^p@*dH ! 2 Y d[Rl#wSŹd+E0[lKZŜk^Ŝbڣb+*D ~W~sRUA9H>[چeI(X ,̹GW̺UͺQg1oaUie[Pie}WR}@0*l-@Y -| lCq;dL*ї`*SjF=jGjz}kZkq%5ZQ{n CtȐr fHPh}´=963r}3>lB]wӇ)n|qe@, ҟ@VVyZz3,$-Tn ȐZZ7>X?:=.( \:O;'09mXv 9PTRnjl;r#r;r" ;(3@p (6#bSR ZBCX:brpyqadblW*1;%ٝBdvAuDv(!WIjk aOJr [1*h.tʪ|Z + ߚO%{c1̮2 Ր$ :jG|Cqjnq"&!ؕa{֤dDBqɱA)Y}dZ_h'<}cȔ +dWW'U6YuX{5uvA&^U1͸.̨>l67 i(!9R'<='B}0 b䐱}#nhQMKgW8J0F__^. +;N|oC6d`?Tk,5C0T$ܷ RyQՎ"zVaX\Q6yrZNȄ WρVDGzRGnQW~PzxٵhdS?oNDGM.+.ն̣]рn +i@$۷3. ŵne|iY_r CS/ҺUywKLAㆡ]Ū1 !HS$;`.tDwU{Kp;tV6 }?k\٩RܪUMmDŶ3o @]7" ӢyA,A߲ԡQ ]C%NYN,i߼%{@F_nT֬Ӱ`54~.v p6⢇LA[jȅyЮzWjZዹ웽CT՞XݖD3>nM+&tA+wF; 3Ku`[A@_c 6cDi߾7?/Sx?.|Բ~=y!QTUqaD%$̼:aF+vJ7jFDP'- +'Q;|*0wn˃l];׊Od@Ɉ(x(m*0kJ%$Tyt9 5̚SLl3LO`ۯOJٽUL q@&PoO-ޒ P2[SAhWt  aH(؊ݩ;|Dž$:c-9-ܹn)Ɓ[/v;ߗZ>G?>T +1x 22;uuoJt.Q?>\ .]dCMpܰ@[vwL>xv/筳W>;{ӀQ3Q7~ar RMD NpV'яI2lC6V)VT(vMqm%už:(N4䏺5  <7CAXC4BzZw0)}37y6DiVuk*}ÆC۰-iڂgq[#uȽThs@ rr NU $jD +#"i*j%$1l(P5[.sU\rfL;2Fni1 b!C4dmH0p Q{8mόMu4jZWmiU;>k]ɚq)ň <뙝u@,d 1!FV$tm8 ì@ ۄw[^ykNaU8ΊmwE. 8sN1Zg[n}k?؛?8Yi +(Z0e`2M{D ُEln.cyh :7HM9&\=jZnoMQ_58cd@ +z7)f }myaڈvIY +f1adK`-ǔ ڽU*Ay@@PY|~5$H ee /@R-0sm(hJKlwXHPAO8#ݝ,l >*Q`PT!,:e WC}$AD@UeA1XoDlͭmfi? B32kI{?tN.)d&dGTIi ZC|!'Ai!2$A,&uW|*k<诖U[Va6cBfb"É9aܦ&B$!"_~5|o^ٲ7S@nPeHk;`GUXj9. #3+HH K5[ɭ -q栘&x@go_ KS@a +ЈT!zZ]j-Qbnj<-ɋ${ZH-23 \k8M >U +j:(ѽ]/R46n;U7 +chv"G7է%/T@w)ݳu|iɐ!2/퉴onZl7>>%3o0p,2/l1'fۤ%UD?Kkg_% 틅.,ak4 P“_+5/4k^FKuFV9g2ED:Iz[]l_)./Y +\t 2_'ȹ-('R?!VnWiK:Re=< EacpB̰q2mư.tXt{b}<AuW-צw@dȀ ;_ ڮRb]I/:75EFUt6aA?Mvە_H Yiܟ*~y~Gwn-(pK?1wHypBtj?C!BZh= |?M$[_hY~Kr7x҇$pF,jyFথ5m<?t"{ }䭹ꭱ`LVާW%ʟJ<݇)o"W2c M5Sdwl=ԿdѪ@ADADADJQAT57A+7_|#|~  ;98d.hA-p@\7TcEpDH!,R( eR" '|xK X]Y`,OѸQf{&IFq)FP) (~ʮIy.>YsҚekҢM{]W$ndMՇ 2H +Jpf _ .O0~ƱFisMLj +cdCʆEsʲuk#yݝ4Л2 C d+AC{oE 2 Cds OW n4[ϵ_غO: xB}Ӛj=#r,ȓ.bVulc w/ [ W])Ӎt+tK|[Q_o&M 2n6C-b~\z@- +X9E"~5$d*T #c ȶ2dtF'xGLf@D?Oj>%O楟ȯ?l뀦q)K_vk3՞Yq,P(lssxuGrqOvaD 3 -!iT\iI +$WY,NU ^熨K߁{@UԼ}5),#ԦfzC|SێB/qcXY&&K΢12"y!!ɢؐiWT1.ׄړaبnD{Y]Uy#ݴɗl!Z3 +m,I8߬9ߢE_߼ ē|a۳]7蛾v˪5+jW zۘI]O>sk?O5446z6!dG2 +|*AgIwE@H/40뭫7?ْdKvᦆj暆qª}貺aAhhO-X,AcR`Kd+ \h@߼uRt}當ߪٹpO"{OY2V⎒i"w[y[)jSXӌ1\я_F&-VܡVR_{ah_[vSh_ڝ_},{%HV6HFp$c$v{*n+go= :fvڛnZ~Pap-r؋^=)HbuΑ%궿S7$pW;7pH쉴ўc m`mxƶYmsڎW@DŽ W%;^>?Q.3 \.\NWeUM7pnnY;(ҮO5({hxzz ,={*=qP|†xU?0Woe>J?~~.HUP) +zඥgQ@^(+u"F+}<0BS,/RBcH@>0 |/gg-  ?k˺L܂+Ɗ@D"=4PGJm$GFP&n|Ed@B(!A~5Fx],gN~1_?Ȫ/,& nK= ykJMy0_ou*# 0U @#D7wrrIPcmaȉvD`Ѝ߁6Mp+CcA_ 28AׁTVZ0 M#0p!H;!H+#H + ;ԇvv<4 YE͇VcI x{\ݺ +R2j}sp6p 9 ?ԉ##uP¡n9H1|ȸ;l `1:m5:j367dp 7?{ zu`X:cC OucG=ˏ:gG"`;FȞE~´˜(a5ч2x@7Ȁq ݿB^] -pp;s{jo ށa9яF%-Z&3jɼ7jz0r 59`7e?B@GVM 0/ -@Pu  Ap#o3;ǶC3MB̺qbܚ %nA]Fb̪bۣgGQ1fǡF @sx" HDi +p Sm/[M'UEy؄YiKNUy܄uk܈@\z(q0i ֹ? #+#!ʏcp!iEA!ҢnPH-'_Ŭ +C ucvȓP ַ :ߏWj^i5 JJ@d93]cIl>!ψ\{$I)†r|~3 ?럂sWK4?|Xsg_GڰV ;\zSL|[ZXgo-w8e9<"+Up! G' J,~4Yf -bu*}]؊.0drm +gRP&=ËN Ңl3d6&e&f~;u 9?8dK~)TzV[tuʜ/f-rˑ.$46ϱOf:e9`h6ԨB2ÂVHWӬM6Yt[oB!Cd ^>OJNs%QSԮAm7%⪑aᾥ6 . Ky/ՔoOC +3~{Eaka!@տn 9p/^호NKo2T3uL; Є#FD,ֶƊdZaRM1 גFut}WaW}[U`YfR̼* 7f9ኞ3 OELZGOa"#f zsEa áa B_={eo=K4C֕I~J{${%w/nS^5dC`b _S]km C46BԷjCqjUn Unf WA#?Jt&8Dwvp KqB$}NRV2Fr}%o=M_]ꮙ.OiWi磸UV8`y)~3@~KbDW ](7 +N.}@׾7R>3m`6z'RZGꇪn*O1JO 1O0 +vCܡQQQo6N.}c.ھ/(uT(ThqI 1B  R +iF۳YwFxu=i?~g6`:~JVC@SNm# +06ST0ssb$X v$pQ@;x +q. r,VNVA{/wTQ'kA_+ +8Xi XE3?XFa.@ +sr0ʹ(B7!,B|3ôq%1U :ɰ`a,,Z}s:,.`NXxH@;d %1u8B[꺅P;Rjj0iR̘%9l +I [z V;*GG0uK[qW+pYg83ƙ?1 b;;W3mL "=݁C +&n$bl1xIӁـن}És#qt+s݄w DOC/2 L,XߌpH? #!0F *%Y $܀ٖ U/ow$>g~ICXxP@'wE2 %=}2"2=!wI:p#v9QcIӁe7Z Q ?\A *Dr '1aiۘ2+;H _on^0I=a=~76ֳ+Abo 27gz{AB !,D $N38%yͿ<+1K@g ~ >(@9+Oq'q;rȇOS QX.AdR! i^ 4hNwvL493Cp]p][W55}_i/>z0u(RcYޣ9 ZwW,$enoYx;Pz"W25(0 XA0,ӃSPگ<5{%yˤP>&3#"^( ;E0,[yYs7!vxg-V&{:_UQOF="?  2B>٭bz9}CARaR^ݒԐZVZ:}MU}kί) miZgC9Pi<mu\xW&9^ ZalX]&o+Ue7Ud䴗(;͝yg:r3v)έS_7 2gA:TkB.گ=?{c~:am5 eI򦂜̵Y23ʭi֥)OSd<7e`gCh|{;^V4;#cֵ [sjjEƬ´inE$W?Л'1dORu3)'L{&τճ~vY~46[{]/q38vV3%oU5'%5+S&fKbJe{Nu O/<7 מKC{f0n)Gf;[rdΝZ&yC[YWhM7Jj ##"tF6՜鈪;H2(A咩h ox簥I',whu{nm;3v 'x\/(uU ;-쎞5]m -5Z#Ϸ ͞J)Pxt~Uꪜ;o2Y;Nyí=Dl.#o̍]g451B7tr]ŬI5 k0v'gC+FS\tjyo'(ayGBb2eXJ]1]9U=5=]hΖv( :\79k"k~ڨO@'Fo8xzn s?|n߀rPN>]:6ܟGN {Z%zd!' + c] Ѯ1҃Ef 'f^T(O&5f9;wIW P8ti:yzDW;_ox鲲N܍ {Nyb=P%>!'? =>KN}/yQ'y.ՎgD> TMQymUt|3mxo8㣩zGE퍳?::&p"~p 1"?H^iOxϱq_n_ +n_bߺoۣq/DG#]@>t*6h]:*ҟfKZ&viiG +@ !ph}3"ZJ;gXfXAv{WKp; p&@{U3 +՞c Pu!<<3k]:.cKXajW8[7@0? Їy!xae9́A~K|\JL3Nplp9+lc3O>? {'7 j!|9P T7G cH )z9\p4q .\p$CpgQϾYH#߅?~G6wPo,l0 !>@&/voR.Zz# n["}O"' {k3;#{Ο@r!L ek{CH?3$<2^n5Qoύ_ü^x7"<@z:5e..]kL̓z4^ +6jD<}JHx@LE$T +~^]߽yos Ǽ7A/y(o"FxCF]g5g]o.YFbB HS '[ŧLɷAo_{֘w{oOFD~*>MMƈ*s$R[ecjVĞGͧ}g_Ǡ$Ề̸RQWq/^o}NzL6$|Ls::u7qY#373wbkR+C;n?E1C޲B)iǔGԦ΄~ѽwG^ɼ?*"ukq+?H,]<WB>d8AըSr׈("*s?49NRr+DrQ'.\cJ\?'ĺ#y%9}!=\UϮ GfMtIP3{۳X>tC㹼] ظAgEF2R +bʹ)ܺڰ֎֭U̶kUWgN,P5nt~MIaMtф=G46r3cղ'Уz-h0<>JW-+ .gT- RL;^D]u~O@i'Ǩ#!ae4CAKӂ =p,=OSՠz*թ6*:xj~e"9_)Ml+oM)u)Op4B(WOt1-RqPrW }.=?'P8Ie*3;T*h?j$xɸǦӫ>rZZ-]]N] +nxx(|y>"|us`{?9">}|'ߪTp'B{F \UC/ U#gXe%qv³^R_ɤDkpsxrx.On tcsTPM5QSVh(/Lfn$fejBfO }sN$GIT4g,᧜l+?w]@[hRB'#0B#y Qٯ9rAwJ:kah0Zcs*ّ l=}H@eeDh!CONmFh?6Zw[&BTax9hN|u>,K)V`ζ"Wsu5`Wcu] .FRA!9Al۰\Dqe}D*20>MY ;7tt}Ao,Y +FM-lMb,Vr9Yb)0-@"3_IB} b ̇%}B1s@u +& s0K a .EKLg-5#`j``g\ 1Xӂ??9DW/n=Z_gQs|>lS&Si +ێ[B$p8J x[?p;{/wX,x xYWKq'X$ @ rLC8c/fS 8 Crs-\~FH?_x|@?D8 0p@ `ҿz%~&*%jCyfnd0<%6YKϴA_C^|cQgc[ |Ecn4N&~}y/{W¿*99Y@g 'Aۘ> +>x@ŸKyry%"+LWi؀e2΃Hyg !g#3?-+I, +$< * n`%oSX[Y7Y7hgXô!/XCO'B?G;@; Hz LO 6сd%R\W~,ߊH./ޏ9ʽPa-45+rVĻJ]xB6a]`;|;?!z?`7}.؀e9 Z)@a=}?b!+zdtBSχƜ -9ͬ9l9s<|0h# 1b +wqmx%r$~Cst4 jlj ȶM'Yw(Nץaޗby!gq'8RQvFav J,n8#F`䫄M׉⾨W?P͙Bݙ?FX}_MAdPYiX|Lā=ĝْ%IuI[yk66% $G]~*v ^05fBl΀%XZ9[H'wʽ^- + b +?:?e}tW$tlww/ +b`fx4X2 +WL\a6e휇u.n]*0;UDfNo'%=ryW2mmlbMl-]AKZ;.QF葢Z Lc4gtTP. %˧|6zf'kzkH&i. +eG21"qD&oITd4&gՋ* ʚeU 2XvyRLI⃬ćcp,CtHљ&,7~-Sn>{j2ϦBnHov4".I.JYeN$T\W,+l/ϗ\ϓ˓͕ɕ̀i3 +N2hƒv;^ho5@qV굡C*GE )eҬdE~40GZUg6g+de +?6!Nc*('BK^.S۵rn)g\,lAfSyLI2M^+KSe)2L*Q&I=Q$Y,KU$K]8̙ sޫ5t>/T}ھDVbK}fOe=Ⱥ%ģ\ɪ)Js2Ӕ¤ Ey2^Q[Y)ZqBoyFY|͒?t̙9C|wͺ*tp|tnd NK7 ״7qk4^T(.͕GTr*"sTEn.]/ȹ^S(g " `5Z*oh}S&-tr˪ 6;oXaYgŵ+ԯ(j+Sjb+xRNIV",l4P |8f1S069fb ц9adt:78پBmvY79ծ{vr;9ixqKLJtc]/-`eַ֕0 BeTcT N 3A,e +3]ج57jݮ$5l#ٕo7I:~SV YM_[ud:7dP;((W)k+-3ic!oqb8tr*:"~xJ)x,c];-s%@6ŒƏ1eD9_J(76%o\/ ڸO$p粠cIjP2 nBh[ޢAh14pZ;c4崭FIܒ3_C>4>:'L@) +;5!`O(`OC^O=R<ܟ__6_^ƽ9:5a,Z: YZ/[P; U凅>43 `iJ`kљD"8p_b _v +=lջ~|߆=:sDh6Bh%#Tb<UWԙk_:_+ɿW67#ƃVd @u8A :C1[ 0c9{xPmߩ$B3 ڳB` X =`rW0^&`gfnn +>d +BW|9$BC>4i.lEBP}?!hPς)Sh0k& 44]]'X X +}30^j p8.C5b3X|؁}>bcي35`3(#TƓM3<`3L״u-Kc +:@o +X -\ +F …`P"t]u`W1&Uz`g8XN`%r4WT`]z1]z ؜r`{^:8|sO8ik-lW.U BpFe d{ccs^ ;Wo>Z(i(A` \3і ~G;~4}NE? >"'%e( Xp#-z`wpƀkA; <p mY($7(7 7},=O|\s@d=a8/|sBY7ar*9z\@DCi^QRRONNoӎc#tle? bτ~4?'龖>I2+$_  +^`g)J z1XH5hH 0y1v tWa{v= 59guL7W(fC -˦~a3Eワ4b(?璎sbBKsqqwswnc rY[ؗ"6E ?D|p?E Ά͙= b|é_αRu+Jz9)X<@t;>syLNa&NU9>bct_ވݑw"Gkyk$,뜱Z;1!k餏y+fkb]Ě+gJ +LuX Ps6d$?ZXMڃ*k,\i(Y z{6}ؓ[+jI7ĥkccKUҊiYFii>Yq?G¸¸Id=ds'rbq/*ޭ3wbZ׹G* vYn)f:3x-^](2QT&H.Vyh}jhWjLRt/UL=KQ'^̚ )!W{ܧ2]5z*7\j6xE@גK݅~m9! qq2qRD.gg%*2č +;#M-C.>"]OROS!CITWhGp.:f2hF⢭u&hNeL".:-榉2eiҌdiR*UJkb&eR$Ʈ32IY@4c"dE*#sнr6:ݱzvyml"8Ub O(T2^+WŤFF^ΉJ?ȊIy9`M +A9[Gln*n.tjc+]w-dۦGU +2",4*:P(bl^ff^DfI>')՗ړR^fe=Pr2dqS'lPyW9]o֎G{f뗫賙峬#Ⱥ/k +#s1QbP+qpKX@<^gۊuOX߭Y5uڝ۽rm7K6I1zvC鉏&=yN8HkDH?qB#[N/;䤝wP"iE+;bɤ r<`207[ o{'o6ygym,nU"t }ۂX?P˩IJՓjdvY,=a{.⨟{ ?atE=$`N +>M>RI>ut+xd0 #a!BWf ?c9jjkfJ͏,b"щ|bP?ERa(srǕM=ݯp<5>8gk ԁu*Q}u`F3̵mWYt$sOŻ?`q)G.GN=Ov9>`c،1l{a{?c%XϺR_iJMyc8fVAoV7xbus|KwxǶkg^nkc^KO;-?||,'^lC,BeC)#L %|M{2YK~_rQU?mxZ5E15nj;w1^ 5VC*ldW{ۃ ze#$P[LS5 4X a"[0YbVKph`0X2@Px1ӮiA(*v>@2@u|0L 3fxugiZh)讆 Do9X-z :тDy yctۃ'Plb?E'qa,+n +5V=a"XuL{.`;Ӏ98@0&X0VЁ+`j\r0043Xg1f`L1[Mt Ŝ7`Ż?,n bX`?2,hXZ,+`,(gq,L`cZs0k5.zsb)X5e&߭fV`:ºe:`a8l낽Bpp\ +v`d`c 2+Pb-[uXe6GmOfg_M96}kf#v`f `e0] :h0\g+d +`e ߶6?m l~V،5X_c;CmVY~r%VE> n |v2  }` O?U{&bph9\.&+S5S 3&Cܜ 5SWe"ջO:qT饿7=l<;̶( ωlFyj~?W?/K>> fMIsU?ek<-rd!Tb:d<⢝M4ޔ0b$"E$`6Ċ5d~ 3"PP]%(n zc +c +'b0obr9cӀ7m"Hfʻ( Hpb'N"Aa1 Q}˺+",nK_ސ_WUS(8cQxpvsaX;5 +xRI|nއ Q~ؼF&Zq\512j yD- HKjOOj燶懶v,ථN焴n6;mNpAYr8`8J06i?(5ASjgկ Z2u]:3җӓI, ^Yܽ<#{uZPt*X2vR7)R:>Q5A}qviiآO\V}*װGreV㔷뙶67>2.J NY02?)H{V$kMLUp`q?B|&gyR=8 I;hV#|GlJSc9 J۝ܽg ُw/}$gϾxykI5;?=8p`$?;`qT%5MIŝ0 +::š2N{Jy:L*: +^s;{}v;z|./{gofu8 g +o@-ԛf7y7587 }{\gx݌n~vNKQ wϙQ>6u7; pp~'o8 Pz`M>|*CHz.L_T*6홫s XSW&_ٿ2{FN=wgl=ҵy_;k#Ɲ#8 7K8:@#$|$E~R !+H;Mǯ.v_i:6|uXDk[̤i(2QiS爺ѯjFbN= lϿ7Xr @7@ +q/RBRT%m2bUsj\ՌWCa*(QY)j% +E^ȩbv +_'6@C@`>:tGHZKY"Y3)gTD +jUA+9y!+RdP>~h^"%~Q( =S#""a C$!dRQA2@FL[iQDBRd IB< JH_Ki)"=#%d`lԐ>Ui 0LF:m׊F}-N lB15I5~VaY/&H1l4 5("C}ycbL(Șxd K05f]dԉYWc )mdUmv\kO-^j~Gsi7CA@O("s}ede56A1z,S#JI/mޭ7k1bLzugvXnW;ڟlk}k齲FAFDKYi* [|f*Q{j#=dilR [.7a]o8cfͦm/v?mdS!9}LGg?: '22`.?c(Z܍k#?Na?M9~q,1Xmi{wνo޸5zeKg S?>@hp]WdzoQ|)ηSC^iVxQ4_݃L>Rc߹fXq]h[SOL{<4yHj|)^׍ny=5*l.z U9 W +4G_q,~8}}G7yn3gVjz7[ϰ ulqo +O,3>ڜ;EG'} 4d$ܱ)H 8 +i&g6M?3&#:* +oE. vMٟnu$/G~g!>?Q烜e7v 9Q*uD$Ky|G׹1;0y<3%.('(QtS QSNSuxuN+vw9yQq|OV%( T-//-8LRotfw"$r48PPǁ2ھڞfU!#m![Cvxn99ͽ굁kg0\ĘIK@{128_Š[–0ºAz8s9~6X#ߑ~gYC5o8D|kϒW!ZI_wZ|΁ ˝-^ҙ X%*5McGzF6 F >}77;'ge4tSL Ha[TXCc>te5qْZXVMQ =8/70gQڂʌܜ9+33sF33rdL͹.==SjFH">$bUp`WLwX [Fnj7lk w(K).I/J*(H/NɯII_);.pvlי|L%\/Z}Bu&L[AV^oo nl +sq +*"Kr3⊋sbFFDOe\ _!#c|P"f +p {)잇懍0ʜouXobGNsǢ=Թ%«)?>R[Q0WQVњZٟɭLVO ;5EjOi!eRRzA'v} +02dLt^1!Ԭ 0\P`Y_z[|H|srtDSVbhcajHcejpckJpS_rPDNNӕ _j&ec38؍o{jQi_GX9f#>JjQb.) sI\"ڑQ騈 h \й/¿J8y߲~m?}J z{o?.°rRMZ7w)3u +g;& Ѣ|8Aaa.{`Uk`"57p9y s՗ z<^,=߁VOD͊иňTNt*[[#{QTMd0%lYdKa/`+ckceNc0&vy{Z3˜ϝ +܃x LXt~CvC^m={$v)%։k.p[--FߖCٶg[.7k\xnͳI|l>.K",8ayJ$鸓l17У^zGf}{uɰ)8Zk~؈۱mcg-Gdr|=dj8< +ְa8MB5'56O;U)[?ߡd +O?xxq _~q8??~+NHfӓ3qxo%oAꃛG@%O&S?}3!kuTFVioǥ];o+8\H ߌ$헼/1_Zf2ƿmd ~;"Ym+BdQ*ʑRFJY\ WDb +h|n߄ɿoH.lD,)3D*zHSRK#Id-$MBQJBBD51C߂P>7M >a$$EURGjbH[L # 12r%" 6' (QP6Hp>HY_oa1V@֊HU br<9^ Yv`z1CrHm,RE1day^M_ZϤgK.E I}Dҟ4|>zH +HR i(#M4F(T) &9V7f3*'l)K/?~"EG;]$VkҖCZHWW+"C'e﭂9*H/Fe(! +z Jm?)0V1WnAvFlrM#w&oe_|{i^#FH <#向2ai,핑9M!&)*?MΘ|3UjڬŬCY'!k>O*آr[o(zoJ,CKik!ceYd(4d# Gk%dOUC6?C5Y'Vh]޺RMv׶+U_Qyn7~Zn'ǔ;^Vz@n#H=Ҟ2PE^^ +I! P@TgoONwZӵ^8h=s*|\عEK^(jw\7vݥzMKjWFw H<韥 \ Dnr*t$wOwW,TCj=\;n%:ܫtnx4i_X}ͣ[ǀ1˴)Km:\j7 ~w@΀J t8)pFδg$D=q;5.D 7]T Q {"e^.TksITc a۹ N[B2]6P6RB)CN,wu]qNrwQ'Cܛn=VqGy + XQJ |̒p#Gʱ ȤHHQۙ`%&vCdDxZ^6+ hCV`xgg_:^=GV_ +C> . ȸB"&W•|8]`w8Y|wtTrH瑘 >J=FFWrƊU1Mm}["6G~]sCw9d +"8^lLڷQt[MaCxfp*ϩ?)֣'>ŧ+.[<SniaĬd/Y3'>\@mǀY ' +X> >xG pbY8TnHUj/<].79 д?;ԡ;=ʽ#%ޖjN h__o _\#dI!eƣ Q<1 ;'+%8_4#l_&f1]}ߨkۑAm͌iJKf%gq +B*JC$ֆ%&J%m% /L^W#0 qB%Ev˰Tp8_k-0Q*9GmUl^ȣ4E{d'*2҂JrÊSETF,OZ:):;PtVʵWY#SgóSfysAa;v%_'7XwRd./X49-U&feeDdffed,KKɘKq%.)ylR䌟QȹH }s(ؿc(j0l7IS~EVkuiCUi{iq pabPN~Zxz^nlrNqBbNub|N[blN_bLDbtܿrE|#z.(o.yq)~o!d2i7! 9wx.[X`TSb[^ţ-bc + # $6' +{ + +wŇ.<-|?6yxmwUvݤZlAV%a.u^ձĊ$ntyF4?[ZRR\6&lG4\QT`Ǩw +]h4$ZG+[(7Yl",Җ l o- okfuYmXmg~̖@Rę#<j809{x ƔïX3f'T>J*V]6hup IewXݥ~~= =]Lߞ1:g>+~1Ww"v쾸AA_/US:IKrѤXzutqQZUȚP(hs4-ֹG;|FG\GRGOxw~O z  O==ڸ | @6cR6[ԭ-4ti +&8^<7U6-mZmiZmxg:ur\gށ8zݶB%!!;Q~l> +k]m7coTS}&}ƮZ ]PosTemotw0p3篟{0 й.}ؿ&"B?M58k#{Y댻 3x(f|s=>\{q3_E +$/_Y0}"iS5KMqyb*Du޷hUHI!5>>[A|?@gb/\<yOp*gMl]E他wQsQ;1?}D(],${URh,` 8ǽ/ƽ:/8 +- 6@BHSX !3aid',Bˆ!HF!$ hP%?V*>@` w&_z7q=G,i!WC$2G2HZP) 5AsMl*DL.,Ŕ$n(dca e,`2H"T +'H"q$Z"īDD\&Vbf\lFۄ>r'f ]W/~ |EBd| RБA2H^Oɛc<]ɅkBYHHU!Q$&VVX%2FҤO-"?(rI=O*/ޫ|zK2yD1bsA8_ECceRwCj^rH5PFOB**Tͨu}W>(UcTƄiϚD?i;"_$\3-$T I7%yI1D2q2m*l,9Ea݄֔$^I["צK_K0kzn)̬W5-$Znx`yPYV7oY=nYK$)`t$@*YG9rpb:Pu3T'6rlJeV޳mkLJ[7GoOJ_*}ag8ܐ9 +fN9 H=R 2EZєD謧gwS'_awn9g+^wYpͥBoz˔KN^ !g]7)qݥxIcʇ4"H{.BJ9"OI!+/jBXz"dxx+^wRv=U%=*OOԏVQ?^V5z^u_s[m?x"͞`z?U YY2-m[<.0Xja}udW7bXI c4&-)+&t悜{G$"/"Uwy:|Wì΅Pesjt wwlc-4*7̪5Zjtk:6`7]n}l s_, Y #?~~&H!|Gqp=V.ĚGHVfk!0r}`D" +5z1Ng0gzf0hMA۾A9Wrf8_  >ƓQ"n& +¥de8bw0QlW(?`uaVcDnjn wC?ʱ]u8uq78us^ν˥5 䍽K Q4"\Iㇳp$ː'^dKT"Ssmx8g=*<ŹCY[HY+sպ.絸.uQxCVzfNan7uAuam.9s~.dD _O؞g#1*=NWN7OZuF9vF'PGEyF{4GTҚ"i=#<"zDl8]qû"5fkI\ \y|{aB+\o,^wZEGRC[Bd,Rzut-2Q(eEO3G-[(10@ j.v}Nj¶-PbvPb?li[z]SJkmb*>gI\.,nJVI\kQ +¸!vaܔ~>Kyq⾰|P0?vKyc۽Xah Mk!S=?xi.צ63¥"-VX*L,O, K&. NLJOp>85qPZi.(.`Z{{o9*U`m iA]c1CeA}aUsivƂ4ܠ␴*nJJKhRJohbq)gBcSpR>ǥŧ \P8a?ݕwFFj }v]UT +2nu Ǽ(ԡ =//Y$<&)<*s%/2sy2q/4<=7/^.ϙĻx0R\#m Êuh0%5.wnw.ktsrC""kb}U,Nev`@"eM ryrͪbU[Əd(GQ:|Nǵo{.>hVCBM@JWE+:}2'XGC[=8K|ELetߥC̥Kx2ޤx4|G'\=8W` Њ]~@u|ВoрȂ~ٌU դ^^twYP(D7LfgڝѹJ_1bOgΛN^i˾Sh]r ߏNU]ߎVa=E+Ƅ`UX֘N0cU"qS!z6oYl +a f8x.tl`M}"k"ڌ6j1o~c ' \ЧL\ӥ{Y`r)\8v?K7OnCw*ANbNKb;2^J^}ܷs4#)]h9(tѨᴣ[q:U{Uv\Q\nU-r.cx_pN`P`HdHYS g1dgYd/ZT^ )LR|uIK\q8õW(8wy "6w^0 I2'-~dd/d/d,~<>o)|ߋHB3 $^z"^0qxp qiA9vuD& 1"CJRH_  ! ~2r#"/>@$@1D@JvL?f?+p~!xµs[p#gZ/>Air2HO I>ǹj=wL+T`ԓB":RHX[ +I"$s@D"pE #BHA"4; bH=74i'!O9 &)3#dDz?(ΗԔBRHH[a$8 C1"H C  +"r$XGFBY]G.Ml;A3ObIߊ'!G|/|Η/"d5%1$I q$)$SEf%Z,8#U-]IL;LUdW[AnVwʟ{#R; +H # 5&6Cex|o5GW ]4!r7Dg \CƒJQh!+cvLiR%GH<2Io+z״XY-B; +]bVዖ;<"|Y"'ފ{QO89*;2`cy,879}=ҰgbY°9Gf9{u0; ZcMё 5iUṔEK+\ԒnE Ϲ?|t+懣 ܃ 88vy5`C>v|½9n2tն4^SRYm<϶26Ʃ<:uqT[qTGQT)maTgAT炨U^Q^9Q۽NygFΌz0̊IĊJ8ŠL7*as +p/b/IC*o/um*,b,s) ii1yZeA lnAvH577oh +b%ޅxp]6U,jMX^mFjt[.]QRSP1^ȵM-zF$3ylnVQ@HVu@pVPV?= +>o@K߀òL3i<8{vZ;5ؽ넠^ZꍉuvUTjoŅKBE-Lf +* [}م}Lvzpݯ_ > }.wa{qzu70M|Ҭ -fkrRѢFl^C-TdSjǫҽYe>~e~e-^e{?$9C>dɗ4(3&VS e +51M5.0-7m2v1r7pݭOTso>~;Ο¹#}xMCe#k@:U[gD\gMwufQaykEPu\rt(c(c .k4֨9Tu;8XaЬ\Ou8w.]{}8c + foZ5!h FYkC}.GWpUrUrPt.R&m=}FzC) e,~e?޽mS?6O9l `!c,}$}d}Bnw +t mIиu w *w wi{l½pT"yR{A}t@?ރ{]$;: q25[_AȿQ ȼ H1 $u!!C>{<{1W8} ^ށ?p6g.8\0 +Od?H /!/)/f 1*, S`p;xp qSOD4퀳p.V} + @5W߀@DD F1V@oF 8"i#3QN| 1| +Iʉj1K  0 ?a~ 68|{x"kJ 5qħ:5kpA%! _G>Ro&Fh%@'; ;swἣ_5%89DT%8TCCQ$d+܅?[ &%$͐I*H_uOď V ޑ o^wKaxAcPF{"xG oI*#)Y1$.#TD(EҮ"%B3_ɟ2ߋ/#!j"j#>ZAx&Kx*5Dx"Hzvx }K2w+uī +tE]V@|Ɋ# Q,)4D6h*KQ䫲{%kh TgJ +*W充tovonnNpU os i$Z Oi!CYEvL03tww0PC  "**vw꺫nw_yGsgf1(3zYLNVfl XYj.T,ISTL+5pcyۼR]7-VsXn{j5V׭qZGW6 <9mȞ'0G>#T1.ڼߜL:Kj+&Xm}6 mjk zW ,\r\tZ/8UpiQiK'JwLCC(pb;1J˜sG6soyj=8ZH+Kr*w-_{yZ-=:Oyɟ?Rhьa +Dg^W#XqNN#"FmQWe? +9LF:x^ U<|'So +þ*}R;WLuxxJux^YImj[W_ZŌyfُ лz#Xpυ˞ +P>,R?70Gkw`.IIvmnA͒ڛ$k7hoڥ3tDg*d}5o&$0$! |賣t=ZYǸHU#,Nw[Xޖ|Maê և5L 5 6\p"lpʣ6IT)JH,KUϫ$;y.LeD?Ga.`)" S].>+Uiʔ&F+DrCC: ZmsRj\2 De^2|J2.-dlefN痓oN>97z7n}}6PDkhe=w]JUdQqSquMQ҂t\b*ܜ윞9S9ҲOdO]7-yɗcnFx m׺FYZݤO˛lك :ŶfsUamEeŢT^م~i ΠIb$`$x`\q_/>3~@ NCP XL4X@+ZuhՊջXhoi +Poի2++Lfgx.'ƗJJڂbKJbJFD,Y_d8r!Y &̟A{z}0 :Ρ 4ΎvLCJUk¦Xiui59>~Q5UK#«'|êVZwH/!T0/yyܹ&h{gw:C׫L}FgiuT*uI4:sڣ[S1- ›C[gH(eGp曮O]qhxPϼdL4>|`9ú0lͪʆ䊖G'Y$;Dtg9vwUu-vt %],:u{NmKި, !axoP:U4E+9EcQb z1bL"F,C3l%ÅvÕv-v}6~ëXY0{#+/47 +#j'.]+OEΆ5)J]%_)zMFDnxQx|Sg{|M^{ꁮʟG>5ze }?gW~\qvZx)o ʝRfuJlJIٱ]eC6*΄7hyoLܘ#ڸHccn-n7nܯˆU?9O ŽAaI7Aw|ivű)jNwSnNO<#5'+AeWpn\\‚yǹi9ǹ=.zOv6},PH4w+P=D BGd6y5#l.\<ǣHݱ$\ͱ2fձű )c;pM1> RFw[9Cu]x5':v"l.elIfLxD &Vtymԯ&kIzWR&E %8!!<T}KL/1___~V}-=| U·veD>߀>ށ@$ s"XjD? +pѬL+߰I)̵Ƚ ];BLAm"w ?$҄t_6JI0AMYd6f`d^C@OaV .C -:!OAc;M )f!ϴ4H7PwW!}߁o_מ1 +g(@ĐXO^+ןĵ7.\}CkKL_߀W } + WK!5Ġ3b#"XR7GAk%t@cߌh?}>+=W>D A@I)0:Ҍ8)/cNV!'#=4לGq +zC }Nsһޥ>{?:2-ǰn K0*rҌ40xpRHg}PD(4Ї +K}nzOaޑ_FV +k- tOiP>F\*wgtU!?KZ "8p^A_-` 21ehIwWZ>Oj%a.{:5n3kznu)jb]2<ĺhtuuYS&?rN<3a# 6[12r6j, 8_Zs?4r74eniQȾnYιbYϹlsѪs޺szszsz  Yq6Glopپooݶ`Ζ +3 B'9^1-{_Ἃ xN;N:UN8598w;9/p^/\+#͟^ +*]nf sbݱx}ʦM]f˹.v>#s#MG~Q^QQh.QѠv +Y xyH~ϻ +Ӟ_(UiS"Fe+0va-E7|5輿X,7\a7Ai8SiPiLiFyIyFܮQܫ^<dAw2Z\ԶhwٙH0ai:CsuW뎆V[ڪ7ڭ7:4t`~#=W C3 #oSs@%x=(=ɺ4l͙Ir^42:JwETHdPD҈Rj&ވv㞈~&[M"F\4[o͛#2o +g1{bxl{1KҎ MڔipOz)&$ǦduEwFGZE/h\=l=aɺ!zu]9{65_TGa]XWG1V/!s5v2S]+^#G癱8JeF2TRCtz:-[sZm*mm:jVWmpPwqQq_:PԾ${7fBun,e,2Ue2=YAZS̚2mk 9V$.(OluZT¹8qʹ(q 0?K^¼_,K`^%}́P}GuJŧiĀVp.tz+vj, o̊6HHK_$X0ʥ05?-7e-'e=+e=3{zM[z/)d$3| +hx5e4VCV2g^g|kZcanM~IynUIvCaVs^f[vFGfF(=]3%c39cgRa뢄|H4OA_ UAJF5iڜ]@C\\(H$¨daEAa}v~0=/=%3)+!;>g+.gWlf9W=r>Ee=:q{D1y9 IJE`B:7A]beD2L<,{QmZISl"Ϙ*Ȣ>EDE<Š}Z{hnK8&c |xiVjia7𪚼5ևFY%U%;Vd + +<ʛ=B{CBg\ /;Kw,QX7`^$4bD#~MuÒU].)Z⧔8\?9,)&!1!)9YR$u P>~?؋krW3/{Zcݎ]DM=U>*ssz}ӻUBc; #;BӬllmۺVXm5mh=S̽Zjf,_p58n܏=D+@O-#?bqJNS]12g8jߟk*/572_nݿg=Ͼwu=zw .c@&@s u-ZɣUڔW;WWȆ T  SM-ց-M) +ΩxGewj‘?4hr+az5|xu;GQӖ>< +RTX.Su]˺je6%uCN&_0yFamY5O.o7D'Q݆|ׂe+1kʦ}7%n&6e5 y:q$h~ >F\k/4G4zB{#KD"pt wAC|>E,!/2%Ƒ;hМgR0Q_Ȼz ډE^9C z|~dCKm-BMNMSl >fK}-i4y Yq +d3b(SDFwh~!M4w?C?,@{tN_X_'_/G A1@ B"YO)2Ak1:!V@g5J1 (V\w%:Dn>U>'02bPF Z18"S +eEA%J5 Bg2)1ihmNK7>Go?;BEAUbj6-NwiA'06~r QĨ@ ס{@4WbO߸Bl?V.*w6q. [5wnܽtU8]]KtQ+:';cw%7::t_͙t#^ +]ϥ %tΰ6iV:eE'3^IG' 4IM\`5}5g{/p1y }b?­=T+[tĞu܋u2}*}:}̺}fM M{>nAn9qNvYmvg8[ns7h3ocßc/` `Dz%w]ݴѤS \9G9EJsNq x;ZެM"m66L7lOOLuP0jGJ!#ƒX@,wu6]pS"S!^7(DzV+U*Y+3#* YY'3"γCvge㲫=7ȭ)7yDnrwGe=k47kt<xWkIڋ^T%zADoB*|ߙ$x8=QѠXsֺ(hxp8́Tlސ"2Z.!֐պC655o~]>3_k%ga{߆E%ֿ)QYR2ñb`(ݎt\bJ6Æ~QiƕM*_3) Ĵ,ɢ1gn@l6jveB4@i4fNqOVNTk noN6l4*0ZdZUcZج"Ǭ,jIYQG,[F~dYEAcHaC w>c#X)C+ti$ˊ=NoKWmI +nHү7K5-1_в$Ҫ8Ѻ(Ӻ0v&?v&7vmNA۬+1m2cYg0Vr1o{_ʅׁS )ı*Oh0ϜՓ(՞!ے)VnHҬN +O1.IJ2/J̰*HȷKXdPg搙0!-acJ~䄋IKgl<b.%D;?7]8VrhiPG=wqtCbuNzYVnqFqAzENjMfj}zJcjJSrb>1Nq){b;$wI!6{{7sߏEt ~ q {}%ԹȐZKm؍%B~B/"`H8dLB +alF0:[92csDnsNao/K8>ZS7Xo9b:+䨵R*-YNR"2RAifvq~ӤDt|2簼NмeN!yS 8e/^$)`qpcp +V|xmPc֙QE]PX㣐S^Te[oYfVkRRTR )#v%lJv/gWx6⢧6B>8ÃOQ,-hlPu*QI-م%诜[YgZbTcX]b_] --ՓfէM}xW~mUWsr70k4~klb*TԡGyV'nZH&]"Ql +Y'iI6o2y zLxl>'j+jZ׽7}'nOq|y$mh\]NTIT_˧~ J7{vBTtLxoBpoj@O;Qۻ;SǫHdzZGԽDۣ{{ n]'\TuJMM綧8I]D-.=+IY@q(f%E,_ Y \+L"=$WqIWu.PuTq^,PrPtUp>.`莜/~UGѾ3N"aņ{]({C< +YN5Ɔ%^IyL \'Bd1N) ddƛdW lǷmƏVYg9 bbytc-½jh!7#M3ɘli3qƓc7ϵ ɔ)qf:93+3F 6^co?[oo޺?Xk +1qӨ Q"Y"]d9Nsd:gE&s h΃ Ys,݉;wR$չIR#]H~绤{RQ `\=AEۈbv`MupH<"cƤp̆ II !x! +bk& #0a$DLDM[1o.t???9JdqH"YsM8`CCpty%@R`/_D?~f7 "~ܾn`"+&} |z< &@654I݅3x"<@,I%!DbSD[~{{Qz3ܡkPn#7W`<{i4~1% 5#4J?nc=|Cܪۺ\, Y gQ>;ߨ~3O?@S|7_^8*}} }y~b0C \z* 9+Vt{Z.7/*譅\wJ>]1p#pw )!cD Fs0t㠙BCy vh4 t&17c좷ݥs&}JwP/ [4bA j ]?Bn)ʅV B> ZEK1A7]3t}\Be/بI1*B_֎B3z*Vjq&,Nt3 1h:O>DpNMqpBȿ0ȳ،4oiUB]ݠ@w'ss*.KUE^=9~;iR:%XN't\0MG}tHId? +?nG4.ev # .B':W!H7r(]PjtJN/tTh!N:O4GhJګvkm9ݴSоN:Vi_Mz kF0f~%>]*jtEۚI@:jMSq63)=&ۤv6N6aCM6l m6MfX͏6_aMZ?8k+0:XbyiΡKjtŒX9X؄wƳwئg[ٛ*؛ZSÜu8k9kg99/pW%wr{ 3ycy?~5,鐓!qcpnJmFJm&JM 3RZa%oBXwY[[2sp/wqv9#X`s~_e\02< oa%/%6?ωmv +5Њxm7g9Juz,+D6GjԅkUTfV閅V- +m/ k_6hPʠ l0/lany[? C|F Χc2Pn@,kh 'S +ٞ$U9[.6P:&L<*Z42Q82à(2ϰ (?87$'$+r43rizn3f)7)D<5N`ycAl Uc$E*ԕaHm64!.S*OyQB8l̘f1i1)11-c,bvYǜ~26+⢟E3ϸO3A +1x-GZrNRU2}JRt MR2̓-ʬc:cF&vXG$""8 +vA>0ALm2RM|nY`aB~vjVfvZFARZI|jELjuTJMDJmxJMXʐMh)ǭR^[% +JbohF ED- yTWNU%&TVl..vyf)k&EGe'gg[d-ΪZb- +̚ Ț:fu/3s_cstlzgDZ_ƦreZTa@ +YNRYi +Iؒ0ȅ1EI&A恅EU~`L\8n[ا(e]W/^yrg\CO.\h9%F +ju(Μ28noȪ(IEyȧ,6.7*_YU׳5OuK꺕A< }bPg1d#nt㡙BAs_s 9C1x?ïwáU"Pxq 5Ġ߲F@ +\@ +ZiN;:Q{]Z̷bp5jPի 71ʈA-KǧD2W2`6jNg/tb.jh+K4FEgPӨ)dy +/xvAp/G*ch]r f JV.tS:L͸ty0tpݵt6;(B + 9*1/A}O,C~CykB ++f8p @:UЩN ØŘck9 oay߂X6hːV{ٲG=]FD`G#Q#]#WctGtGVVQLhDYFQEA_NtAVt_Z|ǟOP7{ ]!ЗE+V,Kui%{TS &+'Ynw|w|w|O|OBOBR*Պ>3J>{|*S.ZT؛yƇPsѨAHXb_ħe4b vJK}e[#Rj+UU-_V?^J= \/s~OryCSqhfljeY8#T7҈:"l8B~Sl]BuPr$ZLV*IW+/hJ5 +$-y\rl:, tmϵJ G3-y >6c'>W.KAo"uSk1z6C2WaQD8,\04V#?$Y+7$K;;P'+B'#Q7=S/5tX/%t^RȬ~b1C>ՏE7>NB0@hZeqţMʼn:ԘhΪMpVĻ +Jc BԲ"43"t"R"#J # " "FLEGl58b~("ca#y?5c.i@5E@TjBd!0S67Abm8*$2$"f$,fIhf㐘C׌Gl 8y-zOF0g %1K5TeHL't4_@PؤhD ЄBJӠ>IJM%|d/yudI0 `64_)Rq[rnolȌHt|〴rc&c^#qoO}+^iyW2+hcM,E]} PB-.6b;vB!/S&O! H5$?BS㟗/-mۨ#ݯ{Y#-ݲvdt湐;<'8]hZ^EDe<(W +CJfU8q=eJTť1%)Z%ZEZ% %]%+J6Su)RU¿Ԝ +y?ڠ[]FT\S US@qu:]oN:W)I_Χ&Dѳ&Z٣&Iŭ:[ŵDť^YXݩ\\ѩzS^UޓsAOEJX=a`nK%j: X-VV#Zwb_ őr–D9L-r--2-#v |w {*;*ÿ vEi!J5n' +b[{tȳnjѸL=M΄iOD ODLԒxɏM$0W$@ң>cc"nv13aOC k(?^GdKJ30M3&$;cC23Bx&f3ILHp#amLa]cg?V/֤ +hC;ڑuMDd w;N.6y ]e? ]Hr.S? Fy۷Xw]5Xy|'^[&RGCN`J4G<4fG=chͿ9 +| ?zL +n￟Ss +򍄮?4]i=C~aN@8 ΂sRhF&Qh)@sr= J`cL#kȵ8wN~!*E<=430J_řs)$QIQy<c|Ͽ/q|<zكqQt}#r4@30yۯ}LyȳgCx0M0.0*g4`\~bn0~[ \xnixNix^5|m H +GOg <ʾ_>{qwwwwwϋ44iҤMZԅ*(.EAf +:?E9Qska|J f15GԙbuTǨ*ηq?]{tK*_ 7}}07y#ғɛo3jN^ c|aϒg3wkߨJ +UKT~@e} skX>PB>7X[7߈'oyKYCfE~ZfLgRsrm'r9/0e`) +2Sy}dAE~Sr;~3񥑳VFƱ~FrWW?S*d[a cl&W yDFKAa=`>mq7NӸK̊gp#lȞ@ >v;P/MocWS2ftاZ^/n?OSwiN1iI`{eC[4n.q~N4ANt:5)2 Fph/^c|L.7Sl7 ̖WH|Aw9ՙ8kiP[Mqg-Cq*ǭ3pԺpM 4aM;bL`vl`ƢYl va똷s? +ǜVΩ֟S?[5KMqG]p% +\5{\ZڌmXtV,Ma&̻ +ۄ S +?'ݿL.w_^\rgaoԜӜb{x }BvtqoŷD[)n|[ō:q8;+Y(';!${P:t:+/Hy.'/Udnbp98J:$) .MʦeA vXpl4xD><- +^ -9 IVw Z]);Qv_Uv-zKI,9Ӊ䏣֠/#di('EHf"CeSɈTXxhxpx`xֺfex/|'bR1ةj8q^%^gu#i Z!WbyqI{2y@':@_׶8 1D\l$6R1IWEjDkwEWtFGEČ65lk9_sV&n꘧ 6E2zY2jYr=~Ȣ&=5&KdLXcf}UbF|j#EbƲœS\ ۉw|}yZ-h(uFMR,/-TeffXYY'wX' Y'X찊+8j[p2->!~XxLs&Pzg+1CR{oG\*3TW9SPWJ +õr+buʓ 2LKKՖqZXuULet˨G#Ko6(},\iX'fa?fVl9.URsVuV2Nz#6آM(hԇ3UIi5&15%Q5fխf55&a5یCkTdRap_ *?6 +87ej8/ȵw\C47(oaߪ6K9![Ho &F*ZU-QņaU!-ASA͋z͇/4=_G][6e rNM@;yXS2u= +d ɽHc{äQ=1dehwvpwN`wN@ww_ʷ{ҧw-+ +Wiy}tomxYybZ͝|݀@ꠀa=["z# 2tpg\5ܨ{ ܇dnC$.K׽$qĩ;c߯r6;C܍}ʳJQ ~_@1l?i_xO +1tm:G28O׉NSԨ`?5/خ+ج?{`9,߇7/oi4^ 3Arw0ZrPgO}ԾTpl +vpZpÂ`tX-r -0]X30ڼ NBw= oCgKD#Al$ww%7P{S.PS{mAK%S,xK0X +Rt2Z*R-K].CܵewvPnN50ibqwjƜMy] XQR'kRBr!] "Y's}YA 7(S{vs\9-$wv!EހQ8?5xE*Fk 3,ϲ 9K?j;;1p~FN_NQHd}XyMVOnn B(=i#`J}"[Xj e"ENw0`RNi춻7@oxd?RW5Bg?r:@2 E(] ,&W&ȏD'q}81 }=4gRybm*//yX~ț?\& ĝ.bwn.F2>or=OkvMе3)Σh·]JѦ +B)$Y}I?_b}5S9G*_BQN\r/Ϩu?ck0f5ԙa'^jCx{E*̻5N|r"!Wum3:KjOƇ!O39яax["Frm&62-xj/T/P?G,_yV~Lie(m?=\i GcK`L#Sl'qofs?Sy?x;u$/1i41:{1QL2=g&r-R/ I5bGoeBk/!%^c b\qv:c* O99jLNKAדkc|;ȳ1zpq(2#0n +N?6ׁall$re*QOI>܄!r F) >; afVbzvekA}p%o 9cȗJ\SE <]l~r k\3Z .?<reelL~"~#8>鍏Er{;N^8/48!+1y)(qXшm8+FW1=ZXڎ]ءՄK88bCF8`}Ek\5X2nNv0v!,L`F,.b>̛ǜ͘5{3/`ߘ -W9_(8gq?afÖv8`텽6XN4lŢm1V`m1o׉9~ڍb~6/`~7ń;܋1g1~%Ae\^@0 |؍˽ +{,\5]0nqSc[ޭn=w #°NaqOKI/IJ7|'zq'[)G}jqȧI|%c^YI6IAiiߝV'e-~5~.oX^+\#GcXpl 6`6SADP8!JKs}Ų +Yw`+E#k m7o7S4R_֪ ~\&MϔA?)U@u7K ,w'}nd%F#?[R$HR'i%%$e%&e'e%ug& 'm0NKft$9IR&I/$&~hqRUeGy)8~ 3|>NnmYJ4f.UٞbYV$3L #Z;7=Q7;= #-(-MmVcf6`>e4.IlyMB$:;蔫1)Wy1A!_smCqC5ƨ,EiP\+E2surR srMⳫLc[LcrLs&MrD09gsQXFaYeJ,Gγ̅BC|bz;6S(WDmB3b:H^RXWe]ThYXiQd^kV4aZ`Z ApѽA/A`ޯyˆwy[0獔J@%BQ6̐]*!_T&QT$iGVdꅗ臖T4WUVl اP~Fǿ^m}QSOɲm;F%JyM~ PXˑ`$5"WiF6DBUAye~]*1O&w^-Vx>yOQҽ{M:Ē{;1SEO7ZZ$"펈hDX{. l}sjW{³S>"so푺%qn}Vĩkcrdžgȷ.2ɻ lRrSotR} +#.O%z'I$EjS?$: +v}۾My+gѪ7q"y{{]پEIO3Sj} cpsӘ`?4،zM4Lƶx( Gnz _pݏ0MkQq]bFƩ͝6Ha= YsXl0 l< f37[ Zf;5;dB2}Cֿq} H&JM䜸,P .&w0 Mg.֛J Es(![ttbDeȆ]d qnD8 +v+lg3}~cj@mNmnGnС9j,BR量"l}\qm|7jWoD񺋺ج'yh gVk;Or:PtRS'xj(8F?:9B Nr'47b'hn~Eb#y|H&w9s8>8 +QO, jX_`zљY|\b{\$x  z3&Mg_"† ōmlƜxx p;8zF~m&(r@ ++`\!l<)X]a 'b́4 N0/2_n&wŁ$10MNjܱB\D'OhĊ9ϱ8}~W2^ezq'FE]g[Y7AtӝV%u.}LQ'Rm¿3I%z?cxcE^KSCL?./gݫPQZP7#Z8,$_Fn gdk+06^wc/iN~6s;q 570!9}[$9l-^F^D9ziuk0surs7w]wL| m8mBW2O!r<:oajt2^ yF3frm2Gr]pz5z /.\kVx fϙ/N&OyQIzr8L3F)l$q$9r ƗkJzKٞϖqy K4rGM*Yq~==8<ζ8}̊8r*؏l_K⻵[켾$ctbNDd\Mv+y:Ǩ3IYlX'4-3m-,^^zSܳJN5^i?3Vk1@hr%+1qTLN̍lEVّ$p;0+y3ҏA+exOӊ{'irqDꀃroSbViةvUʱUU-&,ڱYØYYy =I;08Ĩg1X[8fއfAO\&bͦ7Üi f*0cVifLua&1n>Qm8!o7Y~^ceeO\/s9Cwӟ]Rl2kxamfb0mvY+vUk}{~={xOhs|  -?- ^A?.OwqF˼f1 WF`5Citk\V#t5 ]n]B۠^hu,<z:WZ%5ҧ}W0.|ȥn_/^JLxc €w-x']bw]"zW>bO_R;.VV$"+}YVYwR߈e!X v/c2 ?=Bg.i 4HڀRYM@*YV#/A%AAAkV~UbYr^\r/'ng + CW]0!4XZ%MWCre!E +uhVIhVQh0tHY6 [TTeSeݫvF{!jg,D^ ] lb}/|tDmhF{UQ0:2FQȔWEjFjgGdEdFIڢ_7%nrݺIMU7)|Y^?8Rg;˿$> +': nBi(.XȍWfǦjgV6%%M%m֏ۧw^l]z1EǾ^L/z1zwj#ޗ~Hcc|>;fT"AURP/17%PHOQ&%k''e&&'U%5$uD'G%G&яH>t^XĿKXֿ)92T&k\O-+:SEYr@N'I 'gD)2cu"#3:2FC3B2vg ʸC70)uҾ HY/ eYf չ@ArMoW!%GLE*a!jZݠa:yKy'U~y|s}[wO:ޙ˺uy实gDUPByTh)#))Q;i +N;t¹]!p芁]W +lraU +Xtkf[ay7èOas39')skV 9ړy@ +uzՠ,a>0 h0E`;G\ u 8Y \<)iNw<ܼ1aY O?4/'yN:LMly6yh%w 4bQ[+9iP$a A",Oraa|# 3,ҏsgggΝggX㲯.g0xf$9MRr8C'.7]w&f6], f{ܣ9 >gٙw]r ]MBn*8cN䴠:)/ܶrڙkQ4{"s"җ'0xҗ)f7^${ xi5!w !ݴ%^΢M)qY>"J!ymNrE+ B:6$aN,FI f$ iǴSaLJ0!݌1FeG1,!X'{wѯZ?O7diϒӰُ|nNKJ-lb#6+0 +Ƭv4ft0)K#+)VHIqBR/IE&(“B!E*U`r* y@2KNM'wI*~Py'\(&S9('XgRddHEb9&DfҐ(YPf" 3C?@7R'Y;_5El{f{d,s|D-kZW{WX[D I QElj.,7FD +\\-߂xwA̫ _QP.s/hI] K] +$7I^r?:|/sȾ*?ziC9NJ@&K" W\R :egY^+H\r%NecYP#ڗMve[ҋ!X EߋVW%Ƚ@Ir3V֒W]HK\)a}jT1[ \j]\ 8F6 Y-Um-,k;a^; +00~FUC_#(9VU2"PR%M\KI=ضú-nhYK(L[baܚVB:-Ply7OCt7 AQ.꾄ǕH\GRj\Fu^ +=/bA#ŃpbYuPޔ&TSؽr8G=Ƃ 4S)7HHi NAcW5Bst5zKf* rڞʹ + +R.ٳPZYۙ\3o{I:r;s e0N+,9ƣ] rYD/W(b<‚1I0'$x"wS^ayk/_w-е(\oC4*yF9W,X46wӏw9VanhQ}g8{QFQ iKMB{h¿A}KFERQB5_/2a4I,tTOP_]h-95! |):N!rQQOg< {'Ӈdg]++v +]g0>XuέiW*xɓ'QLlz6} w~[1.H[eu~xs)2}L=+ӕ{`hAd;1>GzMPrB:9迚”;qf*ދTwϳ-7[IK|MX/+j啭5Ѐ07'A{W<9cťȆK*Km, ,TaT: Ānѫn,tàh5lBa' `4zC)TߎJ'Pa|ND{yK gYpՔi =f.2AỴbf44Zu娱Ce,Qa5r+fO6Y?Bkκ֟'bY|\Ypy|<W/}F9Zmdم.vɨD}>(ڡ,>P8|yNDž[lG,7LOL[d9lއe/uӗv@1mPJ%jx +E.BkZ)5 +9n]Bۈ>+f܏Gd%In?J\\dq5_XbDKox@&;GܪbIx(3!/bdnEc-Z K5+7_a#9Aκ|@N wx9ڳڏݒܨE]6Hڬ!qaiɦMzqY][?R4RDP[5_aY5|)rfjw.SW(fj?jscjsU7_/v\>.\tC~6p?k6(({w=/0JRö +'w(ca.5)@:bo( Q1;.6\ƹs g->"?K;J:LA80 Vu-QJ\r'k1fvymQ{9uF?ك!Ynbg#\<'996|A~,Ek+i"dN˱99x$O&[V9A?;䳋lDK4 +@(GrȝHwF#М\ ˵({I/&Y0 㚋sVor]8N+崱ᤑ;쯹N;ȿwmG쉜싰H?!pmr'[8ne1/\x.#wx=k0#+O?ڗW-p'?9i?=Jٴ]S~%b7A}a)&z[-nboͳw5wc͑_m'޷6έL9"c%E I Fٜ6 ȡJ|9iv8Bƨg+f?Әd|I\%Wn)T lB_#Flr0 $G=9Zi a[`3bǖç칟nLRj>Nowf)okϔ|rE'IXB!yJSMFz2.zlgtm̉ff~Ne5[$[y.=3,Q6R-Yϑ1y+O,ybr Eh_AK(:?nO#,>.9=, uѡcV]{4빣QzՏFA" Qi +bUBmԀ}E%lG!^DdLuȻevKܘG7vJ_dh45D͜QirCmdYdТeȳCU;!z֋Hᨶ9l$Y@|d>rnfޝCy_g[6:(1Ŷn(Em0"cl4d"þiHqGz$:nA!x-qU<ɸXy0VKɓ5&}/eI NwF=t0: 9YHr] +xJ!εIq&H1}~V sW u{^ q}F(wo#,E{X~u|\J[}"]HG=|$zD1bg/Fx^ PnI${${$F?$~^y~-Ezs@dRRE|/B |m(_O!_ C}cI_$_- tJF=$J<ߕx}%Ez5I`QGB"`%qB1A DxB#Q$oH;XR# mxKC7JBwK\COI\BC!:,ܓGsi='k/yD_K߸pzE"8 po(xFF  [d%J&:E ѳcԒuRC|`hdg3LJr&R(cJJ; +qpk&8 iCB`P)?:k[+"W"B$HpZ\kB[J'+PvM9i\ɲq9s{dιS;iRk\Sh\RE┲N#WűSkqꜤ H\1Ptgd,r,? +hqNLq.fQ](͞!6YuZyHje\bZ39A: +^GJPp3SAJ\;Q_O<ĭ仈S8}~4o',ȟ* >bOL_R#vO`0ζJ (]WEN7H(_d,kuj.MļI5&uŸI5)&DIW44&/"+((4"[h/#'2~u%m㒏d]BxO#_c?tަR1,uR/+e2JqliPB[Z@[(*@5AJ"}@e0!is:؉`GAтi*Mшa;,Y:tE3R8w{u{d;\;\[[HR# 2P֘]; v,!EJPV;ܨO,Yx3vgCFݻxd>K"֙LMv-Hi%Eáe4ý\KQwi!/d-X( }26N/G/1їK6t-mhoS!`'+5 DWzЃCUPC"E#4Ka0#c$vRۓ2'! #!#\oF#W#-yK1v*&Kr{J f$2!HXpxc D옆?u_J6 iTT2ɐdvs6dvx恁Ap- %*x2IIQ"JB\]<Գ9|~_,"{;Җ.X^_6^Wpk2]Rj!t_E% /Ɩψ/ec2^ Ȋ )>t%SJ놴;:tW>]dfK(C^~gZg>LM9Ml w4r JJyO;6)wk^UY교8ec)}=;Y},/&3*Nж5 << ${Vt9*yqA8~ڻ8 eP~QkV74W4$8FRb0Jm_n0^!w+wa4thP'} Fwڟ _'uHCq->`X0?Cw#}_b`ubWرc& (]d%<~7I9CWy~qY[0`F8uП,t7@w#t۠#؛4h!w`3yt,FLSABM_j/;Qa7kc{OE6ST1[ :dc{"1ϳokoX"c@MK EN֨c;Wj[0h# i2;a1;`hE|'F'CRf,C{ cUu@-CN`YGp<#80H! hq#0J(Eg;;K_^x'NuVNkʷ/B*Ru:[ +ƫK(1˚8F0'^al0QD뛢z;bEw;vv4c7?d)l)˘LY(K>Z ,?pBNXeQ +i N 0Jk^U2-iE "9یhh.aMHYeema@׾<׋zi x` +V4mHXR/-4 ^SiZJ;I>`Ls`|CQ<@˧Rkێ: ˑԋ43vt41YZ{Kq47fƱRb(&4[LQ&RXIޒg>Tr-&H\ɲX"$0rY|l'2S3R>GGZOJ-ͤXIRdU[YEJUԪ+ jeHuZIM ɲ =%nٍ9Rn$ۭ$rI"IOm +(R^"=i;҆ǥ<̅[I;IHCd;DKCd8Jc9JSSNK`Ip'u\gI'Nb\Ieq~3P`!tvH)z 4Ɩ%UO\%N\]%G\%5BI[]Irϔ|Q,qm$ֳx (Dx-҄{ՄzD.iB=ׄy(ӍWPHʐVG`K`gyՒz^N) ^"q(>i(Hƚ0ΚPњ` @5GWz?AФ +EAZ Mҟؒidu $1B$6U|$" H"$,0^XO j +.ij=]S#wjW~WзCW+}iJ-ĄJd8Ih P %k²4>ψi5n5|]Ї?},4A!IH(#US$ ]}'xDgL#&]qmqm/.9v8N!fo>8D;t5FH}$~,?|4=(^_ꘉw[LpoqKqNTqLbKl+I=&iX'MZ frL#uR+ &VW*@TmCCnIp_cz&RKS1CS.5TlRc:J"Hm%ݤF[b:ALRqʗbTo=-uoicV:P7ppsmr4,sζlW`)ىb!Fbq$zt_ͪ)$S8w/^{%5 H"B@3Y(m}益I8A L>TP_W@._0 4SAs!FWZ&J (EWă%>{C\yKqc4a1)f/f+f)f0ӱ(-"݁&&&BȘbBI_> ZP:v4m9"nڣ +nTDӂ<%~K&V Vb+Ѳu_WJ2|/P,] (I;zNg:k:Ñ F;t22vH_% q! btR*B  t5b?ZkJj:OH(Lp$==HzbG/L}tDwܽ/%SaN\v'.ݐ5U΃!Y">]UR`E(2;bǠ$^1;Ø\ab((-H`W(KҲN$L;t{pjˍz`puO&B":=G"6~?`R'ѨI(8d菷Hsq3|v]hs54bV_}?ZPj"3d6A\<6|̅ρ>,ZᤃvmA{m5Y Z5|@>YD,f|?`~F|~Np}/ Sˑ]D_|[&5޸bݯ-k&f+vle1 +RGngnCR@_X F{՟oZ空7j!Z6'$IB1w$O3Nѹ'7O,] x.؉۱cvlFh=;t/@T1FCX^Ew1=8ՓvN8$N84Fo %!yfIBF{\`{ xcj.Xb#$!NIcD8JSs u&z{Kp r".e9_s9)GGW +>ebOÖ$Wq!q.6,Q./a#!nI!AT=ډgO*ޞ}\*;㬸2'(I5!ycZE%RB쥶zHW{Gwoxo[!~Co'~_vq9#N>wnIIIGD ѼKۈoxxW@x{`kP5M b΀VGwO7 |3 d3qٙQvߐfAPmkL k)`*5Nj FPj";`G_+?bc `.>Q.>0FݏaC\ MpU>$)091Gl5k2ZMdQ8=FCxaI8!E o$U9 ֜>͞Y2JM~~B'0f/]\OPk810Vh[u^ڏE' ^}D$v 6N0O3Y7O+m D߇ܖ ǼL~L<i2Σtw3 }7dL-a[1t3lRwdZ:T |<) p +;ʒ};A`MelcvlŎر~Z3WqqR^]֥R{|~9w)2-Óv)[$-iA>肦/Ew[{IÆi˜E,+W"{ڳ' bU`|8gڢV#0jF|["_. \އQζ,#t/a4D'D3t>=̠W旅TZ١׾ on{t{;rg2>NeFɯ0b> ,!F{y5Wk:f1kHSPp269o cc ,p4v#9)f =3hUKQ; R+;P-NWns2-HC@R#Hlbt툊XO#Vwe].3}J`sԩm >T;M +@k?qғ1]R# YJ荖ڪLZӊhE$ZQ>Tjy*25Q>5A6{Ft;bG;Z/Ll3>U[C"ʭ+}ړwRji|F]3 8Fh@P^`!D1*I'UH6d7 p}G.Qu<~$Xz"ې.dm!c8hwG?*ؑO|4 >l,̤G$J%&Rz̖uvXAL=?M$Ug3 žFՠ]`9N{| ++ h8QDz2(gD1cYTbbD?Rٖ2ۙ%5iS HZ}l56l}sҳ i<%EOՖdIҏDdc! $֨D(niHZ tz.acKKa,L,%^M\ęHiDFKTD4KpfDB,ZKmnd9XjsS(>m~y(i`9κRpy=[jIZ֒hK.Vf,!"v:d*6oXl[mW$vn}*n(r]\mX?do4@($cO Ɩ{ 3; s@{O_PqoǺ-NݩTܜ;qv+Nγy;m;#bxM(=IД\$IFy."'h$D|]^<]\G]k[%{8G $vsX{̒Z}tKbX^3P|Sj/k rQLhDuW`WWJGHs!H x𜫟8}@- p/5C"(ÑR,*bS AT1PW^>FAw t50$CF[ٕ\CU,|V 5vv;ʈNIg3q e #Z{d!7g#)hJ (61;p͚TTj0mo;z!"~tjL)}xso2^DOHkE[!1 @{o}tSV^!N Î1~4}2EF*_ +>RWဝvXr1-իT큩TWJLc̤_fc,,9؜OaSr tg׮&o5}!UgrTuq3NEdcE>X-`+1wНdžvVbXT3D!+H0v72maADY"uiw$S"fJ7uY39UV?#VVu/AbIQ&r|QA4{y"s+ F|{Qr,9)qr +a n?d/Sbj3f#GWSas+W`xq48I`΢UilÎ-ر ;6bzX@YCЮҞEptzcmC CBrE=rH>#݌/6ው0u"HP/`)b'ڛm3}Дj̻xi䧮1KNbݦv +~s|nOt"Gw]tg5(hΖnFgL/Bw GRG2Yc <{X'`TNrùi> `$]!.TSa^Sv0&cړo#c2*%jvDiN7HxZT,G!A-%*ᅮLi7my^م\uEOmN7Cq:NB  CџGeqVEC㠥z{0%jga'H%SXuj.EHwapF< ;:bGhG[њhV;[*犉&Y1Q "U?o.2ډZhi`1BI9y4"RKB +PD^y+^:N%,rY1TLiGU#4&HR8pHoRFo>=SŒTg1JJc|1TyS7+L[,ӥ,, 34VXefK(8Qx dt>^)bIJN@a1>uxfxy]ۓTz dH!jKp>j1[pq@+)͖XuS}]F"ӵ73Fry"o?̮@YK,Gr=7R>X`,g/X` bQɧJ{ "&fL?Vy(`AZ4!D2ISxD\{Xc %ưD[IJKm 2@ 0L?k\">۸x )n@܌Nq?'nd8ogrd#)J݃e?碱'Yj$PBL$ZMML}ħFx׈/:i&yfQ".ɲ8Z{bgY[bkvNlkܖ!Nk;] (40>( Þڼzge$>VUVq*yOBRKCbM'p-AZSw)pRAj5wq5Y[~q>]!_B6$́AQ؄ 7+H$hs4|Qkn#%4Ffa2 %CiL(w Li mOPf0r02loWh꣫C{"ڤ7ϻ#nz+[0&&HsSc@ͱpX8^,9| +?=2L)nI[?]<9Ap"aVŵPmF&8&xcLdd.D.IC2%9anOL<6ޑRe?3Bt5($4D׭>jPhiLRG2 |Igp2ڌb݆T2Cz&lQꑢր";X/F$)>aL|–D^I(JS9l ||1Q̨>4w>=gJ#ڗ8(J9)U*u]!ѐ>)O4e4wmzkN#cx3>Pom lLR1+I4-VRj@mv壶)ApUj IzvĎ;:'=upw@q &!>\6ي +r7d'gtтlϰ|?]\MZ{R~J=ʅd >tnoBhУ "sU7~ 9I 8e>ى6[^*LEPI:3;2N᪻ lx\P o1W &IpH{'t v}JkƆ-}:UC㓉)c:1>)4dH9j6m3$ZnNx2LOz|PGX̀_D}L?"s%Y_.I;l?isji`jPĚWmGoݡX܏[C06戬kiPb ]쭶wD:ȴ7TRRu>f5mb^?gXN0*#Vwwp~.Gf0tX\c^#kH5Y&S Nrn܃w*qlUk pZrUr3P=OԻ0q"?;׭ -'g>DƾW?Sv`6ȠYπYkclq G~ %k-XRP*@sjPwal[mKlvב&_˱c)0ϙ>S ڏC:U^L;YuP@[P^LTk'-=+]/ë>c*gQ'"`;I2Л0.&lZK> xBم1YLm&/1~A* JzR{X yYbC;⇄;Quѝn><zF;z. $7, RV2̏JJ,ԖTC}: &eb\w$s$j$15;oYD `AG_bҋIꆶ.hשּׂX2z#esZNiav:Glag PρDIw^7_W8fb3vt_:2f:H+ĒҟE(;fmDF^TnLCiZ]g!.7v(q`$BЙ".UhnDIGF\yJ}C Hsn38 n7HH'&Xӊәȳos/x6*?RtVfjzP.0mA;#V~&%gSd +s%Gz<^[a +wsJmZi.Սt,|I|fh6#8nx3J z F&3ho "D*l)Z6Lw´^l[4Ib)[c#-w= Ao$uT)*`# d|J!-v9 ^[bB>~R@xԤ-`98 C #.I6RFSd{y>oމ|<]ug/J8(LSl/AFg&+ė1&oP=i'z1wz΍r!&5vGҁyў^Jek2,d&#qH$CIكskoS26OC3q7%nj*.l(NhXG (_lq2/V&cl4Z"RܔSG +9Qj/ +=Hɼ{\-PLı؛ڈb]#LjŋyXX䋙%#f/5NJl1X"^nP.  G?w^wGk=e VFRXZZ[Y-_a"ֱbbSOmꋡm۶=>cؒ7Y!kC`HW+ݵvGPh'|ਫx;#bg'6bec$&bjg.&v6bd,^b($GeGf'f'o'f"'VG>u(+3i4g] (Bネ';h^_j8 or!gt_A JnpwHۍ ~F>F" Nd,WW\gXR07]qg-vzRIO,@ ݌EN@yZ +U^| ^ S(ΛYr͊* sUڀ_ۋeBj#~jNnX#StP 9ĉmx<Fʋ.f)ؑERl'sEW.|3d.`H'kI#Melޕږ +Qj@}H.nGZZƱU-iHFzN>YRĄڄ_4Q6&Ne<}-IW΂Eވj@J@OƩ[X%!rKكSinnڋҷڽ(oj 0ǘY`ޅ qi{,DH?o+:Tھ=!߸'d{B>RhZPXO|la @e^ +._Bp>zm/u^٫n*82VbН&ȏA}yOo`hdbZ²f-k[{GgW7O/o_?ڡaQ1quKMKΩנaMK5oѲU6wةsn{ݧo5d#G 'M:mwf͞/ࣅ/ZϾr+WYnMn۾c=8xȱ'N>sW_KW^~ݻ_/gk+M6VJhlw>4<@iyH4>Qi} +Pڟ).hJ'UP*~8?b88c)c9C#*.D8eոe-cv♽k)9sN*98'8׊럕:T]߀Lf0NJ~uد;?7=ê%F&&AieU _ha;q#+Pҹ`z(CTڪMevէCG;ni3g͙.Z e@{#$t 4VLICi靻Dǽ4#ɓ/h^~m/InS>,`޴{ +6ZNq/WO|Yz嫧:i9jOWoooo۰?Cn6dv|x{V~ Sc6<^cþNa 1Ə'>ڐܩwaC Su67p@HG2/ϙz@߫X=c_qnҽUdOs0z<ڰf5ذ?j6;ݱ͚|Pz7o rɯjIw#S87nC+G(wpW~gNj]&=ݟg{ ?d{okmŚ!/}H%=9`f} =;WZ;=I)ո?t)e4y| o]=^w>0aYao 6 T^p[O;{>vӡw[{{؇[7~alxOodQȘ?-OE=:WAERȽ)we?5o9N?{^\k;]| p;ntC~m?+ ܯyx|SIy__=^컻//zٖ-':Y^_»{z^wvEZ s<ƙH y5`[n}Rkwx`юTt<6pىI;pz Zskg;+{^$,Yqd'.{ffkeҝcO3D}O? tGzivJ.\y;Ƚ/ R˟69o,t/6Z1B.YoH3O_ș[_ԎK|ֆʌ+s/|3tӜv;wA Vi׫EwRe+Ϳ, +ieٕH?-k<)-a\X-zÌW//vec9|_NI|:YŧS_6e3^1/g3  aC_mˆbØ OybG)? +˿!-P**6$[57 t6m ݿK:~~苧Osl˧8~rNo_ņ_6'[5'-ذΆUݾK+8b+;r+8 T hmh7ѪnKo0R:ğՆ-uކ [شO.ǎ+_nܳ5'<[~7L}GwԫrWFЏrѨ= ;R0҅:K}pۓ{vΡl}{߭Xu#Ms;w?ГSzox7f3i`K_.Z6ƫG]~:|ˠ[mv)Cnw?*ɝc__vv,\;~O EyO -!oܻfNyVـ Tݿm۷~zuo#n>n!W9y )y+*3[.>u[e=QA;uYqE:(]oE:"?Yc9~x獕qa+*RU&5[v?[$}RGli Vgo4&sZk^kT~a\fY:տrM~z*us,OНW?y⼱'/̞p铿9?usSf]:7us\>7}s3>|rKG,x6m6om86,梡~4cO~3wfNp~4gs_97c3|rO.WcaeETʵ镫KU8/}Cw_Y2ۏǞzo͝t;S΍33߽q7 oT[x/5am_:lX +ˆZcΓaYu7QG.|6W{vīNyjۧfϽsj;}p=DgCΆ@_8Պns}\6he#^X6_#{ty-pG={ l0.ުkoGY>o_>lK&?~8>ǻ}wع˨oc]uC]ڵ`C$QP{g^^_L3c8kǐ.C-f6C=k"]tllӝFiOujt?1k&gU0m^ C' 22A6N~A]Jl&!s2Sd$C?ݤl5Ҟf7ݒ4ߘ\\8{)?5o_Cyc[e*z.f)GefLfG3 3̇IS-dR]dDϕ81> Gduda;[\~;S"E1rLQ-Q6"Nd5f8.} *KX蹚LYʌ}vA*2d}2ubtRXrPPxe]Ld9IYȐ iȐ~N"&-c#>W.t>_>U:QP>ZX_Kh++xUE_ɲ[dO'{OM~^uolȾux!?MZrLBLllT\@\m[zW}HUtY:o>2=`><  (o!C7'zJͻ +1..†&rqrttld>i6:i&Up~LPFLPvlg7a*"PXgBbA~7g-SIVoJp|B#Sh? :T3S:S {l+Ρud^)'wsY17rUvIVw'WZ:y {x88m9Vz"5r=tvMS,CYJVZqBjUxJ_Jv]5fZflށ̿(amd+4G]š%O`Hy@&=G)W&W"_c^֍JVjZ(}YU!Z`r)o 5o/Z^`6{V'eR4"bT4P,ݭOvudytI\qBQ +J̨]̨ô6o? +NxRX4E#k :=4GBlPl/\4[Gꓦhh)(}:ػʻ{[n>r6m&Pp(ǯsgX`wexd8;Jc7VmL NeT(^yT4AiT"AqD:Qq8o(ۅ]8qe3w,0Jmf3wYVvK@i`ii)P))J9WMj?\yL< ࡠ+<Zuګ*I"YrM|Ml^]l^ %.:/RWu6 +7NNEÕp+b#ac/ 7Ȭ>0>3^ +p[ +[ +, D-qVҖ| +*; {g 1D C&[W\ 㮟4d5mcU0A+7s33 3 33OH#f ZgWRm)U; k!b! +B!o ࣗ4n=D,|ac[>Ft51o1m!F7X&4X5 2{22ZwD C'? b!"!Rc)\3MnҌqEѸ#rƱnҽi2d2d2DJjMkv 79758wD AGG \Ed@)?qwG!AkARHML]r{cj[Kj[kj[[j[HdCdHdyq-xz7qz3S!kU=f4>`ooY*C `Bp{&  ̊ƃǶiŹ>S\o[bOWbO US ?~$dHIuHQ0HSsYN ^HMM6̜7-irsu v{;yߗ뵳kHB I +mUAfS2 +Ñ^WVZ؁2BTO;?{}6$C"2HA:d3Ci%C-mFYP|)orԓfrzӪLRS_S_5 |""?bBև&(oP%t>KZ8-{S +|ա26գWlTSmo>\8靌kTؤohؤ_Pċ1N! Ȭ ]H=8 +Iz9*.#]jiquzigѨ{ۨ[qԨ;9r#.b#"r3$r+8jGA,2$_؏ A:2d +mR?-INwʙKztlT"ui6tz z; zU; dE$EFv ȏ @^- +)!Lu4G;D|q +yEfZvJ>J>*^ת^>jsԸ~䝵ɐ OA&-*?b~m#:Ӽu/KGq +YYӢ^[OhuBmnNZRMbMARMnڈ߇Aڅ}ds_e^*z30,1nXǹtZ(\fbV|raPrkr-r[I-6 NͶ >M&}E{rpճ гuL3MJPGd3{<:KZՖMMZMuֵfjbKdyKZIڃAŽ@yz>ǵUn<9nItÌR,(v\,&h'm-O)1iǗVo.3p.5/6 QRh0Ⱥg3RSsUnӌN3B~B viEzqTEs%Ap;\yl YMᖠܕT + M%I'd P`Èۘ#1G!b(I(jJcX]p`>gn_ZpM Kmq1'#|TUE8K H`Q+Hd @~G!9y.ǷAB*.FƑ :) n9_!4}N=*cN#1}Ni-!/#U 5{d !'Q䂮e'g/2d"ìFb2di!gC2 $!' +ʂN \,6Wm4- "Y$ֱ%jdhdhSf4(3Zj^QaI֠IYVYyVB]wr? ?2xs4x4[|CyIF/YҜ!)}FljRˋR+(vTKݤܗz/FAӒҜVb e2#C 2<>+ 8 5UrZP[tԉ|C2I5xe@̟ *ҍ*O.6*xa?hVC,k,o*ʯAp C2> 8Țn)9|#.kGq0J"f4˝w/ ,ԏ*4H)4)2/,(l.(j U*wgC 2_$ [JB>K~Zo g3^m&\' & &FMymz*ܲRTm7φ} aSY%ۏ!Z z sf/mIyfΥ/ *Ǎ+_dT>'R+lvԊJ|T}NŷlBPdA vv82$@i-6T/nDŽ*wʱtطz8f<݆R]gO.wȮ)B9fP) !C蓛1"S9=HUZO!$jэ~bʛ3`_:f];jWmUWUWY_YOEeҝ;迆@2~J, dEMjRně8ä O$bdSmzSSzSKzS6*ޘѐ B! ,( d 9Ȑěne*$x.ķN% 49V8带f&$\ӛv  ))!%Mؤ(ZQuyC{E0N̫ z];ݓ;ݓ;bS:SۣS[#-noh lL& Y8MUVo5_mlDvPo^R=,7?Tֺ>NHdD6Hޢs%W d4J+U,[˴˨ԌTHv~>}^މ=^I]>m;~'7 97b" +pKT5gUuƺm;ksKu)9>)6} =N~.>ɝn^); BG(d[a<b1Bfyx^i@ޯC9.^#;L̑jbeiAI K JKiI 'B!9oPWV4ǟˊ<!Mh})cUB'{ӥD(!V4Wٶ47YdZ-S[CQ!i BD?Ak}c>?bl x([  yYytN"fZ&:fjʬZzSrFYBzyܷ0d:!&J1σZ|zǹyZfD +qhGE ȥv >mn6 +v2R2Fj~INa603A^ ! Hum%ǵv˽c̴-BՋ|*L3ߊ9ſ8J{s;t:uu; +#uS5: +K˿D nHyX.aU}#/01U-g +'. p!MK1eiQ5zT^>ol,վbJOiηڈڍA<2$:| ݉?TFwxm/Vn:g6pH'msk~2zeo%woa\0ViT,^aT6?A+)*(Ҭ;tqWoYN 9U2<מ/Zes{60,7%*3 RAiJMJM[HOKOddHu|oXţEe݃xxO? J#%'*O>қH2Z,sX % $ CIˣTuPzl Z+waU4X 2;_s+O:!׀;=9ix$OԄᩆ6&.&.&.צ禸.Ǧ4JQ}S雵bXu.,wÒM88 /[p*,W$0{D YXS)Ђy (ov퉃`sgsL[@OR Ͷ4>YJ;Hy.K-KGeA˲Ԡes*jmc āL@RtMՑAc:;(eeQr%AkgUm`!0gd .~ +ʂʛnJe=Bd–d#×—×yaKJ5uS!Z-! 6` $N>k:˙lڮzW ]wXz'T9V9Q1>ѥ>dC+FG)p'Ix\vP}E8`I:s[o[pTB[طʅ115c:zMQ]M-M1 +'dpB{degnpW1Up1"iL}E0`Q2⭊c삢Obx‚RB‚rv‚JI+1.:o.iepdx +/^.N +Vh,G,({%+%+'&ϫReI/t j;kLj+Lcp9{ x' ++ x↓󪵎ߒiĂM¼{kдתIirӦR S:kRLSk̪ͪҊ̿g}z8#cgcOQ`)-7Rqdi``Z5mV5$cV-9cV0}X<˴hV^e^QjQY@Ȥ+2!+2! 2x=`6HQYR0y eU/ w!ĸi=G֨V|n^VQyVEyV,ȲkUF2˲#2;w.vo4?ĉIAf,`5R]˜^y.3]?203޴ZfYBͷ.ɥXfsH%ɤlpGdpC@{ܐ$.,1YAg1QuT׈yX#)…ZeTPn\XB,, + 2m + l Q Eqy +"ґZ +u-q+ v/ r((V o_҅7%xSEe G + )zA1& AVh@'?gJsN))}6x"cwD_T[" o $gJD_T(=/5hWq +I6K6 + +$:{{D4yf;e9f8R\\nιe + |!9cd9"8Y& Zi2E|u?rnldqgEe]I`Pqpf_fWV-#=ΕZn Οpi;<%´35bt/Z%J5JdhFd;Z$WESLB(զ*sJ'[ aw 9|WoW ܞj58>$mNnP +Tt/H#Ru,5}թRļ22rܲo>{w/2d??\xW&CCuN +0O?:e<|[au)TrB*+*3SMx3 pq +6IPPT4ʖȒ{LWT+.VhPtH{c7UF|9Aw5w B"],bRtS +# 54t1"GJO ./=]!/ FY%-9&"cRqcjcfq1r/¢^GNG75755- ?-ٺ4=cmx}e+y~:8總_LIM%'%h,29HeQ䋦`毶 vA4oad+Nm2HVh`fymf-ˏLXmT]x$g|gfff-}f]|^{j1 `orb=M٣X#y ݭ(xNT 6 ?#I{$ " ",Ve$QbbW{aiYJշV~ݾv4n=zGMM:]5F#LW,W|+bD"ϊ2{Uۂ{Ĝ냍9Oo"úr1+$8w4 >ÕGp.S;p_*?0njroqiqnksljoIim)hnmil5Y-ZO:J:0,cbM0|Nj g.[Zp"\fk\pS@'>w?|.Vg o ik(E5Xo uX}Z\"NG, k{JȠ'xd#%𻠳}I'! rPe$l m [wY/JZ[ YNG @q>g@WTQSiX0-h-m%j%g%o Um 7}k[첝y%o38DQZ` FȠ /:aan~UiU @J-fn%l))sNC:mT:m8.K;rO*ۏ(?WqZ`o/;Md~| @KR T @N-aj)j!....!V*Ve<42ԧ:ҩL~<md0xt̘L$x}P nٯHkbnkkkbd5B5\ǒL}RmDϭ0ޡѬw"!2^o9_Ŕ@V4,e,?✽?| W"U=oRn&xjyk4jj~-DѩcwX޿ vODVZ`lc`Awx/IX.+?7ۣת_PX +,ԏ`t<ܻ  +zoKo?h,S{#Z6,dV>9xF!/R}Јz[`vg`NGp^{H~{hA{h7l ")2]9 }`_~^tR]u, V.4,&CǕGGT)aCn&*ֈÖHqKdqK뽻` π˽Kp9!k+HL샿¢^㘑π}X;S=2]#=M,A9°9и)jenj V` K rBZR|0j4KzN2l7&5W&Wŗg'RPI q_ lkd8]: /@ |+'ƻ+{W|=cb^gM -3q/0I5NgPLkĚbmremremRe]ǰx7B,罵DAdqd$PzWE[yH5)>5-,$="%=XB"G"¬BkRk" ,I'D1^D۫Bq̯2e3"}I +j-fUz.&AΖq$H+߬0RnVMyVMyME2ݏTE%U~-CdBKB? f +B^SpTi tyDU(m`Do0gR.<>f_Bu+q+v-rp"-d[d>=x^ LܗQo7^{[(*LQ +%h:EGy[;9;:X;'X9lKve{, o߃ϥy$$3}~>OTա*Ge|R +EL2.!Q7$0-,:ӳ+H߻ȣ(Ե8ܹJt*X9g}-p@;dEK dSKT?fy8F 'O-KQI֍1J1 %R5] 4B rJ%T}C2kyGdG߾KCcYL?-r)P-g>:Jg~[l٭B 8j rW"`\xaőQS)I*5)i*zݻ^P󠰡EV7KS.XS; m  ll -hD~-pnG@O4gXi7aaްo9Hpo8sK?䃿8*3\O <tv)l8Q(I`zV152 1,/"$&2$+"Ҵ&"̬%"ļ5"ȼ5<м-߼=߬=K񞽠!(؝9 +WA_>F3qe2ձT͑UAZ.Ήf6< X?bY1ƛEl$DzZ{Z})dG/߁#wxpb%?&3. fHeŕF(r4MS]M,#ݬ]c,,[" !2|+mEq) _rx~ٜ!R,%A0ұ1r5tILLN1I!%Y'XHuS{,~>nˇ}@a*ٱB_: د2dHPR䕓T ##lC}Én$Cg's0YDžZTlPdl_`jgf ;?C>$94x!á?^,$g*Ħ*'H6f >vj>~))*UI$ Dm]x=dž/`i?/]"2;{:f6H/1WJ><CVtLVw5 Ҍ4Q +MTOPJGW*5ƪ6ƪ6<cݿX#^<{3,|4cew6ijCyjJARqBMW**KI.BMMK +!%cZ["Z"w#nyjثFN]A?6 Sx ̜.r)y 82x Q/Ո^eFiİ.t>z \^a6n#8p@U?I鋜p* \E=]4F? 7*^1K O{ԟ'g 0v GaqۥQ,N#3Թ{p-8 2ܽ7߃@"n^vanLD䄂Ue8X|H`VGI`}9lppzC7ϡ| y=\C[YuH |-``L>2،c֑v;B$8܍6'LAssKQ|*) >o*@O?ņs:~qG}w48,59G˙hp' +^FzG7K~%N@0)IA*BN@qbńg +~>\c=\*7.zym;٘g!c} +{%3Jė*/$ @Q +B٠(L Md/RB! >_^ M ^+M=?>{GxG6KK=#"c♨OIpC"ӒS5Hg#=#?߂%}Kߙ28<:]𖤷IoB' +}4ø> +e6\lꉘٴ#iKt\E\B% )R4Q\;=q\wFF$ǿ KyMLAlx24le i#>1C|%GeПP"JE40D0oǘ7딝kQ'Wd_>N{0UW;^oa@<7D @ C(@jWϕJ/rɄ1wғS /GW_n+83Xx4ms؃'W +ƽ,ܛh{IJ6$?+N~^?.. +@d BJ@\Fӗu*"}o#d$K9_Z|Pv8`h 0ΖJ|\%IS+&WL=X|)k$!W*@tJSo'mAw"ݮV%%cffO-(ݝTU#f[@͖ɚM)[k6YzfMډ+2Ԏf>|X_@"!V@UyU_[>'^ ot;o!bgm-ݔQZ.a*quXdƉGw1{ >99.ib|P" *СBͰԓwFu/9j:OYY&nevU(m${m8{M`ή mںsovnȽܞs Ӹk5dB 4)q8l&rȃ W+|  +19m:hEi^`ai[o^}WW^OwG-w5lʿޘ1vɸxa>*iNhU\_sf̘5){˓^Vm Rw$L4 dv7W6*>_YtjoUՅ7 H\CJ-aeo& 8Mq\o-r~`=+"7 S#1F;Szkڪ+JKG + +8TPzyj_Qɵ]%7:R98! œ =rFUX_bIfKSULo _90Пޕ^YےZTWϬZQ9Vr4f #U2+.0˯]/ m@2hg]fyRzts2G(gi]JDl\(#q0')-/ly|sh\u0`|AF+UW{ H5rA ;, 7kНytr NvBpܷ6:^=T\0V:E- oCCkKop翀 e #ެA@WvrÆ;Ko7;~p{X@frTjJɤ]N-mηnF {=fGL@&6|D&>6tsJcIk\5GZw'x7 ' 'lf'n+ސZ!|p}ئMaUPCZ}.bŽF8Xt,CwF2͊o9nE3󎪽g=͚OU#RDS$+W_F?TJؿ8}/۞lxRqEǕK9PU}t/?Ɋ6_@SYW6FAU/K~iȱgC339Agrrf +>t o +&'hۗVn-?ؿ{m9φVD+(<1kb%SAU}>Ĉ;ф;awbw~>yt98>'?&XB~/BpNli\eC_wJ ־3+~k2kkמaɞo"<&F˧4ޏDn!|}˯nn5cXQ'AsEsssfV9[9go. D(|2GQBKV?wXg8kmnǒGBw 9 λ5c-I|PJu8Q#-| l=iQfA܍F] `>uև0<]Zg0zB;lJ Ȋ@I!սA[ l,~€>uayVPg +}5*p\-` Vt@B+ +xCAX$<@Fm@M5PutNW \uOWDU4Y(ґm  /ɾ]m>u }Oz2נ [ W?· ?kI(ޒ#+!r@Q,^R]~v_iB!k#2EະA;Þ }B"Ka?'I?(G#~D\_I'%K($IBbxoˏ1DwWİ9'AGM^1ݐۡȷBo]%_ N%LwQ7~ʷQs;K\ws2":c.;1mRs:!%>.)3꟰bZˤ؋U"6ƞ{6\)CqǸ_v|fl~fl}N4 ).2ZM%++t}` =FlZJܸ3rIJSqJOұѤ#SI'9z;im&y[ԍԩp A- yJPXdVe2[g)2iEh5{hmb2vNdloJ?%JW &V&ZMz !bB@,)n(V*u/oğ4:ߩӺRjs(hv|4Ǝ܌- eٛr7$tceLN%]x6wUɯ󖧼Ny;Hy9y W9~թq~hyn!QFc}tYkS & '[SR&GS/J_ܟ7EQwڋ®i/<<))\P(ղM3OzMx _R=J0?鱳$&/=c[0YV:PޟSޗ'cCyWơ2f>-k|Vڜ)yRP"ulsml{s nckvh~u֩}c{vynS1.&.a:4[6Y](dꂐ5Sws/C( x^ֻ4ĺ zІw$v?^{v"+:Q;Zu|-Kg%$툈5!$l +ڕmUzioM |$^ +DljՍ܃ڷ-`EcmgO{uH>K=~8|x(3py8v|ݎ:k M +qZ{pr B c\on)2/i%wQ;嚛%튷+r@@ХPK1>"y][y}'-D׋ '"</b=Yw`'Ʊ]aCPSg:|OMRX?r z(q<un=]opyy7<M[x::w`B"4q +~7YP;^T^vYʬ$ +齹^{sN^NN>F}LvTd˨mvVsm-fl,{[3ط<v 7K8Gyb?=L:YE0[0d #(47f355&pX;mxCh^q ܇~cg~N +񅀌?(J<^k0T7 M6}сHm-Hր\-UTZ e8ח^7yP3 BB. .n2Rq-J`J२Dy49)(f,C2bzIvwG_Bw}OA,!?%p>Jh:KhȀ$X`qto)~ .HpR-;X}O~Pⵈ؝p VxL$ +좊-& bR &." j\#&bD D# +-j=OCW@T4l@CTB@ *:\ Jzܩ*C =Pm}z~B4b[]КmhKv`kҖ=]93RketSMhhF*(ZPo Ƹ!h5͘=} s }}z_AQAww%{\jʀ,+2軨^Q@7t@[AtGAo5f14Ø`x^gC0e 0M9\pSy 0R3uБ S%0wTS?0!k+0M  393mf`v o.Z<7]h2o` +Z+0k oD\N̕FY4dHKCo`^Tk`9`hՔO͘=V 6-^fGv`9c/3>ZpK|m%i ֪ NA@$_yv v{F:NOGl?\uyh+6/\+8s|} `o!No*'J ~ $oq_\>8pw~<6}Ǵkm<::c^7_yf MDlc0eQԑS9sN6b;W+|^Uϼ[ܟ?u{f]spfys&A/ ( A ( BЍ%i)zoÂ^0<d{ (}+FА |D8{pl[ScD> +a@mKw>Hb(9Z-U->p+y-$2 BHUf™^Qɰ5a[_!" #ͅ"-o\$m$""M/x މpq<* Yj: OG" + U&~L^ +5D`MYP&Vy<˝Vu˭|d T3GgGҙE)5Y)mΔAf{jf[vfKifSfcʻu)iK@,?L0z*nt29*_{k}tk46t ֛ґlM/mJokHͯKϯIߜ_~,2~~E܊7oi2+f., .6(Ajxгfnt ]guYrgƖ dj,!051],*̪).j/.Z^\0`q~-̋‚Ws 3df X6`r(Dѭ6vt::d̹wIlkt'lekPcLPWM\TsERRuq4? ,7";w"+wMyFkJ2r^ee,`2_1-.{VB-y^[(E@$!֯ BǰDh_cſjMvdnXupg@ Nev$$RrJȍMmeMc%[Ig Ú^^FV($W, İ]@,+q~{_Q=}цj,כsl[l^2ܥl;B#&0bR2=ya=mac[Cz2=!oC[5`b>B{w"tz/v]kڰ٪Vl5b/ֱCaQ4ѡ`>2FY62VAkM'M%؜<~&)pUR4BtB@2bsՌgw +&Vc-wl,_[p[U[FRPȰuqAJ5֏D_:oK|SF󛘣/0/{p؈кa=̋:65:b'YtU-뀷 c_C^WnRp.Z]E$ݍ>{B}l{e΅P-~FzMǢ{pU^O#O 6G3svg]tO{w {nڍwAp_P'0]<^ - b.e&`"o +ࢠ ~ +.q# J/<<<}xDh@ g/r=[1HꃢbI ГRSe+%n(! q1H"Y"*y?0nm"4[p~??~x@2& \/$bB -8W\k C #% +j# JzR o,6 ! DIx]. 1YZ( ;dA ,ޔg2 AA~#?B;(kI(ʀȺa@&T*]- ׋Y.xAq?<(]'r2+ + Sd1 JU\$hjH3V(SI +JJ܄Va%P]Yj[@}"h\Q͇5K‚6k7MP(iʟ!A $H4ȁ"h* LU,ԫVhf*nT]#*T~S7|EO>h*I J,( +!M 4S˨EqU4nfv@c-^bQ9h6WfLp zr`.-e pԕ{ qQ@EKEw9r/ z:>Y~Y;k3vΌ^wv~B'ߵf"`"%gIaTo- 47'9pOtYLb5F[^9p^neF ~] ;no.]w.`yθ +~#! +@`#6 +=4f<ݢM%?u3^aУg]a;^֛QWͯ<77؞x!R(j?"Io*Ee}÷oVK~}G;L~SO>?`pnۃmk߀5콑@88wϢGj 3LڞJq:r*Dp#AÄqun;O 3Ƕ-D>ӡ37`kĮ TaH\+Ec׋#Iv7⽔/RƧ")Gex+V;wgxmm&H.Z5$1߀qpsB;}ϒe{8[VtSIA{ch;(~[A%ȵ648E''NRWE'z25tyEC@4/89qrC 2Hc,aOy,/ +Xi]);&{$+@gOj6FzBZjzjj~ +Jjc +jwuyrT0mGdAdSdgdWDHpOd:s" +rsc.R +4gXlHId$g㊣jbbbzVtmvݦR[c~D5-Pq q=.1Gf|JFJN ρk+_+еtzGѭ5*VF +b|:3R[Rʼnu5I5ɕSɻK/%$N*I(NP58i'"Bo)G8]l`G'[,b/KqMmXU@iWgalHsNbtmVzBez^JYZyzIZSFQZ_FAڪig3iӲ>~LI%O hL[wnVao`AgZwH=]z[;l<&uì{ຢJE^JBQ63-7(YՕ";%ksvr fR)S?& 8!~j-v<9EЎ>m |dF;[C,:#]kc*"J★iyyىyyq#yysyGrbdreѳg1g> !|_B,/~B:ՎСh!KC]ӖvcMsoi}lxNMBljEJj\)3;4/)R2K.Ή,=Ȍ(Q tH9!3#3P9O <Ż\BGwؿVk%.[ӔtjUA&)cޱ#1!C ta<4O :@ C3' 8;(vMcKSb%ݕrN[ѧ\ɫ~!!ARV'&B&}W'51^#=HY<[<{xx+{tp+v~,ڣd`.'ԝq}ۂlClݜ9{Kזnoϭ[zxlFv^.kO]҄Љ># ݄{.@UYnjSYҏ:)k :iq0PN[6.Gv[;it蓵~6On=8(B;~Ch%vо=adcC);!_%Kq%Eߋn].9]9^J7t\jpUʘ:׮k\ձo~΁ɟ\}ی?`gJ‚bns")ЇuI<d(@Q'9ʖOk,)?7~\ Y'? CP_g~*y8?2BTOaFoF}F񽶈{c YkiY~I2>H~2 u׳bZsoD5,8wp|/c; Ts|)W}P[eAnA⧢O _ڿ4USL@La9^AO +>u[{"Tw + 8*7)B/n &ϣb|Z #Jʠ)$B`!$N"+($^H"^.hQG{I~p‹^w +ys^#dbġ,\| ' R/<|,̋ A74.fN1p~3/i7p=Oz[fĪkP5%[XyyΕmq8ap Q-1눃p[J8pŀ*°P8z{Dx&0kw p~B?1E~O@ )2 )z d.. $Ѣ"|W)M %BCB <."kAd C ~N$+,(S8b0/(' +2jb " + -R& ( 2+(GE@A$;D@3*ғ" ]dia)KЂ +?A<|/ @Y(MI4(zKB$(IB&XkAӃvX|Qy/b?U`-W.MY"AlF $0R@TdDAEN EA,zzc% Z2IHf/|JyFڝRttƤꮑQ.OG%?\xoP+y Lc}PPùZ"`ws0 +"`%f`$F? r r_>}0{o&7c+t[Uo˾6! 2,H?o1pn[?znKζ;1pup4eg'KeҌetWօ/4)=Rzl7n\Z9Tp^3W/ڃy{>g:g@O@KB̅EyWT~|uz1HC#$N9wnԫtiWҧ~uTjn4.ոvJmoOuî`tbt!.P%o!3A&}dx׼A׹♮wɳ@WYF3ޝ Nz6<C>W03g̷6oL={\ƿ (~F-"Ҁ~ ¥@Y(GXhc7prwM;Ym :o%ƠO6n:0p>/ +IWd{HA.{2"Pph~bBNBvbVbfbæ~ !+ׇL;Nt +9&ӪY_.+Be3`ۛفŲEIiz)ٜdԡX=Q"m7N3] ݦHI. Ұxj[%! ?g3lt>O7ؗ -KiCZ$xXB4.phɎό#TD&3ciIyItfzzfAzz-zzjz|tF%3O -bu;z!QeтgEbW`^nPY\dDeӘiyiFr #1m7!.ZB|o4F|Lb?"G bDXv.ۚy65ՌkIt[.H:̺VZB +'eВLF|VIrlVC2-79&k2)+¼Ġ0Gec2RӿSiic_ ]pMu).cN6O֖h߬rzXRIb 0#!* 92&9;T21`;#B|h9zxηw{`Ѕ=_B[aA+dH{_-{tCzU;%>RG%ЫTzxE^BhEuBHEg~z|:qpF&GYE}L13twwwC 0tw#H" +*kǚX>zf@9||\ǀh5׎8ќ9h&.zU[@/pL>e oe@ w`iOG^?<so X8{[Q=z7q]J+DfM:B9Yޣ]:9^c+=Ƕ8z}dZYC 鶯g;Q>45@>op.V==6BvyOMxODYxLXq','-&;&\'7:n2iSmn+p voE-7OE/^< $W7d<$sqWX6X,mZ'h:XpbLUUlW:L,~ $>X Va=;P^4xY*]ˊ+ +fB.WK̗)k}-)^/mycōaI_IrKk)e"Og,pr ފcgu $@,z`7h/NU~D+GJD rDE^ˈ6"RDC'H|R{R*l7js_~#R_j?Fk G ':W<M/uM"6MC1-iqPJ*SQcK)b"Q_^K ? +%~7j$İC"ƽbgY.;fDn]a@k˦D`JΛs&Da:DCV3BQA8h;wV/ͽe>2Oo+}תLUԯ֭7m$o.nBv$/MH]?"u'sOۿ?aO#vD-Q=dKԦCtĈ9ۡseOYDM𽻾kGnwo:_w̔T$wɹZsyN9"3.]O(pݪxuQ׳Jn+pSmݮDk҅hO cSt&b)Ƨ@%?ڬަ"z8I]u|zv£TGC4~<կkHsF=޻vyК𾡽wqFd1kLeABX4!J})C}Jϼd'rSoa8z| V7k5eh+hh3&C/?6Yo6'bũ^ H:m, lj9Fz&ZhP;Leo *Te1r,r$x>CV!ք^rz 򐷶Į+qz0 7hp- RXkDPÍq6sKׄ: +oqt\qyĠcĘcoĤӲSNK"8-(8/D@\(,D^jK Һí8G,H0Џ?Ə5uç릻wkOϹۣ<[58c{`=~+ _-5k(e8ك^ +i+Z+##n>5^ow﨣WAޛvܥzK7qqYL\ is&FeCYkDF Ԅ>sN0uU*nr:~1é֞CyÕVí܆ 0vYyX8+z:SgGسkb^j@8mRM͌^8tto<@cKۖD=,L3ެ<ޭ]҃4i˜oF-؇;:ЇLHE/u,OvMn?"rTtt?-/9tWtWt3ho*Bo:o)̿RoߐĹ`އSg@OԿWlomPH(6UH$Mh764 +qG>)IDp9wJe`ݣڶǵ(={ (Br6FQWQG QFh$IKX-8Sg@XK1okj?@&(tWP{D 1Fmg H"Ab%Fhb15CQ*I A%hZ.*nCD!~r # / .F +%*D M  Pq`-EyG)'[Uxb4P9P{8#RbDTN#Q"h/B^BD LГX$Rόٌswn_>[AkuW/& +>O]6GD 8aܕ ;D`:DJAKIQ"'%BE>%D2PDD&DTM2 .?[I{*?L{,HaA{o*}LW 2a_V&!2bDU\" +DGKh~Vsy+R%RJ*jZ9zF=wW3nj2~θsqM,-OzY>GODQD&f,b!&jL _ډ<y"|O?QAMbu5f˦?.c_4d7[>gE-N +!xa͉~s"ϜH5%,BPߒ$ ,(N\讹/"?[d.r&_mvub戝;n-~ԡ_C$:8xDbeݎ&@:q{?&qB!@#^Է2'n̫NBO;I$Jq)seAJ r{ur["?R~: ++S~Oqk7΍ BLqC_ +5_  M=m-x]}J%T›'qq}jԠEϖuԅmsk$[|TJ,J +<2RCffud- Z;$rPw+Jdi,j֥t6Y3[]jjKCL *"fŹ' *( ( +h -XR68p20b@`_y/8NY31|eȢVl׀vsFcHf? pDȊ ~hy~`pyePPna? _~_3ogWDxyxk>``Y̝DŽ8ߘVi..9jeڐX׷x5t{5 y6L4w=u!\*1_¼X; }/zuݲPӣG)#S.czbWAtgE8T_GOG9u,vriqΣ{'GL E4a/F!,h_Pۋ޷Oաߔo/&S^$п'ܧ;ڻ;ƫڳʣ{GsnNS&np~2w"t.|pmvEAY-B9ҥ Y28 GJQjxDz $d 4 ,uXخj-w@7w `{9GM;\jxۇ&wG~{'^ks/u@.Ugh4@Dh"TRldwė1"1o_v`~ @C's:揖?*"#:-5 '#O,B@}5߷D^?}~zL(&dYrg؂aM?CnxL#~+B(*2Ơ1hb fI 1c _"nCAZx/o3Mx ϐ74]U(<ƀ1c6GcZ`G)PK -;u՗ +^o ^6a;)U#cG 4gۀ' کOwL m7FgI+!;s3cu=}c ]'e_HdSf̣U Cm]=}V+{ٻ6''N UpV6Z1K"1E Z#P82๝0ܵ\3צ8e>j,]~ y"JE'kDw:6pPl2-N6;ot)>|T|:gRCNeV;AG";PI, +WGr\n?ܒfJov/^.3>[f";Ov[v-wwjVU܃K˹!fX{vGC"N<p}>]>T|V.٨gZb}]Dc>=84q9 `Yէm  r+W[韠?C?O׿D{&n:uѝ?;n^^+#z-~Dw:PsQ\r(IѡX\$W(k, I_<`ApaWpQgpѼV}ƭkMZ43i iRҤ.$ƈtPc ~/9{mM$Mps Y7K;:@cAd~gD4ְ"*&ưy aK,V[Նm;dUzݺ"Uy(, %e!1T/>cFE#{gJGʆj0aKwIJύo1mNlʴʷUfWYg_f_ؾʅe:%鳢 \9>A9 x9^9[86u{+nעG"Ҡ FԚ[Vy95|`ä8ǰlO~qׯxofc^]gYq + ǫ;_ ;4un:B܂{VnӥZ2fqihUIj ԉ3 cTȯs|jy5y5+k6ykízk^Aʉ[ٿX;|%ZHs;@\NQ(MiٝynIsc:B[L$ZZ2Z=[˝&^q0اzAg%Ek3Us7U@U@U@E@5E\P8\}/({Uz7I"oo9a u;QuP7c@NI=V /;3 ~FDY+:8` /pZ'4gGG}8Py+ gbqp0:#r?P3K⯆M܌VnN񦻍 &x/rMݷ؀7⽀yv服9'>y $ A[154sq H93ܠ +'z?&2y3ylocXBaeLi>C?w| օ(#f'?Z3)빇 +}e*赵kwA^?IǟG*Nd|e( #}؍py~ÛyCcPg00_tC +\Rzӌx.,Aj[EMC. s& 1Hc R +`1c ^CƐ3QPڊЉ_C 7Pmp[,1B2„&8"Ơ1X c 9f>jF-^*qE+OVOKB MEL” 4M/%Dn2eN1TFZ +Pcj,0kg،.I {c8K}?bV'NL(EAHDJA$T hvg OF0ܥM !PטepU Y.8' + ϛn8%rNG~?R>B+=D&2tJUaG%9 Y-CIsm .+RQpQ&eb8P'R+S#*J?mjO(eUʤ>A[ cj3k/=% +U((%e;8M9J9@=;zP?_Ϡǰ۰6i6ahx=}6?7?5~\gLXƄ=dDLa PNM}P pЂzč,!r^b7Pi\i!oro||t֨󶨴6y?SmET뿢%)~|_G&m PuXj&2Q7S' @qJZ\~FH_oljwk5k.jW=Ѯ]K*|t5jL"`P +1/Z.47$D-8ZkNpNs Ơ|2Z jT-71, eXxְ8aQ{YD0!xw~<qtHPDZw +U#8'2P1"B.<Π6,ո:,ۤ2tiEhiYhYIhYQhYaZН!̳C~3 +4+g#b/8?n{dɸL4=ʂT+fG +G%K!^[m\hV9â(2Ϫ0:?:7:;ff6imRXL 'Yj1LOdc f{ϐ3)2-piLMUH +-I0.ȍMɎɲˌ)ψvH!)z!!zC\ب[Qmc5bE,kx?܏q3 0ta(tj@[))^hvTe&O$#@ 5(;9rFR]j Ǥ| +N\|'&92~sxNaq mx,A؃3o8a}/~YY*4ˈVWhˮ*p(R(kd 1HioRR2%$2r?庣K$b$obvX"4*@]>̚YZ,ZX!=W5 H7)/46'&"+1$s&'(% s\?/s7sO5;ތ?xĖNlxir SqN@v hm4T@iQ(]2\[jQe\h_0ѷݞWֻ`ګ`gU \b鞃du80mU8hHS (u(h0f7ر2\Dg{DTkWE+}*2 ʫ-=+=*q+֛W5rjZˆSBsѿ\^<5U9y,d 25rZ`f%͒$3+#ѐfm7to2pkhsmXҰNӰWSEiZ_]տLmX <$}y| HҀ.jT@|NOIy~sCƨts:ԝ;*՜QuۣرVɡc}y۶?m|Qn!*VD'¦GB6E3 } ЊD-aBRyYKi~KK܄{x✞@iHYdYYr۞in)a ]ݗ,=7[YʴH'28T n P;c)@L@Z4ހx*wP\-NlA_!PaxLab!All,Á LXzu{2" Xyx?^?҅4] |50g=X*Q쩆ct1>]w,3Bˣi4R5VPƶRTGPTFP})N&ygcEf Ģ/@onV;@e4(T CP WىL"l mBm%olCAEۂ;5 -)zcm%~@} #@;ԣ&@9^.@Gq;ZCOGよAM؈^u:w{Q;PuQW S31p.pcx +.W~*6Ϙ]Uw\ ѵ>}9Yz0q?OKC /r pK7<<ƍ܈櫌&3+jN?:yy34 /5`M&.> 3&ys5= Ɯ?=p38ʘ24O{y`^!o92,!VLp ȒcA:Rutf距G¿%H5҈~ +kb[-#r COļ tPc$1iAc01o0$O0 5*=ԡN {P7/ad3f7: d;b ĕ0=cbAZ験'ԠN#f׊ZwS#؀malp7_A@ 10<Ơ1S> GHIF,,ԩ@ͨӎ:]Ӎ +n\m3+pJ?a5/4Uc>z_` {c0¼07ox!WgL?1V au O}ԶEkۈ `T܎҃1j(:J`&9d\m-e VV5۵{K춰 +.$|l\Ú9.1w^rEů'l$`eђ1Z+8*9V9U%S(S.͙-")Dl>gX'g\^vyV-$D2h7P/.|_>UFjÄA) ͍XM\MHurq+; 2dZ+d#Izu+WFdr%2xK}g\Qd0\Zvҿ <&S|CR?[b_7._y^\/IWl*6jx-Ju.Z^RZ*'˼n+xV."JŞDh/pp17}@ +#KyHR(*UR#jV 3#\!;W) P#$/\?77'՜kSalꑳ؄=g[Y}G.3?s2>gƿgPkm +dQKQ%r ZVmAOrt .W旆jJu=S 9eoX%[3 2333333';036)%ŴM92-iSzJmns"[뜴ܶ)mpkiA_Xf736n"F7C[~-#ZEb2 /,b^V9m%jw`'QHsCDGxdT쎙1{9IVǂ8Ǣ8R9f +8jX"cII=ytL:~ˈ0{s:{(R9?y" "Һh@I|х.JHb\L&K$TOĻH pDysn _G!wb|𦜆U8A[){TѹWk}ElBA,HhUcaC 8#==KD1 .w5"hs#D֏7DOAc?b$=Xxo6/C~ gn>EO2{0{=V7q=@^G ?? n 2 +lyCE1 +;}c0 (اOOd8]%݃Ƀ y=~t'ySv?~loG&7+߻Lt /~`ǯgdqQ3pL2b^l*^;΅AU<#@3L~$ЅQ]sw]bPt4G(mtzc砲n*{ &22|xW &Q@ +UVEc?9Bh.C3?P}nŧ +0TY`l^/~\m0,})b b1b!G\|"g2Pȯ{}`][AU,2W NcSHyvūtC,Dы$݄ϡgg7 b^Kڜa}O_Z*W=xZA qp̀co @~!^+\yȲ2zSGp[*н1Gie]]tN:#zN~A'ĿQ (pXp5>^TrMzkAO`&43n"[I^;stpN.)mth77:JG/˴sk g)mpMX0X`]6kt.Gy:cGKM-mȦ:l7Ff98wr?Yi6y+v oɎ/mb[`}1}ti-ut +sIvt+wuqo{vy wzL{,<]l"g#5#&# +'"*"uF#t#t"t"u"t{#u X=uְZketB ,{ D +kG6$Zs6')5cuFbbrbJ c {ccb:bfb[b7E6n~.~7d  |eu$8Mt$u~*aJ6Yl 2Oe4%Dc0)F/1ٰ;!Ӹ3=ܬ5μ%ͼ)ߢ!a¢.~EMEUIˊ-^,Ң$7Xƴ81Y||\CwރʯzgaL6GH@T'#R#-55ʹ)%Ǣ!ت.ʺ&ɦ*۶"yԶ,y$ymQ1ۂ{lM&7Uncf,>D?.̞܃Wae6O@4Zh(k7gg%dfZUfٕۖ;w8 9:椭9dqL쐞CZvi)ڦ0iɌ`ɂ=\|Baa]Xڄl\`͂݋^މ\v +L@g#[ uUKZU +CԳt,rlkK"kk;jG7n g\{RZEPU?[W2@#oƜ 8J܎zC]TmIEܼnAVT53B3#N/-8-<22B:bԺ,uI@9# %-6d{` +>Yp`Н( U)wȘ)}ȃ$ Nċ%i>㕚^C bu53nc\GSqIi;00/sx] 5M0L!ٚ7p$<`%(bbbbbiqVరS~ᔒ|y6?(YO3B)FjQaq?=;~^1dY(j wך*m7$6݅r췇p7mnOZo/ZmZnXl䘭rL׎52\} W.1\ ೸Sc{1w $Y2QN"u"DU$NdpށX9AKI@ ځ$]!ޛKRCwu\D U ۡ=^DΐVG?O@R"Ӛ;mJv94(BNc;4:8ǟ0@ܟx?>&F |]B'u>^e7qSп牴t` @x7Q|܃ {^! Ÿ2Xva< U̓Is }_7H\*!&0p=Q(z/$I$ 4|[72܏~aLN4Hao<< < DxXD/ɋ7oFǩ0GG{Dvf+o'x X Ђ=>g//)yglSDv&9^q' й? \a 3{0'ޏ> %{&b}/|+l 5_0y)@rWz9?0T@aNwhܿBgޢШ:A0}-T0? ?Ta +l €$poЙ6=1eCvK:J_@~F'H``Oa}4OCsKհ }?$cmmA۫u9w4 +qh7_`W 6N3))"-RdSHw@8Ezy ƣ#w?ߋM 3ޠ, +=8xfm #>aFWaֽ({eRȯE8w\' +~o-OdC]}g7 :/\)OzXۋ ᓛt9;Һ/g[w-[m(o/z6<;sY Ҕך҄A1sJ +=_ z[ϝp=ppy)rz'x[6_OV Eh_pV%*OI*'%uV1aYA}>iQ䪨K 6۪ QF DF#((t~زjҲԒ]yR`J2!ITGjb`px Qܩ<<U=xFF^Ơ4>ը E6Qa ǧO$"Xā_ +WH3rMDG"E$L|2ZV^1E𝺵GuîV=WnY-F* #^/B{?*{1R' B7;p?.P;6\#&N-&U%:G)H!Ҡ.Ѱ6˰:zذ2zΰ(@{uGZJԎSSTQ/*) +((O0M3OɱN)Ϯݾ)&{6:{&2{:"UXCoZd}gɘd)GΗb<<0^:h/#jP]>UWPy+O_!gEh$eYYGVDلY[.:e.-|4 oM2egs"gPUÙuXMTSˡ:-*z'N^RV](6L#:F7*024<"\Z9hT9gX8~}Sw c],ǓE}.`30zFfUm5MKiZUc#5"tB~}Y=:>'iy5Y{͟nՌ[:|@tXQu-D同}|JѥKJqx#aҮXTM\-r-&M> ubjnWU];^}رQwhb4X@XZs@pW($zX"(lĖG\9þH$<#(9: +`; ((z?Q{ Kw݈uN7?8]OY#2Hλwݘ`kDbCaQQ/8i>u{/O(^n*C^QOA<=nGr?Xv}v|wx\%yroUߜb+A +;#Opr7_^S< <лw<| |>6#7Pe` u +[vpC@;A=Я4H@ݢi'h~=P}_#YB྄__(Bq=Lo`666 xf*} ..z-|[kџܷ>7 +G})кA~@#NVpl^pC\@=H/_fg7DAwh#E^cXm^p/\(G8zeɋ'9gh}>Gr8+e3ʐ@MX-g(؝'HT:qvij4[EZ(nV ziztPZ:^%]Q( :QFai02Y AIGt ͑`dF#ti0Ҋz#]xֈ`Qsx!C:_T^]ngWjWga7l7o8>ql1/E0:(FЋd^?ul4[ږLMTi˩tg)KiZ٩qz))i&IEIfIfqIf1IQIM#'kQh¿B7 g B}%#1'40E[ZuCjt2ϊEyނ@լ0$Ä  +f>iU#{_0H?w?Yso1`'d"^'-DU eŚT\bF%bO~frja8 J;6?A?*/(9_zgye>vPns4BDFUeKUJ_ABE(<\=,N;4EOZcXZj_ڠ/)+-])=]rW_hh1:,}}R`Qx+_ Q _D`A O^d0.T$&kJj|kK|j4k4j'=j5jV?'r\Tq[ͱQw(e4X:U|஀\,h?Z"RLEQx-rm>|65Rٻ5AٚZZ+rmTqiSvn]:8%o~Vɮ3%ۆB:Fź>րY`wK7 y"U">m3#>{sxIn}|X%4%|%*]_߶wgӻgջkscǼSYAah1r#1 wMd3@VDx6lc2Dcd86OIwi k]6F  C!QYCA*r܋t/t>b`~ر~h@Ў@=:.ذ/u-b<Qs>T ^pZ%2+EG d(O@۞d?AB48 ^ Μ> Q}7h7ZAmFʗ `vGOi"Rb_(dgRx}xQGt?*&kupп>X#pKL!b +HNgY\$ҹL|ƾ Gy`< +pq 'PlL/a@^/Žޕ?{07B=D3F?΢ 8B0~ŁxhJ ÈD<L;{ I~Bȑy]h<vS $Z6/;Aچ'GV[^^ 5]Y/ϡ?Dq]݋xπ<,W39AsBi*OZo1C]x&3-}u>Hܷ0o"h'_'/ν9~+~%їMA~BhG;8za;- *-+8H7PC? 8~:Z;06BBTV/OW +KT H؂ѣ8eX8t;'3ĝ?@`8-ɞ$#  + : fD!7"7CnCt ŧS`l`Æ[MȎ^G# |G +b0-#G=Z0euFȈtu+>0S#{vO!7En^C,A,.#/.Rb:8Q +jp4Vtg#bhva>VohU6z @I~ ㊩^a*6-x=RS2:.v56ZB(2.Ǒoa|ChY8{Чꈿ0 cjbi2NKyK)vRiMCE\A*uB[DݴY4DS4fUwьQR&qwhT;QRk𽋩k,+,9'MCjڧOb[ڮN۴iY'%f ZϧyR5F6I~01E5AFi" =F}FoSwmPipX|nHg,}IGh>{`.زC_V-h3-ѬE(M[ҔU*MXeӸu!ZWЈM ۴ҠM/ ،RڮRA9O6Pfo8Mqnm> װĝx,ۣѼ1ӄ9qF8CNA NSϹ\vnv:wr;\m.3^>^Y^CxNW:pd*xK,(N{Q~>:+Ѥ>АCu{;=SYJmJ-^J^uJ^mJ ^:IAVAA)A5a"M7yLt8Rj+22dܛC>4gA=~N?o~T/R$I6HҔ$ʵbjIJYBңR&HEE])ݨȃwE<Nh/ڡaVh(h='?t$h; a[3lKRU6'[PI S)7I"NKLOIKӋӏ+3k06[ ;'N@:ѿhD1rB*0 =x?k%$KI +3L(?ӎ&kĥjGE$g%$'w%&oOޯ#I|C'#-[Z qu.c2W@"QF?{cߵ!Zɹ!EԘ+ph,WolV0mY7p-׽1gZ(V2 +Fp hwj=Qs(d_G*vs%9u:C'upl;96 \,eg Ǽc1!d~&ַIkb8 Wᝀ$D@K{@t?,d>hHVd2DF^d8DQ7B4;I<8AH( 'A+$~'NFsz*TpGwCy 9CCLrI}ZLӆ$")'Ny`JJXMeg +:'v' !F!F>EɘVK|_ځ<w|?rrwr]c{3 +-з[Plv/[lonEnϧ;0 >Ba _Ocj;)9rH^9"b L$܆p;Chc'.ر E.vN_@#;!nw@̮A~I6 R9 ~ {059c&s9R a t: +^"yŞ9ZEa聅(D~A=%xo3p?[*? fĺ>u@NkUc=r?DDʟ͹y•`mb=@?o@E< Ʃ0 NNjDfw8"wQܸ|2-l! +O}  v|F?A#T!yx; wy7+pObececw8L{W?!O~D+`cq8?@or_A$4B,-ٳ(GPnMA=Cmf^n+stާ'Poq[s/Cwˡ +N' 64/w?B~K%G8: !pi}ކ:{I/$4{sק:/)\(@t[o@t+/,f ֐I ǡE<|{,)6&V~;"l])҂G8F$vz}Ce8sC! W1~gdxO?+{^up| _ B*8r~1ty% ;˰.ڞ"5>L#$>}-CE`[ŶkW>8*tKzگG[pYduLGh7z}bi"Kqcg0>Q dß _5k +N{yO +(L:H(Uh=c7:rt'dbEe\K菭p 2l/-g;g;2JYr};PPK/n6J걉<ܸ ^g3_噤TᙡTTYTU'(jx +f9YiO +S?,Lvcɮ #|V"?sK @>?Թ>X}O ~T#qVyJ"~qBT|l<"*,L>tIQ߲(o((qQXD^(֓Qad| ʿU`C 6 @>PԂʥ'P/ +Q e%fe嫥ʼnAqq\VqL^qd9qDuqjaF-eT0}40 63aTaJEv7~N 3,H%-,B5%4NZZڡ:[#8zPȣ?q@ #(B4d0-ij"}q*Rn e:c)1*ѡqQQIQZQEZQZQmZҨ!Mu Iiuȇ>oÿ{1ޡ@s"(ZShD!e%Qz%&;r]+(>_+ RKߢ??KJ#!U7EnߩF3b( Q|G +I2t@P<=G)ZaJv W^dRXz4-\5 -N,IKUMIPJk{ yͪTqI}P)Mcw*'0j]9,k\@+JZ8(;( -15ERD59qy<_nOn+'E䑛[&rmRqSvΝ:8P~@6 MTFt\{ch*w"% +*ѡR3ڑoǫėQ"廕D +\JN%Yǒ}I]I/߶doSƳ*>ε,5/zc^ 4Oi.#0a'~e˟jE RpgBwȵPH%Iw[8S'ǡƟcWƵdpj5.i$ǤzU%IU/K0\bw\ M'k *\ pW@;űO͚dbL-dLf-dD-QdԒB-yRI:LXR aO )4"k#ObIO8px !BZ ]l{ϵGT;QxBb>ml:tb҃: "~zoc"`h\@gh^e *\U(GwE_h;AyA,TٿU l pƃ+<oٳ(uǭt{@o %/(0h_yMts{+Sbv㉿`nï@pFdz5_~v<;@9>;ʼEȪ#H܇*"w?XĽHKv[?!GlE =HV߅(Rvnk*0lNÊ+7,<:Kbh1 9a _p$ 0LJ쐟h8Khs =0aD'0$rd98Oq8ʝe/@tg.G@ +hx31-_Ea!q umkJNlbX?x"'#ق\XpBXp# +Ӵn%Op'3Yq F*Joߥ'MwMg;rDi”.?w%ʹ {StQA,:VĤl+q2_/2/G3j֌'4CƥAzMqx;rMg4kZmZk5810oK%),Ğg9>J[$d:)J&d~rf̔5jM5Asvܩ3ztEN],]\}}&}5I_km$ ws%U%^61@6Z^[=Kx:U+2?=LFӍ!KvbY= +}ii5[zZ-#N-)&JV:~QN8Tsi/Υf]ko>JwY~_t[xY2d ~kZM.kÚgh:5[M. N:kuµںܵҺɵܺϵ4kQYwz%/s.yK^^QQ $S3=#wނ*$mKaT_PR[PZ_V^^?߽8{a=_떝wkf+fiefx,Y6{*1H{KSQS_)2T滔Ըxx䕌z,򰖬*Yr{]S_rI)5'|]nC`(v@MUd2}H'TJ#^R_"5RUcҖX%չ΅ŮyUUn9UMU]U#UUkҪvVv1Wp6UrN|)焲\Jm %67eO%SE" i4nt)kDMaS.1`m,tjphhpMopMmrMir15vNnp)jC|=t1uk~t(rGWx +dx#H/ mo7HauINGdw5|}j{^>о`l_k߮m?n?l[&cmXӏF!t^,sV¿<(i}Qҗ(4MR_6XWkiǵ}+4}4}$J S%M@Mn]jqR"`] vyRG%n,Dbb$z$Qc1/c:(c86&cKotx#sF.}Iq|O<>x4;~v#`=G=P xǔOJTOʼnߴY|{HkcMܦejZX4GH7E3hG݈M.kWr/"m`w1:. +51B]K+e8 +薧v9r|ypreQCdN 3ld\D9tw#`.I__^E'\މq70oH@70m3ohulٰqDy:HZWDVa^b820e g,n hBb,8Yp .;c'NeᝎF݉#;Wd~;,6*ǭTћcߋA!cH7nR|&pq# ?7`){;syS8w@9Iϧl DF+;qAڹ+7ܘ"AS?XB(I]x\LAxxǁJ_>xegq be +R,RD +YUϬ(k/ygk"{Rɵ>; 7&7M}x &l _˺uO{M%Z8!EC:]b2&߿mPT@ I A~1X/p>}Q ?X5"n +ލ*mgC9?Cuhg)_$W_]1rk#`H\s}_M70}3̜Y{PSCRI̞ AD>!W]ab`Kp}\p_ϝ5Ke=ρx[(X`>!`qvM ü y' "o#Wo"' ӯwκ ~ u)52 N] +[wf츑8k0 bW/SK4c%C=}+hH'Ji9!M@=it/鯥0|&+0#"ÝO׋pOɘ_ۯڅ^T)u9)n?Q`%V>vQ`t c ѹޱֿݾ c/܍]xAV+{0YTznT$7/!O/p)`E1 +$KнZon=6riurZYc?beQǐuL p~z@/r)pg1ipVUhXa-sRKsYĈ|E^syH93a;ӫ3ӫhDS1rj YIMwi˴\«IIE4˘{/#}^]@:Aʌ<L q^Ŗ!/Y#=BҍKђ,eKb8YFJ, ,k +,;,rҏ2d=kHS攉eM;X?d 2 ~GNZJ5TRg5i]5Pn-v*V9[ ].a\딳պ9˺9#|'KUNiYw8d=m0go0gl9ۜo9ju=YO y>^;5{CJuaT&j +tن‚B +܂zAIΩۜS +80$nH{Jo}`h9mA.B>eEAv^k*QWHyKQY̬-[ eΖZVԲ~gsلlSRVCByzct1%OjE~g*9EۜO}%sPKAhc҄PWTT률fՄHNMd$i2jҵ59Ԛbڐ\bH5$,lԜLQ}& MX;t!e6}HpB<ie ؋[W-Rm+ޅ6e5)@Қ#$(MRs6P\mn4wkǴK5͛4M%R jEſ[MWm]~6PWc + +]>t) $b L.DvI 몗N E߹A|;w1jY<7ųl&[b|iCvuýD"$lOB$h N?%~E3X-s[s`@q% Ewh{m_E;CM68΄">Ud| #uQ\槊1L lR@xcQU0\sH"9`mkGbv9y.QA"s8/t"&ELX1.(4Vdq4dr:i\q|FdžTqNnNn>Dz.;ʜ< z]Q଀WX []ŤIf5j:jwVUꕐG'?`0$m  8Re Sp euA :N~ ~s(\Vҩ6;.٪l=6C7A$7Qn_ot"|#-ĻaR/!k=OcPAvan؃{CO x?~d?O,cɉp=ݯid r)"27ܰコI8)bч({R.DS]H~\D~\Lp1q1pxbq1F_ N&<9q{YY&k._0Ecef/%ze3k"@`?oӝ$'Q~_ᅱr~ " 7he +*쵐kf!7#B|&2G܏p2 ,Xi%Lg3DpC"*Z* ]ٻgܧQB$O"KK4K8=ӎ5bp< `ܤ{c>rfigU6y I:WK羸7fEI3\Gpe_~ SPXʧa3p>G¾KM¼Sw<#S3k /aEr8N^ +^ZcD)_s[.ck*v #{ 93rşP`YMb5x\9x;=Ŏ8@}F|?I|/-g9(3gQne÷w _N<)ĮA;Na]q;V6x3&:I:u ^÷OjZ{@uƇ)f V=`J+W ьNc5qB݇qrre%?QzMn $dZ9PՇat{]ˆg@?@k?rߔgƧۯj׻UݒvB0pє +Dro1b*Df&KbDwL5-Dw.}:PË<9\4U`ԃ +F`lo`r]ϻkrJgEYw9Xn;1ܢGiAΦoB' V&8S R#8mc 3ȌU) 4Y$'#"#xճ@1sfZQaVf/|JC +*ZAO?'Ɖ|##d0=hd@Xy %L1O3(1xo^`ƀ ^LkdJ["*5|}ȨaXF 2dX& o-CmJ: K i7%mӈMP Eazَldx_M{aRWgY+Ӯ2fqT-c2Y.^28YvIA;!sJi-އyqi{yZ漋|+^6aL{( 7+e!%HjL^¶Iʁ O,#12, ̕j~i '1xR|T.AOJYwM3)5PFR){OlPWްHOΈTi̖Bi,:ijRF*KYRuE&K^ۚ4y6M^Ms38(p?,YL( ^?+[cC5.NM!y:cX66i*]r㰦Ը@[l\-4n/fߢ͌{L6#[mFMm݀G;X(w)5V0OR_$uhKHK4&I}rԚڔ4ekMRS\+2 +<.Ǽ\eޢ0.ե%N֔O):sMo6$9Dw}:yL@U^~LžFޯKs4Lx)5ELm%Og)ZjVK!gȰק[S-f~]r%u ihSƧKo&8j&5 H 5^ Wd9Ii[C#y$M5]m2zʐfm6Z{ f>ٺDhݨ7ZǴ7iDe].bGWl͆ +YbЂiC\s\ rLǑSKib >ꏩc-gyr:\ B3(BӨc O ȑ3?vXAuTA|A<XGtχ/o,o@Y]}(u 1u oV[} +.|3ʝǎױ2vy< {~qs?DYPnUsͬ{0u8 S+/,gQ؂.Ұ?FH t+%Yu6Ca͕t?;tw^zL җ5E @=[Ea\}+л~qXs] Y`; D&*_uF}qr}Cv.Zq'YL|vծ~rb!FS20( + m-fħ7#sR֓7~{s{@nWc/UC+8C<8fpМ/[j0hE7dLJd9. KȌDyD};sN]>NC{ӓ<'(|I' ۳) 0 0`B$qΣELj(7"!? 6<.s_Ie˰v15+Zb +V,XcfOn& !9@/zp=E{t1uo}`_ǰ~)9LYJn*سXxPe:I~K +(`G xU2H >zyOway}~#I" :argJvL;6 +=My4NN2+c`Eː>I id^Bv..ZpivniufB\H~q=&U.'ҙQ5)sa!ߣXMyLy#L78"~.^9,s3;OZK٧Z}S|wR|WH)/%Ǥ&)~H澁|@JDZvPtKK`4&IcP[6Pj+*^*Cڥ<_JCƥ8dl%'d?%u( 03Rg1%82tĦ)]."Bj"RiL)ʓҨR))yD7HF^I:"Q79AI+f\lGQV#Rgjb*G*B,>VJⓥ(>] +VMHkXM,c&8I7.Ҥk=dE5qh^~9i/S)P dM2{~"V{UHYNJ09HMQkJ)Eed +S6ܠM1wjMamyZ`^7Ě.DD&^"|H`m"^"N]L=Ln= aՃC=|@vC޺W]TI,ܿ vZ6Չ4"U]lhb +-E$ |TzAqOp0hcsh_ӌ@d78"1w#mH=S׀:muS$8dXL0O2-`RbV[}Ft)䕎}_,iF%҃ 5H>gs2_7\y"9E  +2X;V9aMcw Z9t\B{ ˩|*'!iˡV|67pii Y{Rhʹo۳MӨq)b04on^+gzIx~+Az`v^3!&g +aA&qw:< +8{s/^95Hx]~@?7υU$uɴ?87T_>Ac*Sÿ z|ݰٰG/U ~&"x^OsX wȏuOH0 9VK|"`SF/*v/`dzء1aoU4kuHs=棵հ1%;J &@ve\]Er;{/)J7p|#X0t:Vp +)iv0z=JL2l~駇bo}Vro:Vbx?ăc NH9ׂLVtwL:K6HN&M:/f%/g8=OgWr~_dIb1._ $ +VUrx `WBZF7zZVVNvUO(+?#69eE9(9ߣ>=C:=hǿp-t|W(͚riJE=R*BԮrN)bqv~~C pC9wP#k=EY$Ns)H%A\R5SjƭDܫ½Yݻ}DJZs)9%jr[2]{bq7?O˕L炷te(LAB6Jʑfl* s|vnT{JOTKUJ}دR +%߯Sr7-Y~k$ob9%I>/"KmKux{`).~oh:lŖ@TΕ ) ) N, ɗrvJZI ]-zP!WK\}(6Yl!bt iZʏJޫ3)pɋ 8ɎL(dDJzTEJJt%)zB+%.,:_KD]򑄅P`N)k@H3RTZi>!9q.#!bDI1ɘ-"MJc46k⌽DKqHpw=+J@c6toZПD  +)E +%Y/^b6J)BL`6K9Sbhs&( 3ϓ2 4oykBg+N9o))tL ),A244$IOb-c$H\ (z QX"r_&is[6٧\W"S{pJ(t1d!"IYԼpD̕ ɉ榈nOnmaqY(.9)gGE<@ Qd)ڌDn5~$p(EʠjLYmڇ$]ħ8TNJWqxg[qWSQE[q(Q4R0;û `h`ՄU#yH& +vt)Z FΩpʹ\$HWE[*JcK%Ĺ\XxF9rI"%⯱G l^\x7~#v21`A+DD\kD[gis5Б +xYC뙉dJ5uĆʟeS^ +VYă^ >jn pfK <-бAGaەe|qG akP4Q6N +pMKa,V!Y >ިtpO|ٱKv ~O{CdPAz&CiY0m: 5d|2;\.S8_dabŎy|b8 Eه--ES +>Ƕs{ +."±3LaB%رXΠF^e,T.&/A>I@E?Յ45*N1PpE橘>EʱeZpPl8~+VyriMuXx~/uF|.,LNpM6,T1g_fEzz1K!vccc+?zCNUZhnYa]8/NTM*YPZ}}\J!vyz)А.Pš}&YYLNqp'mt[q6bqJLJo~@7]]%wzR<7֞ 3wޯʽ ,Ӵsthgpy!Lz}0b8y5g6kOȩzH\}1iȋwxXڟ kgB|^uoݿK+PD'I,$074/a<5k L(O|I93jO߆ kx/Tbr7IF$#q!>[ЮeqՆ_w:ؾA7aa`% \0JaεfBIh`,yL[i4a +Hӧiwo\P! ?`>P2>bq/ɝ۰츙xHz=;N`q㹬m`=hyzBY? Uf1u vv$'7E>kh㿞E%eC.Ǝ#q!v?d<}bMu {PjWy~?#Ж~+ _5`4цpȄ^ޅ}XGO]fxUſE> ^FoE}fXcv8'K2ĖM~`<*Zt[i0JmdD/|}n<,Ea>L=#CEи]֪rqc9x0Bpd~;B~ g]݇aGNc.*zuT ,-?& 9: yXEvJ =oXQNDNH^ȿ&?mPv7{?nSeyC~v&]I.`eGO-iþ*SxTN{۳ +Z)=bFbZ)!6U Ӕc\<¦NbzJ7Z|%/U,~ْW(bodIxYϑ$V }\}ޖor~n߼pBc :{d /JZpċ9$!/  ]:*%,t-!-|+~6ُ_ 戲M j)@rx=+g".H?I JtΑR EA|w1Y<"7# ُC4XЂvJ:)S]|$6ƹH\I1R"F 7H1[BEdc8-^un#G%8Q S '֫Dw%p xum!YH:bFqId<%/!0 ¸s37@͕ens'ټJ杢5Q '3*'y)>M$y`tFep!bMV~\HCY} +IH`Y|'#XfDWFxd[fdSF3Ek Y(-̆iީ)pޔp?(aR,$ 1!F#MPhIs57@sŐ'\hs3)!ҹSm|NF#.#Hkə5p@T@ݡR&r +J*VP5V;.4u\P adfEKΟeYrc/P-> ӈϑ S~9L25Lj"ZLhd0k7XĢ/5): cIĬN4 9R5 $>;AeZwT=&JX1ٵ3w2u+be1۱ SC~Ķ *G +=K]O-\9S3e=u;86:2Fɉar0qG>"C͜Wwфc媟fCeyf253k :$-wfx>z0J x9}yLߪ^܃rլ8gݡy;sy~'P_~a;ggxro猻Hf*g}.m4Hī4΋Y}Ͽ<ܬyͬ5}?b (é>J c+şe: vѦn(4ihA1WIZԣt"M(8,g։KaGI*V z:'Ϫi|vד% +IDIa].&?.q] ;<<sc?{PwcNn+ &ѿ J`ED$VYN.eB[^ī|{=:W1}9m{1u:,RPX9ǣߌ~ sd +;`$v.iyQӃXۏGxC&u{z=`+{0z8#Kթqh A xj#Cc;OjN'Lo +i!Ml#n` kdh is,V|K~eCF"H)dy.XE`UP^ա~~ǪRE V{!Alv\m-ϔݯ,JN^16i"7$VXyF xU5Qv,ftgOwZ(B+|,%BVET3,v[i7bȻM7BM*^rR凜ETg]op\XLCX ɒ.N9T,&IrnwXC"K5O´?>ʝ ," 3w068hk9MY|.I2=%_R=B%#FL&^V1zKWxIנϙ9k%kx]$~׉}|'  =8AJRX;y?R|5bud_oI _KY$ҿP$4E% `RV.P<7UqTܼ>XQր)P"[?34^3^ )!&1,! +͗ + m^:!+5,q=(E|JA/.#2۲`5jPFYX{IG̼#HdV#$$G%0*J7:MsdntxF7[tD!z袷&0)n,<+#[٤\Xm5 +}A,H +'!H4kPۀ8g5z1@3!NL⚐% EIEcT. Xxx~GaK +?L~'xGs,ZD"!F(wAEN_$ߓ,/Tӛ:TSD}$UüEýIrAe|dگg`Q~̜L}KsO?G|Bd;vN+t֗4ϓϒDOagQ<;?WϞU .P}|zeb"\yb\9Scǣ0`c8EL`q+v(O۸$Nr^ëW|o_8ftg;_]R-߁}`2tN3g\zaKLڟr8KfpF\t!]Ft;r E8TN;t1waLO(OUbs Ճ 3?ueʿzCtC/DyOE&H`B-8B0nn,;´{<buuj+)bBFSS0$O;:vi'?Z6i:妐zZ?:mkm6 +HHKwwtw Rݍ XƂٿ{]{_H#L<;aɌ2E"-di. eA6 (D9G+@p'#SNԄ[lAlXW±06 ;6 M'"$(\7! ɏ#PȝemDYL(k'ڋX/;eoš`Em[^E,I;Xpe!!`i63tŴPEa?u'~ڂXVnP&ԉeBKGyl( ,qb7NlU۱אC:m G5&ܶb}lŶ9cnLեb S-?Bp{Shˉk}PML;()P(D!OlF8ʹc aOG5غGgW&~&Bz(O Us)Co % -f%s1FL0&h[h9M'FZQb@E VӺ+iCS*Tr۾(BYrֿ/6>ػCTN}%m"yRijbˊ Ħ[  +VpkV+W*WKVZt+ +jErAEp]6K}#a xHkN/+b/{b;oEl^KI0!6]Ag 7kw+x :b1A`JP2`̀583F'gD: uU!B'7έ}a8{ٍؾnfψX@MٸXɸXXL,XIPo:IP2J,2s̈Gn@. '@CQW s{Ń`E`ض؂z*bV:iii Aż` Yhftؙ0 bBG3քnB;l|DXB3U=/Vb7bl6 z˶Q4;h ؐwbBr% va\Gf'y;qށw f7"-_synI 9CxAyF^{v.*j\gهܿ~]sA`}8Qp/:,L\fWRFY۱?`hvqeFlP&:^F*> Ɗ1alT sI<"#80h:! TN9+r؏޶P26>ޅl x[9-V7Ivc'i@Î˽~2IaLÃ4(^4%@'&iuC"XN„؈k plI9>d]b"%8I5CB8 (|8CaE0'L?!Uべv&V`ARENbs0ir^ D4ViT4>7eҏb BԃźF?uf[ƶr[\'L 'nd?kRdPEy5d5TBkn +<!l2@H]ͭaCI3#zãCEtfPlH&C,3Ϡc&zwS=m7VEȺJ"S(z%L%!-t鈕ꀶCl>p̶vi +rDϝA:)W/2 k.roG ҃NΝM lNA3|uށ:C)E'׳Z~]3u4'cP@>/Gq 8{Ķ!5w1#\l?/u/&׽*NKG˱a\gr "{&37JKܿA~}>ʃ JڌaC*\JHGwX4 ǟg*ȟ礶f9~[p^`+!S{8XgFqg>v6+o +#~ۨ ibr#a)́T}gP#? y-ěٿt<zѣ q1Az>2| XmXqMhzc{(rtkr9mtxK5ވ s'DmȣWcHy "GFyAXeL:?~= S'i2Eڮ_hqAYX/8xϞ!VWFjD"#XΣ(6?%Og$.= <5q2ͿEn.ā؃֝ۋ<"p GG 3i>%0?W-w q]aAa2_jY瓛~̿uK"=d#ގ a9qc7G c8Ƞ ee( 1F9(.xr՟=ɩh{ƺc?Gg0J +۩F8fۇxxGUٝ::JSŖrrdaׁ< "]`@lF=c{X6;D+ 91'sN J`O@C*^$T: Da٫Q6ߏ0ch,_{8nZq{}={!?/y-EAH%1e7c۰2Ϯ88IA:Вǰ9P=Xl8pl8flj"LvQ }G[:~CAG9[Pv:2.,[[-i=dhCV{ tb?Ǩ.#$ᬋ8ncc`q0CVbAY\:N䈝"w`> [xV{R !'JJ!^{ Q%b1YXz1,Fń#.,o?bDzQ FKc\q"@#!NvOHK-\Cxo~f'%5ʢEYkPzdmGy,{2CZ:n7"֢'f"PE,4)<-'pp#-r2?ć >(S LJ( ؃XRJm\h3i [h1t<\8yb٤ۆiǎ.\m!AJr;hEY1l@ +ȟ@9Bly<%EͥH9hUX!`'O\`?,i))2V*_V"=| l7$1pG/R ('Vڋ6A8ĬH~r!_d@ڋX'؈ P%]4qRA3{b9tYϖ#9/!&k}9Kk36NvGm1%a0B~ n(dE[o' XKWY{rL?kA^GIVl^+N;h磨3 1#LH 9'QO~)1c8}XhHh,"l&nB79j'\FrM> 29"'WA?Ce\>EZQPQ/ZLKdZf-ú7mļm]{X;pcǹyxO >%"&.!uZZFN^AQYEU]CSKGWO/ 0(lhXxDdظĤԴ̬으ںƦֶή }/]zm[w{0^|?}0~$iH*/CWG7B{;*~Q$H$E$ ȒL6P#Ad4 $CAK8Lᆶ"ßd49=IG$LAI.d24K.$ôe:H%f3Byn}n t-d$A#} Y L3?ȞyTSP1ۋF,C;,]l9⏕+W5֬E{0Cl؈6AU,h4 2_3k4+aOR3021wtq OLNMB-Uը䬎QqNY%IZ'*Ǩg7oޢ?|F?}W33?śt(ac"]P*t %EEAgݷ&/,vZ7m=;pJ +J~7~s7~sX0p(F џ߻>_ ~o|ФtjȬvEn+g&[띟UzOSC)r(FȡYBG~UCZ//N]/dzi|fif9C N:U\YvhPNPʽٿt ,™=POUrU~{ހa_rɥN뾭Vw)̡m-qid|u)Y +AՒokWkW6w7 6谸Oe(9T +_[xrGJ ik{-U~E>n{ =fcP*B%f%x(߽J7JYoySvO-3Fq5Q&N>> +@UȡmL=ַ}'Mx.tiZҪO3Ũye4j6vRݺj-?.N4JA SᛘgIg?x鼗|V5]*:b/ pxW:@:g_ L ~Ẍ[k~U&mM^髒?^:btj99sI%0da?k vlḌ 驂2+<ȚɁ?0RC%J\; [OB"kBbwϳ7Di~x~Sǭ2B;⢞?OMzwydk!v(8b|$#?ӪbCsa.']V5lnbdqzӢc_F$< bV*#SKt~#W/tok[P,!+UdtCA=CZKǛK:OM֍vY thuV46EPVӿ CmPEyvP4~;7Ʈ^6j3*ﲼj{'IH'I.f9 |w*h'% jh^[ba2li4)t |XGޜ&]L{ +dV-P+3ר2[մN7Vޙ^w9/u QS2퓔[٠g +Q+[U6ºѽ]u˰H3P@EM]>B7sclu/\'SA(Ӟ|SƏ&j=L֘KQ2YEONo{{\xDZ@ +ځ lMaA\ !CU_jVx߶haRG&1^%Wе!SQkov_O;j|uVIM铺Gmeč4XV)ppo>GḔ()#7Q)SE1ysJ?U6PC7_,.+`c${ٜ؅ &p) %P!u8 RpZKd%AoSC%8A?+dBdkiC[qo#|3^?y8kU7~s=Yk!91ȗ| m5i)XJ?mu=[gJ/6/N搂C"Y (Vӂ"۟~c_z<:wn`Tm[9×\ /VZ[ -ȁ +ґC*rHD|@ Je$LU lgJ?Žq}[}?.sc.7*mo^Z(Aq*-ұQi0]n)qG4!#W"'jɼUy3)jSB!c_I!9bP9Sm(`2e}2;y^b®ܮ IȘLr˾{m7L{b/"Z)1hPޤi Cy&u*{GFRDOEMO{+fW2wOz)љEom:u$>(~jKO_HSNxI;Y1qbBSe˼P@&rD!c+8QR{nut__4LzLt[q]yga`jsM7Ler͚X( k-d"w&!_]V~|W3%+znk]կ-1H7밹qӥ=z±)CMB(!9d[ G7BmB <}Z3 +OhkW^mտerͮaܶ+uw۞Cr޷ +nez#t1޻$'ޜ6y/T|=̌ Ͳc ڝnu/^0`;b~{ج/zȴ/~JF9ȡ×f/YM..?QʬkZƳRxjjmc#C=&C=FC!݆C "ԊWZ^լ3k45kshm lX(  +CѾ埛x2Ľ}mC;QdŸ+D=RJti=grKHBT{¨Lk¦Ls­TckµPļҽay<;;pW 2#jq[@6OcM*'?PKվq_?Cy}{ӂk(eؼ ՝vU<O7qEd|M_T ~\#RN3(gVV?P>`$.?ܾk0} ݕ%tx@@Ll~ژ|t$QC}ZSMoz> +M|>-߫o: ܥ#z y# wK4Am1Q sVJ3r +?mд_0^cË7?/-] 9 VN`?i$KNN(+kʂ HHiӕ%]IPӓcNM4~_GU&Öy7c,lp[T" +)!<͓ ,'"r ./O)_0 ☖y Q!$S qF&ek'?C^;伴O-xa[¾}mSIQӎ o9CrG1!9IC$CH砏>o}B2_F>wJ*}]ԡCM}kV-uF͵ ,K e D3A^H,i!RU }cHt<:$0Ϲnq] Zj-j[LjH$sCQ!gd<)ASV\]C>$'rj'{r][.lLJ/V[TuUXն-ȁ +rf +W|(}Ubt2ͻi,&lpG@h[`XwXsXSPsyB0! 9$ 8͐ +IkA}U7X,yMDz=Q!gTMZw5#j#֭t`!_8ijm,P$x*~~iT3Ф8qed}h[coOwS|PyĹ+a9a9>9C ,d2DͽJYZ&YO*ڵ_tj7Opd¹=߳:o 6jzdԍA7B|^Z!9$1B.6(=yjxHR6xӫ_^Ӵ+m6jKܺJs3SƄND$ >y'0g'`t!Yam<.f(?y`AK}J/ԝ] 9d:cYlWW]ܙ_1s%,9p"0m[粯Ϳ@Z*HAI!mp1AߚE/z=ӽZW\0+j첮-iȨr]1s+'GNքC<qHFl롘kEx>.3u_a᛺ƅU-jrl8]*w wɽfwLZRRB*CuPʵ{="^J>/9T~jp=c)=V}>gF\ZƜ:{Gk +/Y-Ҷ@ʞ{*3~jj@M gR^T +l|P<:[yYoШשlðUe_yɀykyB0!9"k~SDT mN޿JL= 2+ N#ZL,. t-2@?ЪO͜6ݾsrsiq/RVd+ENOPQo2lp٬Ecި_hLXzBk( kbٽg5wy {/,CTyާn CB(z=PNT3^BásݸB-£\FhDlB٫) g"(M Ñ#tWp廠`+悈QW se||_ʇ9=QRN6sW+KA]٪w}T] wmYs ,TwXh/dlZ| B:?E,>K:;~-bB1\JS'zOLb \c,޷n9xYףˁ`pD(b<#jeU9oJjUj(5P|k.@ᝋBEˈ5k#4SFʶC}_,p? ^#|pRDLg$H۪|SdUAWٯ2_me.jbbE{e60!pOp:h(Ɂ JiP5M#IG.7bhxM492m;<iለ*pJ* IRq%1RePP>aFIr\uuY`aM˩yeM@ +8)Q9|pRLAD$H iq~] r"ߴZ k/ H)W`m? dxuvܴUqUMVI/L.&O9Cr%sbs! +9D@6"o.~A_E~MJ`]:us;gR d9,k!9qhA6X VGאSޞIxcڶ"mcs{]&z= F5th+Dq'C HV-1'0kDKĂYKK՗=ih0j4(o1./f9D!prh D 'Y!]%!M[s&[ϑnCR^y?s)VرCm ӆvFZβ!u3)gesClMoVSl>9GN{\3sbm#gj;-kj*-ˬ*Yћ bj8Ǻ 9C|9_r 3ޤ:F>̘ +/x%sZ׈kqWsUWәr"3-5!9A~=E2bߊ?Y7zm(-vwXP`Ӏ繮^nvjʞʞLbyC2'3dBQΙ2i/*jt-_z=-5Y6p|_OF_oi_{y_cy_SMGsC|!u#p2A^(9RZSjmU^ˬo;d^Ns/U_4PX0S:Zz1Υ;ƵuXC H +y,P*z%7 O UGe渔v${Dw={178v(;$k(5x(ڳx(ܽBGM| U˺2m?+D~~߬MQFӨJیBLDߎa# a)bÊ.+ .]=_C4rg]Y6C߮SG>5I +WzޫfGFq`UzG}qMk]Ag{j訐K"FCrG}C +F=*z Chg9$dcoSl$OSx2bzgPc0BEZSmQYcmV[[\WH|e؈+qcnQgFYqHy6B_1"#7uMxbL}h@\GiJuUa~]urSkx[OkZKFʨcjeۘaWqٹRB ?O0j>8맥LM^ kh\el]SkXZ>P,v=Ie *MhK4K5 mllshSxѺ1ߪϬ,sUvVAѵ[x_ Sc Kϥ)8S .|M7'AπQ^n>n.NΚC"rHܹ +Q{t՛nuSWNn1%>R\獔n Y'Ub#e(uUk6lxٺGhXhjXU@s|I!ibH۱J/|d!Uwy6<:=-*A\m9A]ZNT\3wҼ]q#BFM|)+) q1dG0l.=aph7a/"Y->v=F.bJ&T3uhjNOM Ur77{?( qm[4ݲnˏyϽahϓ"3Bq3"F$켧=s'*14$>LTy䘠;Axljqd,̍?7S<Dmu%}$NYS$-?J~Z=Xn+mB^ ߜ / {)E ۗWn^iκطp/x$l񅯒x詂غقE E{iOߟf~3f3f=͆>\|c8TZ]B~s?(࣫nFrZDΘ0 a^ݼ1ywLFB_^һrx7.k& + fF`>^?lÂZşbٲ8e]'ˎ-c >0лIr€EAr<8v@x3J^5 >_>IK`]޺:ukK˞}7 2Ft.f t\Nf98l[ >6YmɷbDA0P02vߴ;7g_dg)yaӐȲ3¤`DWB~@fp|!9o[7p^H$Y +b ?GZ9|q5$G6E J[UMZ_6(5(o3.n0˩1̘ t@!(ĝ`.##UMK8 7σ=bzdq+ɪf[V}ծߪլάҢ̪?{>p9"!VH<O̖"1COmxGq9W]G#kS +j:k묛k,[lJm/!t9RN,ayRdi6fx7)~<3gǯ59%յ̾!϶.ۮ<Ӿh>s!9m[ # wV$ycbMgF'.Gg_)kwjqOm,jowoNohJqlJr,!9D[G!w; ~)P!U2󀫙vY^uAue>a-Em>9mUmmqu.u]+Gaf9Dc#!gLЁ_8[ PĽK=oE9>ux@w{YdMMjaCAZKUtgKyȰ~na}՝Arpvҙve<$%8yINueoWcqxYeJvm~|cehkWgcBp}R|]rAu\EUdu"CZ8m%$] lk~Trm,E5 ץ/)[kyTwo1MJ̋/rhtu ΍ȩ4Mm3ol +9D"HwZ{m'GNL;;:yZg\Ѭᒺ[ɀNhFaBLiNpE{MMcy_YULYMniM}QacQvs|˩ +90/,eP~xt3gO%#Sr-w+n(d_щ cTrìƴͮѨݧѨ3;ޠNFb>)!z $0/=KZcܫNox!L\A}yǤI 4F MG */YW^ԹU=^_9Y]4@ rYO̴Pf#iX5g;a7 _J<>DbR]l +o*PWSӜrb|q!nb޺{v;)'w,|~lmk>*L yE[ir6"k=J&#:e2啬0,YaRDGM $,x֍ĭ+,4j~p)~x7oB*_E =J}:fNORK0J/_S|2"TUY!$/Lzo54-ɾIcQ+pRN*IU壚⴮ܴG7ُd>FG|-^BScT?Y +'p a}s(dg,eg4dfg̬N"\-~XHfu1OMt\DܼvH=#`v`euppk2+Ɂ4kJ(j"EJKD[s>(CD(%Qq)E!_ WD`r={-a?r"p.qI8!%" *s +d@VVdO:BzS|0@) (AG r_XO6[N]q@v~N)8#GN ~A~:B !2Bܠ jA{^ PH žd#Xck620)`a? cpqrqN8qGA<2x,+̶u`zp |^ NMys}=e4ׁf; N `#Z`jV`pہA=T9a+8}5A+IZw]?pP{^mrp`f[8q0W-Y7+G30pFIn3F?<7x~7f<5mxuG:7}'5'i՜oo-qd;S s|4dX ΘX{:~7 j$Ia'&mA&FC_=;=vUc"lXk2]<=8!Gi~!P뻛W{WOV͒Cߙ{kZƴ)i_Iј+ZcCע. һ>s2pFn{}+ BΩH}ki1'Uh 2➚'<1M|dҕ|h PڀHrX\xdD"/ 7BHϻlYwɪ>oBny_nI_N`zRY K 9 +þ"HIIwwא 1=twwww"bmww({}wCpx6>Ꭼ\ +5՗Xi2W]l7ROrzW$4avTĺˑCz΄v?{4dhށ!B d0C*֐5dr@,TAدV3vFۈWM~oE_Ό9>7Q>p4yHT#cSma[Z/6 d0C֐P.xZD:MqvxNw2,\AL\zRdBfxlHlP\`p_pkpcĉȳQ[2 lP) Vu5D?{s,h^Bhzj__RHwBXgbx{X[XmXePy̩_C:֐ +"P#gݥ#mX΋1GCn׺}϶gDVLƵ&g6O?Xs&ĩqc'Ow dװ xwBNa6=˽:_Fi=9`u{y+Dg`摦Βކʌå퓅c9iG&3C'{濆 !JEXA :w/ j}0x5epoy+%b?c=1*8i 7c2;x*#q*=w`*9T\ڑ# )ٌ k";YzZ2-ϛ+ߝ8_:y4pf"(אۡV :/+tTi= \ęPM3uxC{wnI.w6578>wx<_gJåkht=sBβwќy/mꞑ4>Z0!e}k6!5ƷMTیwmEv m/<7P@ lNJnF׮nFg^>SD풖zY}Bc߭I񉄯._=_C&~MVb+dՏ3 4ʄNТ+[Ď595%5U5 5mU=U# +iܟjMn/WD0T˕PjOn`@to+ӴMh+3- R܅ # + +1 j&^i +:0$v8{iSH$B T@_=@AΜE7vg)= & Rҁ BP6ƒ%h[ ccf>x}aImu!o!tvKGa|Ò<#A?xH؂(Ꚁ!hꃾ.kkB_Dh,B7Fdع#88kt~q+1 + rZj +``@T#4~{!.趆f`d'Ž=x`N!cw@$@XJ ĤU@RV deAQNTdACNtA_NL$'+a {n"3@-y!PNB5ı"[?<= H@,b/:1C~knn Xt{"뫠o;}#5b >X +@2HKmC#xE#o=?pŽ:{[/e Oٰ%a??xCzy]W7\߇^sa+P9wnHY>Sx}YЄy9P))aKEƨo䑘o䣱_ɧ㾐oĿu(k/cHo#ΓޅoB'3sUd@IC:$;ƒÂ<bByG,JDIHiK@H}O92r%ۮw{te h!kHa.Ht+ fYF˩?^6Vke@+qEBӪOU56 h =0M=0ta(Jm_Ѝ;w6qXC ҅ؠ@r+]޿`,JMi5nljIaYԒCa-a--c'ZZ:CBV7So4Qomm]!2-UJ\+ Z[$>t^;=lt'ި Px"+2*)j"&i8*m ?7z'f#l{cK5*#nmk 1 {'@$+)r.h~0{kN;JO銠܃IMY]q -MOwUD*\u$jF  ,'*%vB⮥v O=" o.x , .LhjNIKIJH+O>ї{s=7bCnڍ5$sBAf- +l?|>f&{oVꀋNLxMhV_YdYkAlcMfrgYjVQJ`AJ`^`n`zi 7 ! Rxvg^mOߓIY.89yNF5gtք6E7'tf ddeԎdt$eK;6r/.l{\@ -Kn!UWt]?jsv?3=D-+(H+H)m̎f K?۾ⱆ,nFؿ ZĶe0'E/i8bo;9Nww4fEW PKƂJKʆGK +=۱HJ XCmPq}Hzۛ#J`y^G)scvVG=Ԧ~䶰辀aߺ!Aꓽ^g;JϵmRDmPw+o^y\b93_69G)bHarBwnEL_pS`wxWgbK=qýBGBF kHJlM˃t= Jwӹ[|3 F/̺]O:c='JC&B;ImCs- M}\{lҷn Pŵ :iyqr}-O˴yQa=47 VO$[B Y~]8  M~.O75Z_t͢?8}6!S>Y| em%$kbշHoq?f,R-my߆Ѝ1.CǯnBi`-˓[QJf}) -IUC'д][;dCHq4}ׇ~>mnB ͟A"|j6 +س-X@po )wQ" (뙃1X뀽6͵LBM5 T2LԠX j6ri3M.`׿P':TLm["\OAQ SQ1u]Pm-u0R3meVG-E i)Be_Ml B8\soF ( " . +2ʠ( + +`  +y1ȉ#4| V5({P& hS0  +lbv6e +,x?&||y`X~.R<,aR@5S ![]Iq%L.%\vq z(xGć/]_ EF kwC KrCjCD +uZ pFXE}GlCxM|EzI<x/.Sϑ>t{b}xf +/= Zl,;Fg1h?g|Kgn%OHu HII)Nur4<ޅM?m3/' wA')LM,#,+/\^=񋎺OII힛qӽ"GS5rOUxeϹKW3Qf'?N|xvQ_i6XCad~ r~Ws~WkA~zׅyCK& ƂkGBˇCK]7B4PcuXoaBP;ů/68"((&%75&3+2'<5=q#$m)4j5j=51A[W2[N)1^w氙̘ؠcoOsODUs@Ja]hAzeDulILKHArW@~~A]_a_otw܅&߬+5@del-P~U`ӧMosBqͽ3&2'm ag]gXIoRvk`nb#"&ɯ2ë2ӳRNj:B.TO.Vf , At]oh㣹~3gԸfNJZti=BEBgTKWSl?K{Hڼ Jh޶ҡ#ha\؄oCc/D{^ɳ4P--@'鑉Us=K]pXۻx{8)VJb,F[>=iE8Ѝ@&OBѠ'i5z4~MG-Md?*~PJzN!ፕ[wA,>3ciM/o=7kEBfhZ4rum)PS=gI7iIQ"bIUoQCmQqfь[u5[r!&,/*r6d{`}{ÕzT>Nc{4BhP׫ͨ87/c6'O8H(95h1 RVzc 8HЁBsm7ӆ>S-3ւсqfPn)VLb6*AK؃ȫhj낾j8EWu!N[ 2LS4}]:69#T{44鰍>v2r^>;/l"F . 2rjJʠFS *J$(H@8dɉCc)z T@Q@C[;9a)p>AMQa1Ei PUIqВI0[$.b|p`#_@&Ps"?@n9гnmέ +< +/ {w8 +Q!Y$B<#!m 8;"oSy!0c90W}iA +@ 5U{5d sDL16:P5 P[Łf޻ >0slɁ +z` $m0*m0iv'1ǵ&X<ż5܊%h,nHxX~Q+YQSI>fY>7E'fHp1z`ys]Y[zE5}| +3&`-R" +2`c +:`o1F`a c3vcnj4U&lߚ,~7abL>؂[;0Xn=`{npWeapѕ skZf`j8­ٴVmzp+#߶GpN.[.[f -~=?ivc {Ih/KEI:f:@1PUDv9vvev? %|'~?a7/w>9v|Oǧ֬r=58p=np*>Zbcd;U/@%\8Ը~vhuK8F8Mzx-++_<8-o;/;_w^uvw&pb' 1.UCBdW5z~sv wKyC(zEh~IyN}F{J8p#EmO\{.t?KzX!'DqCj_C?zߐ_c}>r. ~Tzϩzǹzez8&*)"C/߽gݗSn&p +=l +1(j|ž%+}u4xa?9<11:1;*42>[GPyj5XCq( l( +)ϡGf$'T$'f$&'6&F'F&^LQ'?2AzY!} 5|t_Z^toTjMSbSݶmθFbKuE@TQqHjV^xAbfLeTZJ]Xj~ChjmCHZOCPڑK*) +Jgd*3C J>|4Ohn0knXЀ`7͹ӷ/")ԼȊzFFCy u^*2o{_` L[!mslyӷ? ]=**ACQKA^WǪNWa75?1&$;"ԧ4\YQZQQQ^~ڭB[2;rA۶B fI ;3S[хcsJ,+M֎8KHJpRO\xk@_ShG}L9>P^Nll/sm(qm:_p~K@0֐m1l؎ңc)^䶏kt3m-;lo;LJq $G{s\ + z +z㹄َ=3 OR ϒ [ УVZtc-LnB=/Jn뽠DI 6i31G}(.~ii[SƒK;<?2?:z=r7ӼE7?FNҠ KdK %k:"EU2,YۇƓN:#{SlcmN؜l>5iu\թVsB>h~ to4s_G}wǢw?Tϼ'Hz!9zH卤 @[9kv/^旾SY=CZw⢩}+ [k%WRԗ>/ύmᜭ,_u3}M2}UC4ybf '7Fϗ-b4?Ң]wmR*{UU"~5j3jem{$k8! 9sݟwLu_Zz?h*H(6`0y}jͧeAHP +Ą$@Z( ~!l< ~np߿D_9/ T{ {bP+< ` h f=cU-%,{%pc~a^ 2A4xAL 738 9v.nP94%@[n?hi˂*ETA-Y@J4125,ڇA4蜓RV[_k X zX>}* +Re+ +Ө;(z9?*d /#i ֠@XY @ItU@'NtT@Tӯ cJ`8F'1+/L~)4ESPa@Or ` z{DdcBIu%R ]TO 5 ] 4F[3jkjkf j+fwԖ_-QaԾ@31J,`5 +a#v`-`&^Z`&:`fVj֨bީ|PAeYs:K[:quX~d +YP9o7bo!np'`o"xuyY7Zeĕ/Zl3ngjՔ&o|~f+ev`h`˶L}@7Q. 񂇺0 e`O[7ne:ٺM&6]lym{UO~{dl,8 ]'k0ݻAn[Ge~їE) :}&xھ'ؿr|aWBxuzoszs~wy?z]G>px\ Xq?{`g8q-%Hһ!Lw@s>:o=,:|ۡ|˱rӱr0Ltr,]sK' lI`' ֻـ[ZNJ{b?EH5Q|\k>3|/:]p;wƵ4q$ 59 Y^G=~"v#0X='+Po;2C)_Sx&=Uj|=W{Iy9Yi)#䩐IC!={x-{~{~ vn onFHbKYl56zn##Y!?q̇p3.0%= |ܳ2b̳9bī7b`ĠɈ}>º|?~i]4.W1{A6>-_vǛB5'E|/tO'q  M͎-m21=.SP7jo,BضAɿu%_S4r{[Ju:NnUt/EK_id?h*4ScYR\īظDfNz[+Ci+??]b:Y[MiQv2.wk. ,IOINM--(-.;Tws?',OBnTf:(dYÊ^2;} Ҡ e#<#]2m:MMUdעJo߬ĂĈ"RRόJH19d9n>%a&%i +%YvFJLmvftmh3:;O3;tpH\Nټ)+74"0>$4ë0 حTTH,'#&?N'݃Dm NuvJu.qnrt9T{?թYSXW1~[@"=Bzt};h -:yMMs-SZ& ┊ 6DRDWG{@s[x +-9ձ(š1ɡ}(Ѿc>޾~}hB!U)BKNaoz +yRκ9]YSٜVɇ񸨃1W/GO 5?c7Tm7i;<a3rfcm۞?HD3]iG f;_䧭(wYSfjAsxʬ~3f*$z:!j:?j>rv7{77 7HZ#HB4s@ BghQەͨ6'*-ƐwK#P5+&,p 6vIV=p qs/Ւ.Mw1' +VGBw`#I:.Ң[QS.g"[Sʰ=3xvGs+fbfN `g{]Aŏ7\t)?}|P<^U{C]8CF=>~J0^WˠZhi}uIOn`3=1z"pe}Js}2S ;y󲔐ٲᲖ/CU_85ߎjj+d5Օ`e%y%S;Jw`g`Cd)HwzD1Kw{1$=,0:9XHHpzy=aW";?6x "CDC4~WB-/F"3x6>|<*v8"'@xiڨѻ"FwDNEEEogƸ=x=9hq!5z/ Yz/RY@iؽJgul3'&c; GU&ljL`ndnYϜaNeNĞc}\!f1:Ab7I$s<j\ty6 jpGDiՁpqAےS9 S%+RWIKM]0:3uy"uy'u(-s sLoҷĥ?صRPdٿԫ?ojsŁpKpuB)}{ALব Xr~HREUI}IY=۲eu&_Ly*-slk7Ɵ?Q< |) %vfЬ]vUv"[0ޛVݕZۑ2oUjO^[X^ktԽyiҟe7IOX)O@ pC{$Y޶ʲ*|U6"}$`g*fz!B5YO[ !Xg0Bo Hm/NKkέ)*ή.j)+/+//ɞ-/>Q^s(Y^âhx99 jY݂ :?rt%€_`۱pρΚ抔򊂼5UYy[2Weܮ\<7#UƟ0><PúTϋ^}0:5r`9aAx/jNi +lmc&%WTefUI)jM*^]X&x̒G%̢̂"xx *X7q[ ;:?Ɓ+=:INzi ZvtE7džWd2Rj2J**jc*VEWFUM0RU4iATً?\x~Vؽ{Y6trퟒA;'{79 k{C:rے2RV6TD6ohZAo询7NV5-6].7=)=ϣ׼ ,,wiSkYС)vO3zmEF7+M SքzUGF2SRr#;KVt4t:'; +.к^_eZޤ HBPн& t~{l.6i"1۴ߺz2ؽxNZLj`e22BWgnʣP'2F.gHO}` @q ~/q~mGhnNn +Ђ on;5s>f%g}6DmdDN&$R'2R&JR) )dD~S/b&DX#t`!4oHz\-j:+'MwQBwDͥEwGw0|vn5JΗs4m'Yv1w{eja,YK/7ٽ<`jꖉw6G0<-{A7c^%8㓚XGmOʤOf.l?|2B50j`X[‎&-5M_0Yz's #4~S^y ;~`gApࣂ%!J6`jVa$ h]]j:ZЭ 5aVA}38yIZ86BI#'@T$ v 'e ʲ&)o +`֊XUKA%'iP"# -%cb' @BUWp-#o ,)h|"& B0q %)UАV]i90YVR,%^"$!Q|B1.# g,B+p~|K⹄؜7$lj-b J9(@ .0cQ$PaBeASC +tgȂh(Qԩ?3AL Achȃ9КY):e@4]R`Z >c~HE?cA_] d@AMt@; + +*] :m}7zAZ `2`|_L^I'%%Ef_`נ&F`.f`j .j`u0(T`آF1d"n,(Q0(/%rZ.}ُ ' +I4XkʁX9&j)S LsR̛4S,rL &UZmQa[ews*lo+};%7v_كŸs)(H8Og p1R';5 ]L=)a[ݮMgѮWWq/>;_iN748=|^SPj]A+,,,e%IZ|zIxX8S8E-:q*0TmK[A7k _Nrfm ܯ>vdiI/['Jvx## +*IA"4{|&wO0mXfXofgc3=v[Oi_YNJ<lyvIY-Z39p.=l-l=u }:C_nn x?X >ܖnb@~nH#pB b2-%7rNHƒԭ#[C'#{&"GSa;2EݤF.ā8倇B'dCrgUjwTډ*P>O1 uܞ?FOfFidt0cc3cF ꋽ,7KH] [x>бk%r@0+fyXr^|*RH iԱafN`BIl|M\o|K\O|O\Wš΄ŷ&dr]ҽu)"kj,(ػ8!JxѧY?]hjUzj(ڿ77!lUfjʴi)-i+RҫS֧WlKH9^r;,P jdAWхNtG1t"ljR]2d!ı&һ"&UUTQ]UՖ5=})?-EfZ۔ Yaܐ~5]_Vt C89Nt{*V5{4FSWTG%'edf'W%7%o(USp0iv|yˁ< vۿ;ntlB웆z:[ĺf>.&1!25YSZZUR_Y]Q0l^v:?qvDȒIш˳J\::B;Z17پ!v{?բ;ԥ#ҷ5&49!6!95637 +?vmv6Vw*V(#mJHfHDŽ@~HR5Xb^S᧍ +|!g坬O29g` >x`oP]"ޱ/ p/zrL)eS_䧙!끛!DNd!GF VHB +Pp >[w}xM8A(BsX ȉ.hIj$C)%T,P$!B\RP"*M"', +B!48? ??>E:m|+ .,& b/&fB`/$n+ +"(@PϏl܋gBm8g_~Cr}Xl#63m@jU@OHD~@NTA[1εŹD Cϋ 8(hJ*FM[d@Zdr MD˂T4HJtȴl/dG 7.rDA~((,QaP Jw@ (|e K%A4ˀ(Ƀ"Er& EҠP#--JL@es~[4 {%EE @CAT$@[YtU@G[AY}A-\ԒA-_Ԫd@Y4:@c@ +4uOH }@tO~[{"Mo@>)/Z` /FJ`! `zʠ : JW/'`DMKFRߍJ-jrMo$ޚ~xm +LA%-}Yq0BU%@l&T50Vt&MkTj֥|HZOS,{guTeWe[}bU > }8J*48[**i|b:OM[F7^Q}aA3*OOͳ$P?j=@u9`"){I‚/! +!T#/6oHzSo+oEj7g|c[L{Λ,o +E,*d=[h%p8Mv!Wg69r:>e"&k]TFeQQ8h `3F{=.ij>#_GOU1@Z o܇P ō>%N0Tr܂w_Ԏ|,D*i,1ku|@l&70;3!%f6te̱aMoMKM_RXr'%f9VōάPFVW:o-V*0Y0Mt2SrZK›j"Z""Fo\Q/Fu«jbPu"P`B,uBj6tWDMj6Wy*R G +i}ĎX$ZcRFx]bc"S)gĖ17Ŗ01/'=g$ +I$XYEKY] ++:7ˡf#" +c~z]Eth߆ڊԈԜҔ䚄6f~ 37y+13\bV/٩Ka)f&b `{_ɂIm-vBMDz_T0bϊ̌Ĭ攴ޔ)Is))3?$g.F$/-#>9v;/cZСv<h[.*67違dΆ@ӕ5!1E Y99ɉ٥iٝ1cQ9[9>~^ _ο1 {E][kЌ#6jX wJVmk 0jhUՅWDQr*)IqqQ+2 3E#E3i!ESB&}.F,#뗬ү`:wcCCj,k͹ =J͝5AVe-aM1! 5ȪTZeujpe[JpprPt"Z}'>]tpbDp}9 <~^^۱Mp5hh1gHInW7м+1sUWb[45je|xhSjlPc^B`cUB`S[|@p,i:|(ʿN$=GH@/p)܃x޵ Ҩg{zkUkԊGlc~8ZPWJx@g^gUW[_0ݯ{:Է0}'ط]oo/KB+:ؿo_k{"mZa9OFGB$Q1gG7eb.؉>FIG*>#>i?þ^w}yy5yõZ\UDh'Ο;`Vg9Qݜ"3,,0|b1佑1scǦǦ!"if7îMwS'8O?,=X߆'ގ{=MxSb8+HZycV숻bwgػ.sl:?h2e]s]̝v4wp |bqv5b,;;J=#g49O+}wI޴$yl0:x8[H\$/D Qp5h'Su '6JlVoפ*;Go:L(pآpa^q+/:>Qz#Azt=:<<=[_["]Z"%VF+7`Cxطs]eCsЩEtkWؖ 3jué?:H^YYB^Kn#7FN6D󭋼W̧6+6 +j;@}#D:5n`TȂ#%rhԐc{<,?i}I᎝ 1Ķ$LBJJ]tc@MtgsԲǔ>Qݑ}2عΕg2VBg)P.3Z@ϡvfٷ0>je\Ipyl 4V7R! vGH~мi) @.H{bS7\*:sa^˶ښmPZwaQ[nmcf[MZOErb@IbYPIMhfg2׆g0E%Heޥ%NOIHr BYe^M$~छUgRK'Rߢ#s ~`{QL`܈Pfg$PkOf{Q&7٨)/I? ys<΁4@/q nhskamÂ놫_Y[4wp \q\ݏ=xV]0w'/ܥRvs 2@#mm2uٞj꼽yiqv\qv^aW:v[΀r.o؁q*]7vFQGYG <*vKPápuCvlP9ܩl}x݊VG(X|`q໢>P2[ ܃}Cq7㺏ms*݇P&v8좡uY eQ.V}$-K_4!av\Z+ڨv]$bxbzxvۂq~.x9GbD~!UH91LJy?2x$KXIΓ!O+uk<xW-^gxr~}l;${{{q ~kyF {>V㏲zUy?2Pl+]@?ܗ>iRy$sK,_\_ICbo#8c?>G{O:PeAo,^!E6=a.5Vy9Ҡ+f#< \P0Y8L.µwPp>=="d!EbSĮ2% \b -TtY #' A +;R6͘b=*wPq]p d!)A,rؤ8Dqc?\Uhl33q^"&A & +51n=1`7 !(GP?Q8'lr1v`0Y'(H*㒪ᵸpD[[%7G;pr0p)NيØ ,}#7l_x+* ][V*u`LQ`'_@pnpNΟ?g9 8p|$|`OXb+x@+H((`T@ A`\X"A!Ŀ$L07<_6|$I +׹(<|SEzy8WU\4  !. :K K PueOHJ"_?+W}T*N 1|4\}uGZyz{Ok62@EBtD@XL`./f`l*>tB$^f-yB~cG}B G6o4-xx]#w/ 4~ xe% & tssf%& ؽ-ڋ ?8 +WKw$&T'ђRZTn[ԋݴla-/!VĮXmd=Gh}p_6oď|?bC@8 ߒx( ^][;g6ҷmRW쳤/Kw9(sơ]c aGfd;r:.{^r_ewR|`ώ98Kroy{ +!ډ]s,5ZkQ\nk7+uPޯ2O\88xPuxIu+ fP ^0߀57 .ec`Vb&4Dn6Qo^tZ;ʵgjyݥ=={&i)IӺ|]G~=Cs/Fw]vN*bW;zD#$ѵpu3ts4=>;1g 6en+447o5Zkx0 QA_btz@w7"Q=eAcэh^t>Nh #a4=f4N5]GM1_CͱX S-M~euUuU7U'u媠f` wĺX[&KLNt"YO6%O0ֆӌ !鶽|nZ]'֮bNoomrXI[phwl=ol +P0}kp_С ;S}kTQncFrj +tnti +ktip[Z6Zӭ:[U}*GǪp k7vPA*Bp>͕DylrgJz%tƅXF3 n5RUD+"ߣ,bGiv∣w<"߹Et*bwGo\xb=UH@[X' +-x9cQJmM6oLqN$GexFxGUE5Du֐sf|}372xfE/gǀ w~f W2BWOc;wf{0TԌ{uhO|{VSմ&%̶"RQ[[GI];) )vo3J`bKrRwx b~˫hx.b:c݉GUhM gpg Qve!Y.7*+ĺ$=9/%#317PHe&T%$% $LG%3.G1S$gl"~xn98[}gYkoUDCF=+*ݤ˼UWS +-s鎙Y xTjtJ.\2FK9G I}՗ +;Ww5heQ_>[G5_sxmRENa,8> =.7D + , ά ffd +~Lf!S;(<[$_}sp +;ΟQL$lfmiovj$ב5rkҪh6 tFiWh1TPXL) / +-zD+W@1Lsx0vmmGhALgjRgi4^e/T.⭚쯗d]V R}|U~NOZoY/ՏHUݼջ\~1sxP{wcыPK?/PBe}6|=.ݞ +IZ1m!A-N+i$BWs-keʵ+g=Vv"5?v$5}'5w;B)ڎswa=ʂ*H5ڬܙ#IݥcUuM{í}zb={d/JSl9ߜs!\q T B B2Wo1k=NbN $)YP9=qV{2e,K[i;,iwٞSӅ_$vp> pF<3x@gA}4).~FQcu8isƂ⌣!3BFg#0ɂ + 5;Oq^sxN< '@w~}k3ۊPw#.9B>؇].!dyAFwYj5˖K/"= +ڽ.*r(¡v^gtX xi ,D[E 96u:n{x^}pro~CzFoh=_ ed4b6X˿6j) MAo?5Hh&d[ߘ5]-~lfľ4+v->ZůX>]dK&9f"+ˬMVp՗zd%]徵ʑkS*mm[v/aD>k뤮:J]v%a.H9eN;-s 3='&3f̓/$,HIJ 󭳟W7]2>q$wխBci1GGy +=7(ڦxkqSG)Ni#ov{1/01IN,q>=T/o%!}'Loճ~%jNOW;ߦvnV0'`H]iZs[}ͭ/5 6?0Wx_⽉s'A,}݊2]pt*4VhH|!StN m:SoGz~1fwG0fr]|՚JUӬWϰm<ۦ7~MOzö.d]W_ fLc~K#xBx<נCV< Aj2 ֤%d٬H._\ГT$i㢤6DžI󜺒8-HZܙy^>9I\f'}ڑб=]{2̬B_@Ƈg+V=%bW5yz}{2:u,H+wLu>'ý#ۣ=uMm#3RxjNޜʹ)90=I!@csD˰+S`hd?ŕEa:= sSlOrޑY9+ʻ-{FFOKFoS22vgM_Om L +"=\ߧuJjhcJeSB4Dw&tLLwnhPӘ=ů!{j@}vs`]ًWUfg u-dJρeM`^xFOhۨ*xZg?|:I\Ok+z, +R[Pi04ު8թ0cZDߩyŁU! e3Js'O=Q1!0i< G;ܜ2vup#|/:]7P C.PenM8d9~e +'L /*,oϟWS)zB +.x<2<ǘ)Y M3Zxz-a[&>-L.Ƥ&Ѷ2ͭ,۷tbH~IIdNqULvqclf⥱ibSw$_N.R840< hVx>x!xuBK͸gʷhLo2oU^\<5{bunPVŤ򘔲iqIcEǗ8Wq7<⯐7 <`N1jp@_;zҹ5ψuΜ%Z73B5μ%!1#aj}AhbȸںڙQ1u"bֆG ;Uw'(Q@TZ31&N ]\pꖠ9ݺ4ۆ.Y??@j^Vゎ R]ڲgĶGԅD 0(bڀ;g q'WXϰf1{hk6I}-uNzԩǂ_"^GtqZH8v1&zEΝ>'lLﰹ =C-dYw\JmhY5׭wT9m~i#]ۉZv&“&;@)?oi](9Sr:Pt`yl;pZv{Zy#g93<.oي~[a,y!<Ec%.d,/LY\78KbA_ + =y-w3=64v`!ʁvi0Xvoxb+#㛊dtS >>wtos:8/9/8~{~K_~B +_A +>c~`߻3D2zmDNY$2'^H?˓Ϛ1-''k('[~+ kI<,kIBb}ND 1']{v>Syv% i~G3><"ʜsmܔE4sL1> 7 +E? A !'j΍=# m'h[@[?BW"D/ A" 8b@ h3"6ɣ +dl1ghpĚp^8D~( +ھ_9#2G?@[>{Jx?p"5aج2l&1L'8@2̥9I2 +׏c4Ah2ҭ3c4czJȮ0@?/8EڲL .b0F R|%ň3DE14!v0rw!9t{ޞ<_`RZrLZMIX-ljZ"|Ԣq4 60kZƽ~讇 4w@k?{ez@_>"Zޝ<&m%eY$$e fB7)A-QP*xM{ur'1{ĭ&zm;Nr/m+3,SfjRLMAihᵙ4SrbrocEϥ2,%Y%Sj:Lwٹ_er.~~ o7-Rgx몌 \Ӓa")+`F2D WC)g+BK/p)⿪M^&^f VWK/Wp_hn r7uvr7tq.1!7d³ 8m/@B$%OI1{%1f#zfi!Eg o e6.|nR-a:]Y\ne%~X /X:)r[j;]^lwa2\:fC"}o,PD4y_ +>qs]r : s#K$٣rz5j){ +]wx) SsFa A7A{mX9:»uV]M7޲[: Ùvw8a^ćcF_n\&TL$I*FiI[=?а/pyTFFK-^b(߸;zqWQgM:0藆za>X~Fkw+ KEp&3SvgeHlJS\՗oЛn4>tq\¸ +:qq,-=nլmq7[~|F3mcmQ;><3 {Lޛ'O'seh,M1Xl 9r^R6llg%ٵ%γkM\jߒ־)qCcīO|fSĬ0s"A<'/`?Q=f1$)Rd@+ g{hZ=F[.hRrg~NGnIۄdLyŮ57͡fB)^YS}JZ|fdm5◛u?'k\yf3l }p581}øn@,+QTsY|n`(iՓR3]K&yM+ϭ +˝80+wm`FӁq'=gF.snD;\F b,4lNSE &\4Z/5A* U5屦SlK]rr + 3 ʂ S ft' +N,J(8_p+0ob+BT3[hP?،vA47fd'hmjlPӪcTR`_4<3}J_ҠS'M^;?0t[@tqқ~ѥ'cڱgD;sL =SfZ\Eu3+C'7F6ě'ۧf%yUTDUDV^Q=^s+gXaU/ªKXC;\$:;[a܍׳u558U)mR.k1#:91)-3bzWfϰ}nC!ǜ?s +cPKi~<]B NcB~lwn]hHv.w򹝡$N^^gر&㘵gҷY { |2}lZp˜rzӗ)%-Ќ]0$daEP$ˀ*KfsN3>> ?3sKCNf1gNa~UhޠL\H9k )k-?u(aLtRhDL=߾B}J=&]y:}+s9Լy@;"[?r6G!:h@:Xkڈ0D=w>}L &.ڗ05 )Η`j8ӖcLCOyP/2soeJL5}%3n˴-9tS>]JʯO5tEq7]V:F.ч*_ytF%wJN:㿇iC_ۈ\(`f7Mj9 +S}*tU>mfq./r Vsg 7q s'qǍsGnq7~&kp3$qfmqEcEs]CK-Cu0f9sVUVǭ[G;Gl ,Y!oNvp).?m},Ŏ6[&4fG]r(Nw醍wIp!PcQt!牢Υ.բ. #.3$vΖ@bu6~n$vDr% nֺ=^Fzwe+l] Kw~D7}9UDyiO[Ooһevxg {n.=UvtM>mr}ȭ[+wj!~+}+s_6q0")GG}(t(B;Mr80HnK`¦T 9kW+ +U^Ԩ4Sey<ޠ*=AKT. +:ڂ_PFQ;LC,Xno_I4b9LcMyۢDr"•W'eh,XV4RsqX械f.aڝamיvT#n{؏:3Þj1-4md:yGE<'﹉}XgHL=Zi#Kw^ܝٙ7'.Ͱ#.hV$2ة-Mͱf }fb7{Ѣ&Eu_U>j4?:y1ZEV Y~C5:Rbڒ[3M̧'[NKKfUf]i]kSH5)Srsv3Cwp=F\{෪i^.ͪTJ4הDř&g:eNsK+LέJmN[7w3:Gt/1yϝcs#ϷL":QN4_w։S{&ͨ:xTTL.(5)M(IwH.qM(*T3+z\Ϩ^ȢE‹>c$^spT6|hBim +4uUK[D3dsCT2"5$[Dgن8֕;58϶ dPʿO~}2sߚ58ڌvhG;O|<^7%+AesdW0I3K*#P!=L=nVnd[QhkYPkE`kE@kl3M> }Z/x噁g33hiA俳퀭%Dq_D4y!G)oe//tO +VX2?A;3]ϯsO}iz^^K=;7jyttL6'u94]f3M{06v/'ZTu\!I+(i9ŭpD-).UZѓSSӮҳDɥgs>$o"d)LgFZ1&W/%j gz AB6Xp>=Jq^$.[a]2fJۭ[$enڽVk/,W(&iI1Gy߄_ 3?ȀU7uvV a]rnNÎ 4!ڽDśW>< QN=&2&C{ȝtrڇbHP:iDjkIP)ZN${[7e<ѿI|WB Ьf!4ޝ"r8Jdost>!mnAK5 IbCvؠb6.0~Ǥ;v|PȽLssy@_ICSx߀w!g2 ?Ո=AM%WsJhw#vݐ+?r&qzj; = <Ki7D0=R [B5F᷵ooEw +A%hxw0t``#% xg(gP?g o>FT*bC 6 1#D0Խ=x 9b.1#ĐߚJU1Ac4@c =YmD vӯtCtP?;DK2%/:h gϽhg@Z[4%fAcDN4➃|'ݡP?Os= 7;$ Dlj31I1&*db"/ #d%~ЩƐhpaف9: U؄uU:C~}.B<8719cb `r:"sC +8eB>>5u~]ϡ.X>p+KgN5:%=~BGdctPqaj$TIu?7{»d cKw$sD&%P.(9:NU;":#tX}jWh74۩͸ڌ ]1S➚=0达}N_uuLu~&0(cSQ wh:wg+z3&XgƄL"3ێM޷-8\W.y3{/U$u +MĶHӶ\ݮVͮQ0d&b7G0h-l_#`EapYbٿ_nD`ݿ +i7xO}DJ${wI.s?!b=rc 1w&KX(aXnƒsK}}$6DHI^%/3YfOlOlOR> d.]'M~aN|0Be(c0{L+,-ױ]?aIJ'XC P;R+e((. (P;T+Zi~`Rg`s+w ܧxQuFGML(7Syg໎`y=n$ kA_dOa jsCsgNRo-S:U-I5]%K9tfc&须ծ S75L&O,Ñ؆@b|,;ӰOҺ$MK2/Mtu͋ QV9Q9X1R!^wZD^]<uU; *"NG4,CJ+;רLlu`1X֧s2]z2L4y)2Iʭ Mq z1151U15F1M1SbƬ6)fZsԬ0L +b^0h_B09z,eXH 'Rg=]jFbcJz]RNMbAeBQY|Ii|YI|yq4I3- +,WZoʉ?d:;gfGsg0`#^@=Mc55Uq|]fjUzvYjAIJɤ,|ˉIֹISm&$ͰNLZn4`.%cmRY$1s`0>E_}h +o+C=LE6ɂT$^-[\6!\8+F 347=2;=&#.=!5!9mCRZCBFibӞZǥ1K`G5􃳓*5hx-B= +TKMi5Re B5'F%dZN`]萐U1*{cdó :"YK`1WhNc<@G=+q]f +eViD5r7)r9%:EqF)61Q8FLw ϟ>4]Hmpo&> ,b>-΁Bw[#xMDs%oߨZ=*Lu/ɩ +Tʨ H)яh]a>9&trm:3m&/ +,]kP:b_zo7%M}(&Ec|x58 nm%Z;^|6b%hJ&7q鞒 uQZQS jLkr'Tך4Yh[ȧfwy}{zU=*G3x8hfxKYDg`24왶6WVA +-qZM~M9M%>MStx6hڥt^ý.Әs=zχ vhe7#߉ a:)S;͹NGA<Q\9 +cT|f'yΞQQ6UuvK%玝N;zhƔZ{΢x[Bh>hK{%68Jd|H\xksH OyLZDMt^" ZNu77]<~3%;wA7$#tM%"Uh_=D_*b3Ct#@$G][#e#G`=uB?O]3j]A3zw b]F5yHgX5:S$[F`@=vx9:C$بB?_ޝT๕Մm +A>Ǟߞy{^ᄁmp{)v?c ʣq}(A1Xg @wFV̦g๟2Co=?r|E@F_Ϡ۳ :"M`@A/:(Fbo4s ZKqMhwaoO> }c1Ԯ!ZtRךx>P1N&ܰDnȴbVm6̛3 u拸}j \Jy{,X0b &\d/L9w>UY+3SVڅ6?hd_o-Xk_ XP*XP%XP/sh,wh:,8:.v.r< :00{1^cӿSG^'9j@v ^5n+WzrD=n%nSDݪE $[%ϑHbJɹHv~[ 7-n?e{ 1ÃA<>OYW/ \)'Q'CzO<">e2}t4%;glO r>;|NO0wzWu-Lnhл}%`o}EֆS_oixwTg`dY +m[[*f(M4-`r]ڀa*UU+~Q)xr?SzoX#}\$bE)#+N87C=<@5,\%4N1$U!$[uZHj]HԐjFvʐnSBhN9YrY(GI!4&3u?L;ُ-v\7~ı4^in`VDKhթ隕ṚEZS˵KK[uNX[>71|^nG93!i-9!D7P cS%zҋ8Sh^J$;djbb5'G'kGgN+]cl=pBtQV=QS1JzbҢ.e,Z"!]~E{e љ)N4#ˌ V!UPZYfcWdWi74-4%nYr:ĸ]fqq|3e@GGxNl@?^/D]:r4#Wsu9l7)rE*"4'f&'%e$%%Y$$['ʹMZh"*iEd#F$1Df Gv(n俷  ؂Gb^HuTU`͟"^-4aBzFVnJfQBzi\zEtd˨V魖]a,Bӷ2J,(IP4f:M-%ڍm֩hфzԖPeM)ER&g&OҎϋ7M31)ɩΙa,04 w?_m#ߜ? }'1fI= ;8 }>|)툣߯ +uTaB+DS|eKK"4tÊR 'M0Td0R_|Cߢ>ENz}YGkt('G.rM -DqJjy_DUkKuK%W UZT_[>IϻJ׻YǫS۳bGŐ{ u/\Ly\4'jp Y`A+lZ Wx)IR(Ɂ.1O:!D>!JwZ״LuBuJ5iM:U\)LRt?TKޡJv5Lٮzh Z[`C_$Z0+`&IBmWvhB۝D3fFȺ˻e(8(8U;59͓o[!m׶UʶM-IRVͯd,E#`j? ^HԳ 4>_ K(KLȧ˖r.sZ"rX#a Uv~2 "s-"4<*0)0{_h<畸QQ7a}gZ D7p^.K˵~).㬗,{#| |aoϠ.{f \O}/dQw Au}hUWcLr AZ"+3 2dA6FZIcC$oH! Iy})o!$n=IGk.I9Id0! V 1s#j6~ ?|vIoW&z$݂ķ;v_l$T 2LSy!6L>0[s-`m@?h5l%*@xsXess]xdextf)> ѡp: ! Cx또o6!q>Bm^G[Gyl]o7nĉ$ A^\*ЖVuRW +?r/l69sf<̼'Ppz] Dd86<<- Mt ]osHn@@翁 |,Du뿩pc5yg +arELj| r•Zf Ee[yUHћDF6w}C F~ +; rn z |KDW5k/w4!>|O D?!eW4pU`PEn}\F"'WN-|# t7?a[(- KBz큻nFc6آ_ +P +p5 B]wa>s, +3_1¿5Kt^Atz mrV hgkt3$ +NOU'Xz \Ԁe>%C PW;~LEUyv gOGvvXԀsCʷʟb}Cu&cC|8.ISɣ1XL{3k=xlMz<[$o-rۂcpSgp b9)Vד moR(yiE`F0hL* 1j2¥D#E_-^GP0w_Ii4C!:,5ԅ/X% +I +)KJ4IFC:$#!}!áuEsòЋ!/{B>C3U#X0#М)ȱ-Q>Ɓ/EG"s#"+#i-l\T'rJ+rNgGuGkD97HV)msT>H9"9 ZxvOС$H%G)ubt{cKcb;bc .1h]iɰ1vQ}iƵbTVǨ`X:3T + ~;zlRH1+o8M!Z&[ӕߑe0?%̨9ָ1Ť!d^imiMz]f'6/MxϢ$'09| )Ɠ=_|?^icEƲMi8ljdH;:MF9&u)Ef5)U) ))e)K-KRZl*L9fr:7mGܔɬ9` EuОG!`XZp! SO#/PҒՐ_bTiZ̷(UY+k 6y\]r.S] t-{`ܞ2:Hv3eZ;JtĆ:Jy-0yMA^E^QInYaNU^vMNv]Vv}fv2{!={Cjُ'f|gu&1Nb8vVYjAX6 ?ᏞJ9WZPK S_+)VF$fYeئTا48$t:& :$pH(lWx.]LmutZSucп t :5ՙP}#yk5ZUqٕ)ʊ Բ|뤲2yqeeb&lglXG_ +/2[˰һ%pШYF,,C4 +;fj ٖʚݙ&a^c4!F'> y4."*:*vUxݸEX&fuM^5 $/Ӏ*U~"̓G.-=~)Т *t_~f{(-JԖ7? 5844uiHIpQPF[_S4o#kqx>Ў>xF {j! +gL$c#{Stz{zjzZ{u=u=zi{KܳGrҦ9}c\ ||V !kSbK[Lы}QDIpL1\( ȼ^$CC{EnC焮/ ]}-t^xGJXz4{q"{q'kqt>W PȄXN'biB\DeQ*vzQ"n>i%x֠I6Yއ~[xuJEEzAA PW+pz~W"8ԥG lD8AzFa +<1C/^)t+>dnYxhg)jz:~g: +S1ݨCf(88&m׃g<{2Ck\yEi0r8^:.i:znaL_6Sj4" g)xVk5tqzrޥChh}k'Ǫn. ^pƀ/ \ytS &𴃧ѷ5^s߃o`ћh)zw˰[ ÉzM rKB{y7 tɤcB:"ytPBEOixvJVv:nY>";IeWi ڠ *ՀR 1a8yS3a%9q֏)0v*3m&դӌbd6NzZg֘)˴UZiC,a?`Xu&L) +LE` 96}V&lifh})iZkFkzhav+izwNi%f3fa'7^}; ǁ!Z0; i)msu7ŬsOf<JrfG-3,`z.yF`xFi(сO;"eccҴcuctb*jccb+bF c Jcf cRw;-_Ԝ&OժMH֭NЯ3(/5,1*o1.J1.LXl$7aINAӬw3XF@_+ flv,FjڗE]Ԗ4e +)%iQZ%)EYFɅ&yɕ9 fɝ)))R7OJy<)+/$0I^Rց̓΀߆iزX;$4?ό򜘺\o~UN,+\^l0T),,Sm)ʅI喉 ʽqG-b/_Ǥ1IgbT0֢!4#}( DK~1XH FT[lGUE"aQA4/?Z'+/@ncSbScjo2:wETܳf7r0 ,45 bMÀ˨inE,C +AOh#JuUTXSI+SX+-dFj%%eGUGG-0/3 +6 -mR|8ύ 0(`MTgME_ցyڿ2 X i2 'ur*3:'ʮe +Sk¥IձqUzUaUơ!U V:_uCWQo>e`S> oA,h~>x&KA(ŖZܙf?)T-lLk n( l hhoU45mܩxZ̫3ߵ 2nWLjijcأcؽȵ9KBZXc3+}W}/@alZ݇B {ʆ" +[hD! m(h,c C>1@}T6P/t8,8 LOl3}06{XU7+p>!&ܽ16wt8tImLc̎Nd2AƓId8Me;Dړ}$[$6Z Lnp_$ZƪpQ݈vLk&h?|D@DZe$lB;mv'fDo&=& ms#f7ziuк~ tOGP+wfhT9@y`h74n9Dl-Ϳ(& <hh[1@n  ao:,_@@^o rA"CDH!W8* >N#8;c8mD/G ُ7Gw߳@)Nd>-pѬ]u9Z{Ф'Z%O+,Ѐ)7 Ø +/`*:>rlCi$K4+ˣ-RڬUMhV+iZt&hRgF+u҄9Z<- Q#F% Y|8bŔG]1a?/fЅӌIm0MiLZcV@SeڼV7 +6r)YNҨfZb[!k=Zh[ >V,=|hs>~7ki@mi7Mه*8ZF9̱+hı86bNrAZ贒7R.f I-^}~3osRL]!hKoP. M[azg-tn#dx$2Jf3YYyxx=x^i~v|'M^on yxϋ࿊Ҏc>L/sl|WL}Miω|x!~E,"EУt)RAF8_$lUt +&ŘJT?+?,L\I⮤\Jցe%bp ش67GK i0ĎB^ۊŽ 1 ;zdgNNLc7.6PT!)FhGejFDEFeG/ˊ^^_[?-AJџ$G'Gz)KhH[hH5ŽecHQs1էSM"I!,M &Dsur3J 񭆩})cI v'2(&Ø cXX5^D, ? Ð7u +?Ž>גyJVPҕ)IsR#)qʔ,B*f㸔^ؔ㘔5Q)ۍ"SN\3 K0,75 KRۓRΓ=X`^WÖ%v4m*˵\'&?Nj +fh'e$%ddfEgTGe4Gdtg,1 +˜4 ͜3 ܎RG;[`K[iQu2WݐijnؽnVV{TZХ=sbJVXj<sl"Y^rȓL3_DᭆjC(ZQ$gkȽHZ#tmm.8;l;<³kʳm~iop_h]ϊb<߿c$IȲ{4(zȧǔzɣםzɵ7q9zyvUmo+c3XE u"'ȸm2L3m,po 9z^stI\B.dk$d},tG|+d5G`Q+~.$ʀM1p'2M#iMxl"$O%x> &j7ޮdزl!'/AXB"]M-16m׀ `(iQ( Fd >` F3 4i Ӎ>Ưݪhts'?wVܧC,߰>Wn}h +g' К \mHASnPC22Dd.[}| 9 QQ~D#Ȫ`vcLe@ $" +Lv%?C"  >C!qaRr! 9x/2=c4_ƝB (HG!#DGDp'q81Y$ŏ!! +d \.[whNjWG"b\|h?ʃ5'!mS݀7%KhQ"y߹MZsK;8 Xp ė5.O=?{Q6$zCo'瘘`%:Wp *"(O 1@s)h^<8!i'|EW$"!$&{Yq/2늸9;IК;TgQA(Z ~:gC݆P`sHn&!ͭ?v7.傧CuAAvAߦ-״FRt/8i%+<)O5Xh ;6Q 32CR%ٷ$YK2)Y-@qnxwTh>l-h"9Rl=E3E~`aPaؿ0QW!-,zVKZEq{&[AkcB7Nߋ8R\VvnTC~>k-}lQxVZQp3Tz3@oe2^Y.tUV +]+[Ε}e|ʍ|2@^#ӺdZsgRYi0wsv1%^r1S>9[}#ٶ{M{YGe{"gY{ #.2h!Ӷ?J֗Hi5!&YDN2>dhqdDeL ɨߊ HߋtH?SI֟O*x}1@.01Q=b:X:2g;7DD@Yz`4M"D1B0;YWhը* `һZٵVeZM>M}(7`3 T@7 1;6' 6M]:5'¼lSCi*>{ 0A$p`7c7I$^{.{`^.B"\s8* "z'bbbb=YYrwA_ĽDAp~"D! ?{Q&$'Bx +88]\S :yT 荒@\\F'5 +k7,#a}v|O0|6v|>|&Q@=O dbN'j]׬5wG+?:;?1A' í|H}/j +M^ZOwi>|7I A=BӯPS?C]z6NCPTg8+4{09$Cw=* _Qp4iKQ=e zuz} +@C~Pr|%>|μ9pŠ>iK>8Q:!йŽoA= U:we'x!\n |Py!\~HsE^Cp|Pp.KAk7`xjK"<1V.J;bڊۢz1biw4k֋O8:E+ <(aAMJa611~%`dJum= ;+UO~fUk@ޔ@O1,QOc^ W , ,5 4>vDlF?YO&`rxi)"c Q4^/|+ #`h!I RNi%'-8 W"?uO!SԀ\m "c)xEB)>cZz,h1W1bڽ~ i`ߋ$ꔟv4_jZtXw0zaWpwx݋f S=)m12e:4Mh &Ҁrרz*xuϧv^j3VlLPigՙ}LfQKj0ox`4AB>h Rq+Ӡ5 XKXQU,uXPu&ZSu)5YPMtTkEUT͔|#q<Ao ۷P[)k*~âT*Qb(IqX, 8Vr H1azW%mтv Ԣ@3* r@&/Џ" *DԀM)fhOqnLt/?2!H)IH%Ke 2Eb7q'qLꝴ^╴Wt^/[7bR8V/'wF}'-ecy>o*N5I)tcNt +KÅ8_Z'=W^.Jo{({QrZ#tQ8)_8-tHKJYpVGkVCYHǛ +(PX>ZPP#z0~ +On(+'F"t ]rιǼC:}n]<ܗxVwVY*=Z{=ۮއX~ɀ-Q|KLȻĖ9V[CU{mkȪ&,jd^SH55d\NF5CdP3IzIAyҪt 2 8GD vxhGؓ A6f)7i7;Q4~s4vs.ɛ+HB6 ~5!iտOy?oԲt{!P@~/%Z8JʝŁ--=-'i1mHBn_wӍA֍FtNhNh6h- mP Kǀ^_NTaOhO|f AaB2䮞\0#aB EkQ1>6M}( AMOⳬUIvr&hMH8 8@2u8|1^G.CAK! bG@s/Se/ޮهzz\%p_8~&NÎi͞c=H@&1ǀ >=>IY_Ug6C˳{62{o0D`a C̙BHv@"ng_s. d[hܡl>j hNC9A# A5ˑLc:ձ1Bvx^_# A(0#Dk.5zhMf]w6G!bq$O Q~^t++˟,!+_\cXG9z˅kC!ސ!^sxoI=@v xZuH}h>8+y1NGq=>gZw9h/ߢ8o3~GvvwѬ?X^P՝gQ j aq;R/ 3?Bz6Fm k4ؗoTgP~h{& jȹJBsNg +p</ϡ?zc>*{:(7p}߾IwU74w>y.?mD5B uꙬS1SMB_ }y Mס^{j_P/A_\Gy$خ//6i}LsC6yhH|+p+<(?u)C=j9xv<} (Ǡ|/LIzsEsEu݃x"9g~ +G"ꒉ,@(G-8d[v3rWg1tgi/x7J߅Ξ`;p_ M( +sgN[yy +B)IG8 +Q~9ʯ1CWw"6vMh} D-ZVﺇfȻW5t8|/KLoX1k5Y4g+F䀫 +ZQy[De_G?JM+ E4O|Ĭ +ڋ;@QͰk-2! iІn4 Qi(b[Dr%kRV1jUQv5iS:5T3GUGR*Me?PK,)?|i4iOnF1-ԓ}32pvCOo@-FdG )ToIu&TcRFզTiJTfJVSV*2?L)Mʳr-S97c~߉A/y)`%1X'raL͇Qȇ?djLa6DzCXa`h( ,G+Ջ}û>KD^kD;ᧄn7 ]bVr< +1.!ݮPCY}=[zaGڦv_1"6hK +vhw&0ڏ,F'D^1%"Ϙ:{l-vX;)p.p=w})>}+d#H 흭UCYsqZ26¾r|'£$m +J4$;R$oL'% +\2.IEZSr;!yog<dzM>X'?X'}X%ηL` ~|p[ ` KlD'J)(KiEJ'r$ )#q̈g2 +xՌMfc9Xf"mdqL3c2I1IcyƩ,$;'c|;aK=l)_S <]r3#<;w#|_!O%jgq#= BB$@JKKKB[oC@,ϰݳg̙3߳GĽzUTBwJ;Į@+.[4]zhNS#mO/Kٓ{q #gDZ+uZq (qM,q-b[W+u#ŪvX.ڭb:h>"oiĬ_b^"Sax힂O(#+  F|^,Int 7 L5 c+pv@d$2a|{P6"2LEU_+G,dLb䲀DG=DAvt^-D mzl2Y֢({vsltzu"PrADD29֐AȱAn-} CZ"WdY +edKm֡,U֡@MU J"! dMr$*m'nk$;c'\*'V إL:,6N]n]w&:AP'7XrHO[INaǕ@O*tc'Q q3iWFH=à>P& FuDus-5(PZΉE +w[b~8r94Y%cu/uJ;Dܩ߲uO\=kPQ+`Y|?Wאu%|55^:(+9K DjZι<< m]ڞzIõ?HbߠK B??'`ZsQ`e\F04plѺkWr7G.7WsOu8bv_,^~W, -u>9}E@?qq^^g2A.?5ݺ!گQAhi#iK4Rv+a9"؅%o>u3Hm轵XnC?~C^]n"@E+ >_I+H&k|#BPbzrD!֥3s?PF ;wB^)~1JO<9V 2XJ,fO\zeokLzl:3 +MVl1Ha>ifꐰS,e6?x+Z bӎJ+h0xԭSS3K@G?Fu?R/ӄ% ԟ'V-|ݩ-~JWGiK9V^5^ /#h+E!_f"8лhC"K^hIq&2$_FkKɴ0f| 5o!e9ڱX.[dVlyNj,_VIEP~G2C3!t2B[+?i6`"Cmd] /AK_0H; qT9.JT8N/IԢ'שlu.7$=]N?ͤ#dԻ uni-Gj܋ڽq#0+ӥb)(^y=/ݼ>BkPFRս@0y=/Sր$"Z/+}}B'F*}oTK_2)bQR0E +JAz ܯ K&3SMf&-&-&(K^'VuW%]ǘIڋÑc`T:HeTIyPtT)Ζn*M~H&7t&;t&+l&#lIz^԰3&aϘ$} ]&hBZL$ ǔ@HziCaI"5lEtwp?)*]%k&k&kIVDIfDIz@FmJmR\mbjmBnm\imLSёDD)ir/JNM@`729ꑣ +9b-[xKNLdtդGiRcRLRbrɱEڤ +mB\?m|0fӘUȄ]ڈS ڰaqŵǶCz'l#si2r4!GrTgE)h/I/)aIHJ2K&jMF vM O K] IizIP& Hj1SHʹV] x4G997 )o2%)U}$.#Db2"5Q t&aݵUڐ&AYMfd-gmfݦz\xglѢJo1 ݟo#[ũ؊|S:F-$&Q<%"/PJh^&8?U /i| +Fi WR(&'ŵQqG\~Ҹ涘h1Fl߯NlRf<d,VrY|VŠ$MK$$TJŧ$YKūXG#sE̽Su(+){5RߋIY_qFFB M M M&& #L!*@jxG6= [w7b`9pp|b!MQ K>H!BUAfQh2w2xn2$IaLuD y"J8Qd"*7$Ǒ1EBt.xo]_YI3RLtDF_dr@GZHt.o:A\ sd0!̩U'fѯGLN #/ٷT]jz&u꙰y? r]!bB+B! +bF%. K{qW1o?tgL?lmh*4^&| +]u({}N+:{s6(tڦBQ|?v[M}pP= %=H<#]hb9ֵ"ɝ丛,Iѽ99 4tϤG#T nIO 4~M?)g*B2D϶:r5({rZOrF:~ +9!~E +F}o|+W6 +> FR$߀hu| S| d1>6G}[5e@L8Ad1#;WғR H=ͻw@oB.(/->G]DQP)pr=(k05 :o}@]yAAJEr\Dv\=>.96^KÄZ߉r>V9 >bMhObx@w}Ss#ufLs +ϔwg@wO@ p -?- ݙk0~џ鏧ʼn6«+YX~(G9؇ z`|F}|f+ 5H^:'k0Zӛ 51Ex=Ih;a (c$2BAj 7Pn.Aҟ3cK^o%YK_J4ό>LuW\RhS +U + +xUë3>ӤTc1WjNKoyO*L~&B-rʑ`]  |՟[(n)ôARo!L,UgKB(ʲTZKo&,=KRfGJmNI)yO3cN(w([35 Ky6MF :`#5v!Rm%}}+=ܱ\;VKc8"y8<ݒrJ].H/Pd9ȃ\gR=!ijdY\3HAIZv.R -FJݒ=SУL +,/]41]4QȈ>:Mxd&,j&$j&8j&0& !_eADRu?Ҿ*XyoZ]|6N=d0rFR$,؊]W:C4Jj%|WcW"l% A!@to[/CؿGtOeCYMS#cH6zEdvy`Z[ )=uF,VGvR8%s"S)NVסCeg#0}0\gE{qЋͲG7&I237t4Eh@  ө!z@` :oO{wRס]řX`9^C7T@&Qh<xt m&hTqq @cqʥO7z-t?J~Sd/;GeAً,Qm2/F ' $b3pf$C3 dv1]L3 NU6U/c r,OLbcJ^<{6if>ެM,#C+Y@J I a뱏 lt|d2.6TCمn8xӡ&^߆ CP8{V ֟fאv=${Qc/ ~|V*b9}"El ןݗsض#&$ʽ9q:6Δg=Bwgřu(u(CJ(Gr=9g̉\ P/Ox }i">,v,/^(iT_ m(g"tY(g;oyֽ2<&:y O ~~^V%tY7pql>X! KA +(}e: ݝ(O?Dk//a< >Ї|-K0'RF-?|\/o..DבxeP gAAπDYO czs@2؇zbwogc*灾{,hP͓rN`>`Wϋ?"bΆO1WPw5!c8u=gJLynQfB]=i=t~ 9gDi'BhE,|R_+pjq8c/x ĺnA}w@үx]vk0s0> H|W¨@U? xgCe` }:\@OdVޭi5 n]੬m-FpzX>րWWnv!X},W"rB,zEw:V`LկP-+?/wC>]Hͺ5ZBiO |E[Q'19f! ed͑H7ZiX8sFMӏ[tC}] G,𭺡ȄvڡCwZ@±X0>Y)OLB ь12>2jFC`&eFnkT";́G2Pi#<["=6ҦlQRxW N0h?ZGŢxQOR9W\C!S9VIbM\hB xx+^*W/xkҌ*r,6QMaDDYa[r}V^%[BZ6td2hsz]OWhWr KOM 2aRj2N3vn|ӣ=/9KRMBLxf?)UDY"~iufRcf/Uf_*ä"Z[$JeXIUZUHuY1e3]2mJI=*)%$~5Erb#<))9}Sao)휤K>\JCd;dJcd8u4*Iu$M2U\Kfu=".%5tV\<}8p,[$Z߳k5AW{V +\$M\}%-D"%-^$=W,ݑ%~G'il+I.-.A)) %%SR&X։e(1O!fi+DK4vO&忢MYLZ88~?<OQL5!W=%.CL&,Kqt,O +p̎t1.mvh8ePIγH~Ȗ2Q(lG9 yꑭU`otNĢNLI7{7IeٍNFE +x'HXH^(] ypz?&ncջ'# +d#%OO?7wlŦB+62y +1#DH1bVNrpM9  Q/cC@5ս8s) y$Rn2K!3Ce J m ////R%L*&+C_sqw{TLXe/\0P&REҵl<$8.!5) l .qAQ(J5dd%{i6xod!=p'YnL+Qh K +vő|E&Td6Gd$ |EdCA?e~r7G9Bu{q&R&yܐKSS)$>Sئ`SŤ|ItD:o4.ĘkSY8L5z%:@ȓ<F&;tDiL|1?9棏$!H桋0c|I I$_,ԯCiW8*|wq܈ro);nCí>*Z?o&hC:ceߛzkzЖ=S;(((}rww#ZmM79 Z ?W݅.NaI"gRw!WFݽ/uecB̭f$)3h瀶M5O[a?^!G2g( +ꯦc0<e r>VNX63;'؇E}.{tXjLG6Ļ9#(%o[8~_oV_,ɩHGOu*줻ZIXHedXFHeZHU$ZIMO'1$vD͕p5jWB g%c UZNQס(g&Y,3Hٍ> +RbR, Isd{wIxuhrLCœJ v'u3rD]KI94gX% {rEa{)F +1i&j#Ѯ%]$-\Bb%=Ev:|R`ѹr`/݁ y"@lP.&>,~>Q$޾YW,~_'%`8bpJl+؟vv^02rM.Bjl 蔃$Z@g +@q*nA!)8 & &a*tX&fyȻbX ڿH{QAs7r' 79$oZ[{SWq&b*6bY.g_t{A, +@!W*|SG"h)Sc(à1PpOЭG?q9-}(x_M0ͫߟ~h!JG;Q0IMʙ3>\} {zsz}^}g~xM?EG{f D٘D7A[CuP3b&Y -HqPwK6zf ur&ֻHڜѺ^3PxP +uE݃{ӎ:4l 9 f&lc-j5V! +zkܖ]f E5&~ +OW +o= c=XZ[ [\"\Kc1Huw!Z0 Τin5]v}ث[a Ogy+F#iȑt2;9f! c{ +&X/u?FF_(~=zapnytBI[hKLE)1 99#8e 1#d85ahn']fuxa-zD~RSVu;Ӏ|5rBDю_(9bp;.QS V>J7 +=B +t7) e+C +CZYQN~ 3҇W+J!q!˧?z9KwӒ!@CĬ``:ڥq> 9|G7)^]CO=R<ɡDih0KM D6O$TNeSb&|1%"eI.x褎t'~R*~<~_2UU*qh.ˉ& Dp"[^F %^r:A] X Z2 =.~I~[Hdj!)?I҄HIęK6MiZ*]*%̬NB̛$bZ,mkqB|/ixZ^~h|ZG*:x,TuL9vS@ߤۙJX8IDXKUZEIuYgIM_ہm7R*Zk1SuSF,[\ ꡿~JYM: J8yo%5ҿT,,`hƋ&@@o*GhnR͕uyI5YY-2VtN%3D샬:I,="8@BiHf&eRa(c`6@p#A % yU$KNn"]]xkP0T"K d#K,߸H+1pM$s$* +G€y Q4&`=F$0M2 ] e/2YhZ$r`,&HO`etd"HUT.RM8%'3Z!CUm@꙰ P37֩gL~r&+jNd3 6$gFB(*Ac2 ]3mDRɘR!w Cu(ʙ^<7@NS裘*<'`9HH7nNQH qBc/TT`.r9d-_P5 2R]Y 5롨 +YHpt-0P -AgA(?z=t^w +wWw_J+dnݐCYKSkdx<|_G2F]KSp3q1aFQ $E?eM +.\hj/UQ%RTN&lׯCQ΄]_ M+w#S1pd@^+eރ~#Eh"] ʚǩǡqvhZb@Ǒl:z-_L\Xy1^Gۇf,r6 s rOG'×|$v9Nh {l ջ״gz/N$L# 11zR֨L_/Ӝb#ST ( j + x2f2dr&Zt@e*in<'_R,nC{qZ~^Cbc1HIHpbqẑ odFL3a]>Bvk۞{=9m߈N6:wl fm.6a&~*!2[%eP ;5l?NʃĎIpc8 2vxKeAP(u@ֹ9fnCnbƽY@S/\u(Y~w6?fPg's!wi{̓kBgI6^Oĩ/㧗0Pp䮿?+w|GFgd> -Kd//^Q?G,qN{=꽰`yL6w= ZS'ɻd—ɒ_#g~9 ǑQ#`!x9Ӝ:>a܋Rn0p6zVWD^g>O d插?@6h^q78;tLS;vImaݎhmb~c>k@xQ-KiԝG[C2A|cL=ݠ8Vٌty=ZnFu +mUMN61tqy> ۉ;CYſD l\9/k@pYFɥHM*.(g]z8򴆟 5x'X6#Itϥ"Y.=/ .f0]$&}1o +;um𞠧K5(|L +5f𴇟͡rF"?9nܺd>QXQs4<iC:Zϑ`11 +9FG"2+3-)?M]q-:za,Is5nW4-ms DKH!K=DԒ` K?[2Y@䳔zZttC.܍+U3?խB `Nbtx«^=^Noz[E%xp.C$!"(ГY`mu[ݠP[> ? X8ې28>Qb?{@T_;PP O9p6N݇s~ݚ%y'~W*b0V֡PoTePPIG`mH!ׄ(?$_ v<Ř}2% RaFkjfniemcg? 0($4kDdTLl\|bRrjZzFVvNn~AaQqIizWVU?``ݠC544zq'L4e3g͞;oE,[b5koظimwڽw9z8u]ws?C<|ꙋ>‹/x~?_|7~?oW^Ͽi_cBi-mvPJ=f)Jˣ'Jh~7e(> +ZE C- G =4+&+.(XhcXchdN܉Z*z_QhqE5O+y弬huE=o}>STP/~W?-#&(Րj }]WuQY;+:VZ:3R ֪/hLL:[XXZZE(#)uxzU#E+:SRb`L:+I6 9jLISϚ;ђ֬߸yێ]{8tx{h}&6PgUHZI3i' }u|[?H_iWm[yW>Rǭ7|v߻+7+ ?Ykl=My\ʭ?qߴٕ .WhyvӟqtH7.p]$p77punTIyQ" QY5+gnT|Ծ>e ?_8sf2& kDo!~rU7*凤ܨR/Mintߠe1[yZ%ޠKu&}Tִs5x|߸vn=zs7~clAl7oX_& Ӈ):w}O77r1Z- (uc?6Ea 0<:UH }t>LW hmMսm<}eӷ߿w8?Є>CogM} }ت7t\![&a-5C$YTG.\/a_>Q nȷۮYA!m @M>k?6I_tPŵ&9ء*{h؁}r;712[v?z} Ӈ%ͼOrdaSFѡ]Yj&:}-oLb>vH~θ޸@Mnj _ ,i4 +_OOGQ0Íjl /ߴOr[/_ uSK&(gjُtn/tP`eFx +zvx-0ĸ@c;Ϫ4>? +nW (7c5,з}:q1L0yհX ,AW_|l9a.!qY}tl2߽⋯w<'N?g_ܻqJ]q谿l)ӕ_f$'XvR#pa!FPg{ݰ8YcX ̠8ϟ1^VH41,`0 a/:7(Al^뤝F>ʼ}f6iv{{WLRZjG>.[;pL1m *ڙ Ļ?7(ݠC 3@k ,fg`Q cT`q'A caFrf~;C}!FgK̴μ{Q҃^7*  ~6*`k +,n3HՌ +lj_]3\kZXa +1,pѷ}QFF1jm]|BbRt`׮w?vUGݽß8>:yH]Xmm'M/ i?}Ɉd812y 1*P |~~ػ:q'VF ~g4*о@oe7D QxdYoX ڠ +QjACYlP0 ׸'\rN5?Pد/p}7o0i/=;}bn7l6>H+q +b\F(0*zq:Ã; ߮FYR +L8_0qR3(xASF+:Gi{>)JXLRvŭ(NwOO78ʩCofj3n4ଣtig[C +L5.qRpn_ Ѹo\?A~]>g/X~N&AK +4w XDOC +3o8aϒJ', =iWqv 3AYk( + +sUg}$c#%h@;qM, +\2fl'.4*Pga HɌ;gm,m31_]yPGO FIUA( +B[J9(ZT"Dă[\VN G9Dn"@@FFTeH*uPv 8Uo/}~}Bwooja qגjm C'"Ȗ\ 8λ-)"IQj 17$~ Z +RrB aD,0v%U +xN0-6:!AeZ6U-u}s!<tW;(oٵ^QʬjwxrpP0Ec,Fy ʍAp<}mTLaڭ1ZFZ/-er%ȶdtDl.ro#O;ywNMIYBN+3_hj(.WXnuD$<$^,P<&x0?Gœ&M eMP,rlF iQ*̺B+D* QVg:†UI\3.!qi@x8DGYZ:޽0`b()H+JC +ISq$\ĒC +<0QN92G傕poMY-5;<?Mp?~f۶X|kblj ZLV}PIp>C x\(Ĕxe6t~;N-&ίH)#[LQ$}yHpJmF`LN=153m():_xUO \r94))"Y%P穋nO cpS ފ>1TEge0YP¸훞O0r 0f.fQ+ s-]$UF}ݦ=~qŷk "9Nf26:'8,ftXAwd=3VZBJE*[P5(  6&bU1;L%Lhj XZ0grP}\U3 S"&a`w(蒚N):?" CǽP˪d߼ EOc=:Z[n0l~< d0fN/`BvK\y+cu0#bVkHO3YUD-p}B^i"b0]x~3Fn[>멿ZYTV:*J +*+tA*8@R e2f<8ƨl(є\'7!zg\`1P]o[pxG2c[mGȆ?{BtK 3248ɘ˭^GCI^V&).&&.!h ++Vv +tmDA#T`~TU}RAo c= Ri|qMX jjSCl%ɾid/zFGfܛl6։ޚ4uv P[BKzUosԫ~aMOkcLI0,1J ! LKv[}LDgHZ_R=k! i;T_\Zɾ҉ٱz}#Y*M3_sz؀]nj> +stream +AdobedCV +   !1" +A#w89Qavxq2$6WHXB3V֧RC%Ubrdf'hS4FsDG?o7C84֐9u3-YxNb*nVu h\@{ L9ӧ+m=g9B jVlS8#2wҨ$C;PN%P_簋fh-ƭ.F)E"_3+FhS9!K3odYzO(B*J .SUl_w +d$G)oc1c1c1c1c1c1c1c1c1)OA0⼌J4Y0Ց+X^  @ `듗VMhT#lMcɷjaH +fT]$>1_o3'/ЩJG)0ٸ;qǓn +I}bGhgW鱞$*BM! +L}BaX?d3gcN1czyz{ihH)I˿kئ0pꨶD9L`#=|T#[̄[(ڈ9I²ZJfILs`8&McJ+:tH$0qzIh6+IF3 Gط +Q]۵A 1;Dr<H,]UQgb@jj+T/P/SNC:5~ZqUE[ɨ)')?QW"Pnd+(N^?P׮tܬgČq-"qnxF\N^7P׮tjgsɞ>QDRN9}ͮR~D23RWQ~ӯ\jžwJrhۡVf+qjEIHE9vN)ǩLgrm5|rs;%^JR/5y +}7?rG)D +lN^aDILǫB_Ms-ܙ`aQ;i㓘ؠ*Rx{UK齍p9L =J ?@"{=1c1c1c1c1c1c1c1eqs{/8dv l^!d,mں7%cYiSfvA7HTpuNySO9}[Ap~U̯[5%x=u\ +X5-TEYp?HC3_Ok'DpvWLV;%)xM}^} X-VEipOHC3[M9}[Ap~U̯[5%x=u\ +X5-TEYp?HC3_O8Y7L?IҺ,Bnwu=B:NVjY$jJŢ YbEO/mn5~df$k}ƷD@&F-Fǟ|2ӋYETUP@"S9ng٣Z,o*0I9ыbF'bNYP"U** TUBz%͸u&ެĖ^otűZqtT+6ȵUUJ$UPi,1c=TZfgVR3 888kHKLH,݄\T[.!s[33\ec`` c_LNLk WroAtls$r$D1`(箘DJOGA>|2""1d%$8heXI$cP[33\ec`` c_LNLk WroAtls$r$D1`(oo^pVӗNVIfp*h)ی*)@Lc\D9w+"ٷ)ÅSAUYSi"IuUT yu+$ݿ'ÅSEZUYSI$e1UC18d[678ph Y*pM$QI;9R"a$nHl1c1c1c1c1c1c1c1c1c1c1ck8r:1T@jn")U>)Q(@s[_SWzfe&ʡ 2sBL:V1M+M![S֙( SznM̳m,ŭ6bgNutn gھfmݚ[jtN2Q +(ЕH +"Af 6/^Bտ4zo:9hJ{ -e;\ J[dԨ+?5&{Ui^H񯐷:\iXw7 zF%Jb}eʨBu)zRh27U1r %Ґօ`3ՋXH%nENN^S|t${Nͧǽv{ H$G2.+j,F$U&q!N 7'pխœTG\2}׉;eIjhPjof^Rd}5,()}\*_]`ϰsi/6D2{Y6DM6*]r9F~WLD}N>8BCǨƩr"y##S +Ol8) +qSCYGp{Co??E#y55Me\^hst{'d[ Z^T +>v;z8eEy5IU7AVJrf6eM@z,L`(ILoX+ޤUEIv̓tB&}C-(Ԫh9@DB} ȝ-wx{\(vmbEI"yOrX!'==m޵1$C{1v&w61c1c1c1c1c1c1c25}'b٣hsabtꌯ/(X:#/ueed1|_o[ 4f=TUгtUJ JS>9TN99JCEbn} oܓRXJeiG"m7YQ(Ho\ +c$2"LJ( +h9JQܻ*ٷڥ*?ݡi QܦDarI +'#c^Mx-qR L(Z 2*% LdDVxQ6 9)J??>Irߐ\M=o\\:U$V:}J@j} 93ˬe ɫS^MZ3ʭjU2*e.!tT Tܲ&9k)%hqi:t39URSn2% )ApCePLq^թͯqߦ bLV*JOMfٺ*z`r\*PYUT ~yj(BK*k#Q +~n>t&W`1kE$Ҍ +Q9өB,IDbdՌKՑI'GeH[Dz:tP+RU5d`F zb? rvSA:mcDBv F ,iiH Oن5BV>nIv/MC( Dq|yirY{8Փk rNF58xgs3V`rr)%Ab*Ȑg 8 -[OͪNؖYOפ#@Lbf|Xv-%ER*Ȑg "8 m״9[,Խgjɵ'#WIX]j .۷:rZTð{*1l 5~^̒v(Ƨrs,l{^Xl*ԦJ!G4c S,Rd[ |Kl_+y+ ]|aevG@#bX"TBve^F"̈́FtK޹YnT@u +t]kKkAٙKݮ$^xxٺSvR&up-ȋ6ł(銇8@FZ@@$֕&RpvE!Aa@o( $s ͭ,C6Yny;'-b) +IQ@h$Nm~qC$iLNi]m.mN^$RQDV͒I ?`ҳ$H̒x1cy9i,+i[Ɲ^@<֘hh\?~4A3)Sc 1c%)?Hh88f.&&f%5ՍdTTc{#%"r"ꬩBL мr3ӚpCBCs'/1/'lLbY$ DUUNRai9-^EIOOqrCA1u)131)lc")DUeNRaQ5͆Z\=+f\Ev4QeYJSI(0JP阣p w.xء]uIJIV +DHueKmjqC7n 뭥vJHRMzHI&0uC|mmsŞFn믤6bHRMUeRR$D(07c1c1c1c1c1c1c1c1c1c1c1ekxGhٍg*7M3k_²ק>|s)ظd$>D%7w_[kpv{Ti Md19qN,E=8DѬR>1)4c +&%HEPMD(58 NC%9Q > I%UMdL,**(&@nSKЦGFQ:< _t38M*(Xt77Y|Bi(>YGeʷxG4YY6xɗ kqAa'(](0DufUQ+31LA:3"ۗ[__VnZl2 bfOEYJGurU~)vE1b9 /y}d\ֳd֌UL8Ud43 l e騐$d`1D@Ü[t/t~xKDN&-}W[T=9g l[o{~ӪheE:+98B^$wZB~`D)+<>Śx9nXq -Q#UA 3Wr (BC9QgDHȬT$<4=!К/vhbkJ$UOZ zQLZA]J&ܦQptqc1c1c1c1c1c1cT1B^4_Q0uFWn,_QZTòòEcd,lǜn *%@:|EZd{!*T!G3K6 qU x۞lUE÷+^H*fsy;<ur ߤ&pۘԀR%!>p8\m`6*"QuKR$XI3t޹*7*9_%)czIS{L"kEXjthjRxKH EQɿ0rLl@b"ܾ(P/d򧷹e_lzYo-`iJ&QO[n F.u( +"x;&45Wn`H<%"ըdY9J&AB6 h1Sn_vEOXp憶i޵͏VW^jڱc.I;H\QGa4c1DO^YPunډܨ ͚ms\,}fk>*u;&eNrV%|\ko̬UXZIbTPrQӸ`T̩=TJWT[w*>edf\ k$3OʝGN[V3F-pZvQ'=odGv$tQI7&܄)cP(FȏڋfmIAGn:KnvΚ) ! +bP +!{#hI>@mM~MҰ.4cڙQE$DR9Ѿ{Qlͩ((YI~MPߴaڙQE$!LS@@D3ԯ1UʥBH,{< Fk+$Hh15")W~2L!f@j>Su]~}ڣI%DƠ"Mdz0}?FdȽZ@o`s;l¶6%d[E "Mjx0}9${]b_߀~a66E+y&1Y(p!zL>`ї發e1:'qYD;ĥ[L=>2 %Rc\]Gy̜Y&sji.+'ĸN1魪~F'Te]ڞTjfk?YeװXĎ#bjim7)H^5;fDwhwSiPa$fӵvpkyl@2?M0-x$ 85Vv; SʃM\>Lg3,V:l@2?M0-DNk?XiLoګCVX%y +r. .Tzuܔ0#EA/ՍSؿOY.є9A@)*UdFN]".v 8) ac|.7[OR`B;cNP6lT$"bf0IˤEݝ) a0DTU_ +Q2ܰC Ҕ7;0UnN2: &.4DTUO MBܨC Ҕ3O3_IYnR:LDJ=nW°m w,!@':hnͭ,5-1R!Is(.EH %1ڪB}9sxmiyfF\ F[K+ +&jI5bW%: [R|fǏ1H҃bhY# grQD\Ȧ*U +Gݥ1ڪB}9sxmiyfF\ F[K+ +&jI5bW%: [5bu>ŚܺgW.dm-і!_d~,G]jSM`{Y]~+ж?@NoJhk5 XX{R}qc8EyJ%=b7*8\ǖFN1q}&7enXk{ ^Enz1!ZFQ S]9S4mmWV:Ӡ%@EGDM**ꂝ @o0֨J_ެV氭KT lӰs&z*6oȟaVjP/TP$Py!罹J\ˋNlt^hF@G @?r4ع;C}%aXWWo}Sw?/OξdٝMnva\I_TwtWPJ9l\条ྒl++>Џ`T}`@_@RkRl<]4l7/A_Xݵ7Բr!&)j&tNrb>| I܁>ٺaXc9j\Zi3S[͡bMddBADz*h$dC[/i}]^k ݣqg8o46#H[:Mdbb>| I܁>ٺaXc9j\Zi3S[͡bMddBADz*h$dC]l7ZU2Iu9t`=fN-G=|KB$ItD&{3S;ե[4-k3niQ`v5 Kx +ؼ$k&IdBL<ߗ[kks.i,GVȱt#H42jr`fjg`]frfm*>ƽ!ioX6B{"DX,C}ݿş hۆxxrf@H ZY \&&.bhDmJ:](xe\v;ITUD.^ R66wNs^&EaFBT]Śv5A"S{ MөsG'xr1:#w?9Wn&2dޛ2]1㥬c܀ +$p):C_zߕ{Q2c0;bf7A! ˸Iw>M1o'5S|J1o!T?4Y<ҿ?;G&N3{)y/vG[\W90u>gzPTr +RDꂿk ^ŁD^_Gr}ݡr N.3Nia PV_b>]9M6wC{fUm,Sc~敬k*| +"Z}ɃXuT'+@۴8.A<~V|)#WU =r>* +XX'Sy1գWc#c`VQi1LzrjZ٫7C7hi4VΤ~Z܊#u)רRg>$,7ϬK7I}iV_EtD'zGSP 6j{3;?eZM?U."HJ`0u%m>"mL9J-mu 88{;:`yXglM+m.ЩT f 'frӱa@@/gBL(lqύ oWfkK +az-P-@D/gBLO+ۜl-m%U:ػ^}v,=u7S isŷv33Mn]󎶸[2ӵv ,Uu?sj%z]L!g7eoeiSTWǠ~u\U,RGkPK>&cW_0w0u[{%|=buTDovn\'1MS>9+|s+Njjھо={zdʕ<<_ul\3jG4㚑ϟmLq(Iw>M3dJ'?y8?ɦjzܚwPq[I0 nԱ6ԄeTH]!r;o[xWXDma h֤@&o}eg} Hwv'DU$ Dܠ{_\S~ӭ!XkZ 1vh+߁Ix5.lT3NOeB7  bDW!gŗZTBOu0ND6~>[TM, xk b& ;&,ōuhRq [ @⠁LSg_yJ9aTY*p0(ErzLY{UJ!_9S +-D qP{LSFK~߯#7ˍ>di7mn3Z.o0LzDHQn͋՟wpUuTn2t&D8z +:H,zKӠ-mϥ+Xdv*#"=^E%J$PXRzK=ۼbg,]x2U B"Žy(,?*`A^"Rfa2[u!NdKo/.Y, K=?53(*M\y{gU2 _-(ic\-eH֒|:Dc:2/[IS$~Wi%eݵR B^&yC\ %Hr|>@:ɑx#|%,K=򬸉hiEK写mk*F'LёzJ'(t#j?ê U*0:.5X|*SᣔVD^$LK7nuv\#'R^'Q6(&uy *QM7HHLzudVi(˫*gq#;G&DU#hC*W4Єz]mJشk6N*c>31.!"FeR06?d.zkגU>Z2]B7 t%ڤ)QK(v +KH;Bu}u*bӠm8PzĻT"j BTEyRmS2Uvn<2i*"_ʽlQz^#KWuᛜ|@*uv%!CMeȔAɭ()3-N]f')Ify9q٩c1c1c1c1c1c1eRkOO GxYF^4_Q0uFGX^k R[c~Xcn.ԝD=4k:u](JoL3%z8?-u3*qjߎH#petP׽d$Ie?ΛlʘZǺӔQc4_g^d3%z8?-u3*qjߎH#petP׽d$II,ѱM!6mdž8Q&U ;DקbǢc~a5nwmݩrGNŔd|`y]㚟CJ}9>NWG9ҳF; | tlvջڶV̧SnXIWf*ћvTTUC1(MOşdU՞d\je!KI*"VcS1 =y|&ύMӶ˱m+WI+:]wTi-"JSBlrx/l,&dVf&'U) ZIQP)a jgBvM_}\ qQŔ3M*!iO$7wZ&T$kM%p +*PDJ`ws՛*# *Y +Y25X邊) ov.Jywu["a;eBF4P:`5 +`D6(hP))lZ.C{ř6K&a 1v=)TNOj^SZ#ghЮZH@&}&07bPoCN!/.3M~\C8lq"bԻ j_srK&EB?b 5}/~EN)RSGxW-N$U Zc>MRIn1jTNC'zwG>()FuZP3zX$S6aPґ"oPDC=A(-*xv9Oz\W,ѓ1)R<ԒNB;F6E1XC-4Ӄ9Rz\@y}$co6FpVY(u9˜ťO\v4Z 2f:E3G:BHGh=H+tŲODHL?xG-'o'$_KegxY+b7,A,XkmmYڦ;_˙ +Y^LQI(EEHj-yKIEhX('yyXU˖lr3 &,nHL(RRlG⣌Q,iG[Kb +>HAR]Gj;d8#Q^ל䴔^֋%Rw\l.0pbFTnŽ! *vɤp:J(A_:|s=KQmL*<і͖iry8=Y2mUAإb|ˎTcZY\-NG&#;_AX*kuHW(O +8vGqUh +ڵ,{"!a7=a]T7P|F!9P Am7cQ*ƴlZLF*>v`U ꑊCQ"H" p{rZ'D\NYͥ8crR[>)L5%c+ +S=^ +!JP'Ԃi8.DPiAݖkqa#>Z7p`), C'E u )S:zjwe[gXвvYǷxRFIGהoz@. [){ЬmCRu٢lu*3 H|NXP~.ݦ.I㏇D& +R4_vTmuY#'5)/LHU1zӗ'S;dR8E꫕d`1p{ &EOcfE +k̚b(U0)@~e0z1)&gǻlBR8h@CUS ?1ZtwbG V"Hp +`=2=q3nݶz!T)4Xq!Hp*ÛJǿtyfIT? Ú$R-6k?O聮?C9|kәoI}I ۪L965jss)21L@9s]^+V&NLRd];嬎#v\F$"%Y"81b{8%9%m]4wRٻ;N[ԝ"b9oSfe1b{=\5LUj; 2a͵&NӸ*nZ1hebL΢"U#(5[{JF}S.TQ]^f4nv9㨲trjNv]CI(~6Gqӵ'} `p 'b uN?iSxJljT:f{jpj>n}~Gq0ӈANp ~Nܯx˸i:eOw;]FZh>n:v/pw3,9$Wn1p$N:^=_ASLV)\&鲽)5(1S{j'L#vU0hb߱d9gzNZ,G)`Tzzf4#c(OEkƯ٫3\`Tzzg+>MϤ&gCzπmpخ՘h{&<_֞hX$SRAJ<tOZ"ݖ/ ?rl[vĄiN۫QSJ*.}¬RCyRમQ\STs4V̓ U[bc@EKz-Eb$JEcUNRxdb۶$%OgmMZv_QQsfXȺUrtssO6WjEV`[lNҺ)w^οIv.qET+{4ݺx;vi2{@7ukiG]ɤGRY^=Ϧ* +S .W7o e/Ps^l$S_G7AKwZy +k4Xs銂$T NZxܚnIӼb;A4=l +Ժ5#ݮqbe#),r/DH)cG× VS%ؚZJlcU!0qp?"433m#P(z(NQW 9c˾/,OIS O1?VP(zzwD !\\)x18E=%Oȍ4L[H*{T)7Jq{@ yP&^R^h׮ȥ;ʻcum~:r>Vovn=\KGvnp1pa1c{:=r"RgsHܝuWRv&#ӀvILFpU):fٷwX9۬"ҕpne,lMېvI"pY):e"R㗌 {E7,[Nøl7~ DR j܌ToTPMĂP9 jíNk-y˯u|TR ֪%#j-]RB5*ɝA-Lyќ&w% ۗ{^]ҤK\5RdtE +U +b,VL jíNk-y˯u|TR ֪%#j-]RB5*ɝA.\8 X:SeMcLy7d2:!ۮ&%(CEi!6'OPՖ0kuT"gą;yC"SL R ;r`0$@L !n[jS5 Y.rG ȡ1!NZvLJ*-]80H@&ΆNBmN3-a(EL% +wRDQ(v`I!@y;K)fȍ~A6s&v7Xj+{hS1Y{ p1Q)}I2gERx|i B#Rn@&мXH'%'$Nu*E1R'D!K=|s߼ Rqu My$OI)TbNB66ӴFŝāM)y4OJNHTbN&BOﺷebB|Zf.݅OQbB|Zf5++!Vm?CX5#%5++!:Y6QcyG>&X?]E'qX#^}m,f|ߟ:||0\6.l_o̧m/yW3ſNfyVqO2jD7"txhY6@w`zIdbʝC,R9=$wFcMPH71ssJ;i&bz1DT +hjU:xs-U9 (ɩlݴU3x}gKM$nT9}!l銝Rvkj/r\}1IW+,\$s mr_YtF?NW Ru1/ϬIiyBMʕG8@CٌL^c>cޠ-|} V].,GdOI\ȳiK;x.xmE4&]¾iMԵbt + f='dUI-`P(uvFXN;-V9Xп~\!Uxs$HP(uƧsj.4B> mJnhPk1)8"NHhDSCwyw t)9 \joߪUWXߡە΢3Qcr zwt~\BFo _[2\+nW*(`g˅\QSUNA02Cɍw y p zuQE:\*sXM50TN3W̰(J[ʊ.(örc-c4TSL=:Xu'+N^U6[V<)XbPI4&L!z|K=q!ߏ+8TlE!H3p(dPMBG0Qg$<{wGMȢ)n̝ +)hB&>̱c1c1c1c1c1c̟AoY [S TCGȿp=,@9GT +Th~_ڕAqoWDVdE6:`fg-YdSU3oRD<;r'AR:E{;vY"H\A Ub$nIFAH߇7C}Cs~iMݖ(5f܈R;qR2cir&2,5]%ˢQb?Y1c1c?5 }ȃ.쩴đԦ{kHTl; E4dٔ)N^AD#nj]=ZvusgWRh\k;ᚔ#?yF9J;h,(G =1E|շ G{k[+:]4[)9Cn=UpRpR*A1QNGb=V{Lp>jb1rPdfEsD0rLd! =@sЬJu˽V%YALǨ);a"bd)^!T$8Tl2ԝVm tGl?C&;ڲJ讉:g1Lfz?o_hW騛uBxZD hELw8QtNR@Ne[g'e[8Ѱ4BkƊOR XEe,"b *V!:̌g-'1c1c1c1c1c1I?[!?/Ee TexYF`I{%K-o,;,;$V1f;IV|P!Pʒn"+K?Y.FĿ&bJATD{,^~*"(jn"Vn{*&[LP-Ԇ@*pڍwV%*3^G@TH1MТOwXE$hk[fWhҧg"]9KbS?%7@̶G!hxn씪M +`iQN\1PJה`)7KȺ!$-kl˜*TK)uLU5" +rD];^dwrټoЛ Fw?mG&͂l G(fDTM2JP m>װ&Z^[Z'ݢɺm"bn 􋄚5HS eh^>96w;ԛ"p44Y Fs/5At6HS( ehf;liV4&=m>MhSpO\$ѪEM"A(3 e)]mOMjW +OEJHJtMw#Ί]UM"VjN֕J&f]Wd_kvb15|H,tnȧ +MPj.n^@H>Wf{T;&%YSO=1fTiTRkPiuʵ~6E̼hf,#YĊI? ݈E#m|1,ͷ2%"(QmpEC1^ +8>H"7!XY(e Iv@)F`D(c&+BD0:u 'c{exo[ t J5 y%IA1~1Ǽ'NQo ,2$K@#N0"T1"pD:Ds-GD7x +͉,y/c!yɴw)ؘ P)#k7ՙϰjD`"KA1 aǁDԠS yb|UV +fk`QNV= FRXD Ԡy_a6n}V*%h0;Zىk' < + f`x's+ ި^5+-BXVPiY26HCFʕq0P=Tr#[JqV:Yˠ5&*YgA?jl5b0P=R +"n?.K5`Wg.sՙ!QCue]ZF?F:@PDz(uP(D{ݚSڱ],1Tr 9-tJ +2źv?U$ZdRT +'D5,݋v(g1P].I7VyN,&/K=BFf m[UW'1l &3"P8 G:6/?:O/%<w&"[: ~{o)/ߙCUL.̛gJx #77PS-[ ~w2<~qߞ/;XO?Hq$~z运y ??ϛ_(OG켣A +Į"ø,/7 s-]س`<SjxF[3?%?G=ڟ,|3絘 Ϟm_U- k%P,7jΏ蓮]Kۙ=?Upx%dzSY~6o;ֿ8xj>ucfxS~Vn/Ś翿2Sŝ[7zNf)9̦gsI=n||>m#kJPWn['#<\l-tM5jX{]阊g.<.ꔹg0VkՑ뙼Tt|rɨEڬ\p 3˜E=3eY7FqpWh2q &&nMB,e+>xSJaj]CpuJ\+^ҵV*:f>jv9d"Vq_8eLA"ˏAݑ1jpwn^>g u/:ŚtW cRs,|+mkTditI_Ua0tJnX,ڢ@1)J9>Z-SAN2BJkbU1tZn|I9vHˠAQp1Rs,|+mkTditI_Ua0tJnX,ڢ@1)J9vܵ=8mǻV۴չW\I4\o MCiJ{ï@~Mxd:Somcks VoZX@I=l ' Љ^EE+?P29'Oh: Uͯ/'ڳxڮ +EuL8hR6-)] צ[&2iα59八7j $]ȓhD"Q"ҕ؟uD<7m*n2i_OIh>ۋ/Iun~SZ3ϫc:~\6nk]Q+Җ{,tILCU9rR頂`e\.r&Ls歬vvmRج΍&q@Rv"ʮ +c;]ڛg]%[) WFHr }u(E*dލVTN»K6S`lV gF8r }wT);DeWXL1P;ys"-ۖw+X:ʜr*#^8\`@(;%"Ub%鐘F_)ޖ`3PFTbBu$ +ȹN8T蟦BӘQcyͶfгmϛ~|ߛpйq~U2Sks_=9e[)?KTn~Cf߀=t/ˍs:|2[m?] \r\ qv,g%?G=ڟ,m "s6O~e6;2Lfs絟UHgc>G|ry|~.:+m`(=wˎe>VjOxlԗOcD> džV$$1c1c1c1c1c12Hj-Ϳ4֖ Q(&ᚎ,DTQ.:@ZH ?|; +/ ;EY}*f"mC}b9DɮIKwpr22xt7+zYS%ROBQG'r 39gn;G:enٟ#cΧy| +HvduuU_A 2KW R;+Qc{͂EGMGMD=m%.\5HvEMfΛ*U9D@0g֎f]kUFj6T٫ghO0o+ 5HI."(Scg1c1c1c1c1cU&oP4~Wn,_QEe Tdu%,X1WCk)ӯo!2 (،#(xų62RD"THT3Mo1sƯ-vS.FGIdJ4nќ&Q()T>_x38ԅŸHKx{%L~1H;5i&%(J4锇P2f\cBM^Z]Ph>1++&Chݣ91)DLQ&RC]6-N6z7q*`2h YDl6PY#Tb?ӑD!LQ22ǽ~N֭pV + ^"zA!o+2%PQxr("&CSZ:Tl59AvI4,"Vi+ 9IRTU!E}MS8!eS JL}?|9I[)v*^x! +EAWijdz~bv7J_zU|5zNqZ+YcwV +Jv]!Eu7#l44CӔ5p_h:ӛmӣ8ý7 oVdlg.ƊHo{@h>sh=.X6ڤCmNY ?od|v F6Gqzo_Y6ެ;}Ɋ.]Y Y#"=p(})}yk3ui ! +/:◰N0JCFr +=Sv(ђ){@~pz*K~0j=D%u-zt(Ғ){@~pz*GϾ(B[PZMТFHDa?PV_9nɓuL`]:c(-erv@ ھi=L?@-4/I0M"3Yܷ~=?vN?_sSxg#!2"[)#'o(/%G0F1)ҞH7TΙGBɿzt3s~e U2վ,WWCy c<ԏȗO9_\w箋83D> ~97tJ|/?;p9'_݋6O~e6;o?3;CȜ̀SsߙM̓>{YfA?]Y=?Up:EԿM k%P,7Qg_Gz;k8xj>ucfxSP~Nk?,SY~6o;Wo?.YJ~{)?Yտ#GDkkmOw>dk6>Q-ᦼ SDM%q%$$N=wv)j'=Īm=%WmEӀDtNU߬@ 8pS^6$8O0IUR7 }#+߬@A"m&S{zk:N{TDzJڋϧ鵈ګYR"qЦ3ݠlx +7+ړbr`7:kƑ+gd Sw $u~e]KO _̻}k;W*tKd#Mʭ0db]}STA}:=聖Eţ3&)L"ܦM}lQ/UI7tms,gF3&)L"]"~j7o];ʍO%%vD TJ*8UU[ oAjNnyԐ +*GKjH_bfL 74%AT]En={+-r^Wkt-!bUUn'#?z<$H݁TIEQFמBܝO応6ݯ!"U6՜G'%? ^$oiJ((zWH[4mb5-[O6:Rj- +S2LHteȂΚs SSV5ͦ^&:4$'Q:m%_%(s%(DUrQ1?B(awWֽ4źeAUfqGR6NcYGGɜiI\7LGhdOЊBұm2p49'\$eԄ:)׋i*(C))B"≈́Chy~iUs?/_xlҿ3/=kKz?dN`ӟAN|QQ6rw9T3r.ZR WD:f6G w\qZVðפ!Z6g*/,gF1=ub(")&g-Nï'||Ry{+n.%[ (tgX({rf C]n%? Jn[K n24D;pE;!h^)"$5l>Rvy=C+ئY]qu*fGC7J5[f;zoEP1Dda6檌HM2&D$l +R=f@|n~CeÀ=t/ˍs22[mp?] \r\ qv,g%?G=ڟ,m "s6O~e6;2Lfs絟UHgc>G|ry|~.:+m`(=wˎe>VjOxlԗOcD> džV$$1c1c1c1c1c1C\=zg.:c1lAV %2K F==Md_%DcvW?-ay89b!`UNڪ b Gf[N1y16mRc]gGN +&K V&H @)>~TPyT}}'|hjhO/mh UF3.2=B+3|R$t;>1c1c?%A 6rN8ID7]2**AMTVI@2jf3g"|F?l7^ oH9h:.8D"SD'q>Pƭaŵ:tG}]-Β57+FT .k2I +&:lD?` 6yؿnt_ur5V7fmUjERr[ؐseUpzL .#&];~dlk6Sv_hcA2֪D>2Ӕ瘤.Q2i.\" +e(zī}GiFE1i&МQ@/sOd] + j$Qsw T~q툖ng1c1c1c1c1cU&oP4~Wn,_QEe Tdu%,X1cJܩWEXotxxr葎o-$,`t0!R +L +䇆-oi+T !p]5(sNt"u_I#2 %sNc7xU7"|AqxNH*ҶeܼRVjrN$E5̯C c"q1+ ZӲW*B,jQ ' DyJGݙeK5!nH}x¿9~hqw=A$tO{=^|cqzGHD{$e:K{C#UQȠI?>pN?t7ARB~y^9`XUA{l@'Rݺ)z,O>Żl>ȑwzԤ;!X2xx*d3&bb-"*$/q~}޾ANB +Vx@W,UJCU"6d2Lą2jUG)~&ǫ$e[j7r# +EYEZ-fC$HS&_ +J*$p(uGf>o_ ݧ!+}R< +M*̥!M2&bB5_QXTA#[QAQ́.-Ŏeq>ݡƫݍnS*T-cBP'YKnob\dȽn8tATC86}3Bqjv+7|Wk5;RDR+ǀg&A^Ow$HPLG8SVnDEG Z<;rLUh癥"ixa##) +>ͽy+Θ Fhv} (Z471LZH~ +>xsP1Xd᨝ S|NJY?T`xxf޼ӕLr4;>LTl-Ӛhvc-f$|y?T`77o[j՟O[2{Ͽ(c5Q%oCݻ=E{NvBNcp/Ps{Zɲkf?7b:|ON{ǻwS{!/x-9{bf6| z_-F*=CN서^ڵd~o^'t_lwM>ާRqx݉;7r .Mɰ&"Ћx`_^S!qIEO1@{GpfV֞ƥ"9PF8e=vHhW)uOgQo)ËmJvZY{JN9a/3JHMYBv u{ն=/kJEr)pGz쑮ѪS{1(&΢ ̞k>p$4؜WB?גug,ţs:V-S*9@ ݼƾGSlq DMhC#MT ~fb,JUAPPRq}fJhYŘCY&3:r `/C@{Xm1r!hB2hdaIj׬EJ*b 0~čE&rng4eծ~kXi?erz1VUGzk&cw oHqÌ[hW]/l|}ZACkh %}(.Cb*qո*s֪_mQW|W>X}u"<ݥڹH&(s!1nZv]wt£J#동ji $g:^W) nkR4B !/ -.aJДmi{ 5w_4FAdN &U9zlRRI޶)W1 xKwǬ=I#(@1 J6'uG^<[Dܫ3IG (qV`$& d*ԣduoL.E֯`JQd[X]þ^=gM6IMDUL `Q.>UύE8[_X#P.OD_֟S%;=~jxj Cr\[!o+\Vr"k6j͞p`x99FXV"B +9b\FnBnwyBRb.^nˋ neipcȨD{506ٓ7H8;u飺,dv8^~gfx㳳1VTU"b +@=r߉ߙW  6 +J.aI%yg.,5K#ƝB"P +)|2}+1(FݳĢ$̈e*`1zcOPۊv tk۞陴NDzasQ F55W2BGD&Rp>{l:rK0f`@Kwr^m ]@0:cOPۊv tk۞陴NDzasQ F55W2BGD&Rl\^ɡ]ꅖ0%VJ6=qƯ# G2'U*bJ6%xG_v$[D]j +FEu%;td጑ETʠ#tm]gnUꤣFES0Uwzg2FQHS `Q+J:K&z"WT\(2-q./$& d*U0u(o?Ÿ*ƢCr-/߬?Oq'"r/vO)@Zޏ(Vck-&Cs'-]7XYN&ER9!L.ɯ/,tSkN-r^휠J r,bDUS_(-N/l d[yI͟1pԽ5۸ARTVHYE1NR.A*]^_YY9[?`59ARTHY" 쿻Y''?'OVr߮b1f\5ۅlcR:鬷PT$ǺӐ43j%Ns4EELU}2Ǝ5ļ÷ZjTb/qr;"_|Ӷz ܱ8spQ5}PL\eLP!W<鉫w_i09r޽)\13HW\ժ&+eE!!LsQNvKf'7M +-$ЍEoLi&N٪V*BB1 67LMX$$Ix˖J-6 BFT1\*) +c2Jm; :{9?NyH׵蹚HǑSĠ(u\E)HPGmxos-4L]T&(qКb#PN[ȂQ`#D@(t4پ$8ﻍ9]aΗd/J.:bhr(u:&G7::[j+tU <t&qT+S XQ/P)JMӿ\ +| Ϋ@??$~G]ğȿۭ?< q#Kw{\ +| %;=q'"r/vOGN>xmvٶh]&-kc!PPo +qwu +'C֙zs֝fTm^Zc&jغ\4KEPQr8ɇxN\{6T3v0I*,۩H5ye:)Ed +O>΃{6Β&lfƘi3W^Z*Hz .~^BxIxC:c&7mLvpN"OH2 +bKנr!E&őE*pkgEt!UEdU(DLb(0 =.T]%]4EdΒȪB(Q"HtA I.k"gIT!TIT(DL%:g(]$J iɝ%TQ%RPEQ3霂 =({_w[~)rݸ}!\kݻpwN98*լ#'aDf8ɴlR6wci wK}_F6FMӕuB(7o"F( 4<,fd-l圮1Bn\g ^QE ѻy2DE^ѦmF#jv;vt5clTd9\Z*( $!v$b;H cJO@̑{h&oGNI>al~bn|~َozՔD;CL/ջ2=FM1Q?[f:Qs?SVQzZ +DW66˳6VΛG==մߥB]a SjܑSQT訬CcI$O!z`;9[r'; +c&o1rr9~TQ2*J1)xg@=~Mp+'*~FcH.NG/CB*J1$w'Wаl-oXVV +1U\7꘹9*j(\%N̾Rq}zȕR>R^|1)ZVkznu +^ÉT,fwM\tuJSY +ȶ&-Z~f~5/VJ+4W8唼u.J~HjO|RB1˖KkKՑD@JrFhZ'tG_d;ܯEᓋ_gZ" +~ѯBvƨJ6ձOd(T9Gې#Sxw6ٔmXWf3PC9tGmob,EP8D_nWޢ/{f|ozme?h׎]H;MT%Gjا˲QT*NPPKˁ4B !/ -.aJДmi{ 5w_4FAdN &U9zm&RRI޶)W1 xKwǬ=I#(@1 J6suG^<[Dܫ3IG (qV`$& d*ԣi7uoL.E֯`JQd[X]þ^=gM6IMDUL `Q.>UύE8[_X#P.OD_֟S%;=˶ˡ˶Oݾx NϷ]'VŜII>xo&E8P q>ܨᓋۣg6ͦX^4ѯµvHEղd&U\9ەA|;qԳwKZY٨ aH:;(72d&U\,p/s*;ndͳio=h2kưdf]mul& W+Naqo~$h/ng4Dw Go``qKz2UGdkr&Sw z-5N)+,N¤-"؜|jhx})). +Bc{EԸէR#c? k1& "9_JFyb%K `1`sд1ivIYet~!oy[TCFIOD6vR;;;1c1c1c1c1c1c2 Kh(( +Zq HAOwv)& !%*'aoAs>_yk#sz_w Lӏܼ542q5 uwhjfEu7 щQHʙr,`dF/"|cݡXxݩl +ދ{UE " NT9Q*E%)DptU /6a@䮷esiPlU2k5ft٤1ঠ0h:J3eeS +RiJD'iU)Lc@oQQ =9HQJTPԦ?׋ב::΅WmZ[-^] "nSMEi% 2̪h-ja6G0A&8wwv1c1c?'PIOܼ}E+wXE+@ĔSɭ2z#!}^%UNCr eM5tJPXTL⚪*>8DA2d AaٙLg^~|ŒK?H`0~\?ZG`M͕N08>7xbS$Z[L,`KE.sP ÅcZe;nobpvZ;. !qy)yDR@@@>׬-;U}XMD'0l zqIP(bG`}Wi{ZPvBBٴ4ߠ'%]E5rd37eR7C1D{1c1c1c1c1Miy vh/(X:+Ƌ7?/NKx-*Ykyaa"c2׼ +ZaAe1%_[^{6Ixk)2 +$2̊DQC`u&[<ةIh h֪5y- m04sǖ{,nFU)꣥%c3X4Ua8rԾ@AڞvLQ/X7k92tL5'JKG gKGTܹh_U O~H;oT(mz?43l7lȿi/,JYt͎q酪Q6m2-Qe&snr`nmH?zRM7oAL Y~jc$gTTsFԜxrݣk獤䝾x&B1uʜ[,dL +bvߺTl xU> )[JI&M0a+=0!:m[,dL +r+5!sR6MgWjw +obVKcxͯgH9hg8\nPwfkgmfT,ܨgln0ݢ)sꝱDݴh%_Naf_Vot: ,pC[E3{}I(;· 5Eލ6i|QnTfqX u NTAn`ڹ9ع9/-c&}B-R7%6W@Cp)D|vDݎF9ڥq@J::P/LStR"v촪1!H( ""@:P7hO.ݱ(;TC6Ԣ( T R@SZ9%*76Y8]C5g_5p+VɁ0Upt9-<Ҽ+gSfjU T]fd٫861tʘg +.t1mk\|5gS;]ЫW1Qu4Iv!a ]Ef-ZWp,rJlӶJq`A1L5aw&86nS EΚf,ɥ#&1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1d{\vmYa2L>!$7+hy=dU;wD!uY 1DD2cOiCY|'\"6-FSHdðMk`rJ#,v3H*Q3, +4+fٵ%x[]NUD`MUD+E.Nn Lb ɨAN\u˩NԣsN=g +PYԞ`f"r tU :%/'DgxSƞSL)9^n,z4.߸WF(F "d{T*X5+;5 ^]Y(XHz|cGM)P1Crr b >@s)YW.>zSk6j9 4d"fepN.MAtT:Jrg{c1c?RItEdY:J +JD&g)9D@@@@@stճ=nnUMgM&dnJtAd%9 SD'a_רP~'%4Бlt`KVcz*IY^p,EOzn}!#)6_ǮʏnV۩TP\*Mz Y詷zLo~!"%gV͟^?`?o "IDQ9|5vkTʹ2zSJV;tz@ЉD}>4ڼ`\8KͻS4ݪ]ޛزOGw$z +CtE$ ++,5sc1c1c1c1cʤ֟ъfӪ2hsabtꌎ?+1c(̷GVy=x53گŲO<"dw#(N.LtTjQQR1"to33.9|H2+~Yj5]2ŚNpas nS(B3!)Weo 4{E»5W#0Up7J1ʐv;r+B<&c|FrE=OzF]ok;F+AC .cU!vFd%ok(ys]FO 폮Ƅӕ3xNI$a&6.ё^II$$Aq~5s_ 5yUu0 f+L,F$DGA{|4 h"8Zu{#SjV^}5#,頽a>M h2~5s_ 5yUu0 f+L,F$DGA{|4 h"<-V +[c^El8ؘ2`&4DBHP=BV᢫DC VhŃ& գdBR3KU؈qb"Mbśt٫dBR4 [@FemXFFG7M $RV)BJPo={fiB|1_|U)w r GmK}R7_ ox{xOyzpjMQ-u_?4|/ܾ'😤#GOyzܺQ#[kkmc>y7r>d~$=G^f\!t%am-dʰx,Jb-wQq05P霣Ԣ!kզ,Mg$LBG;Lk!+2 `2j9Gr+L4e5cMBJzE4sJGNS05R9rP P\,]7eN2o' ?$bb9`YX圱d#U%=@D3m1c1c1c1c1c1c1c3Fzr oloPca* oC5Eq*[܊ +ES8oXvkxH3i5xSi; K.9@L + +%!8]dk]f_iz0&V:Cw =B-kȮ=@L + +%!8Efk}Uô6#[s\1c1c1c1c1c1c1c1c1c1cU6K ]3jy#Lz}4Ca q\Y7J4fQHJ +Vodz? OfHCC}jj򍠛e̖VI7'A;LATpfEsUFFSt;{1dTUHȲX0zpW &r9DC8  % !h|5*=PALUi*ay=_x|,L-FJ>n.ER($ջaY;wՊ肯u{׎@azwT꽍OTEvd\Ou7S7~HD}PD~ޔ}O(5ry͏`pzT +\x/*Y~]Kא,35fiCܩMZ}B=Ek/z.1ޒ1!(1Rr(R30u)=@C;gY=yT:vWZNNi9_XLOUJ(t΋Oڻg HEHr9.YX1c:NyS~P)e = jR슦^)(ed+7pQ#~<~ ,z@sfSKk/i;nz,zM₡A&{yF]@2ؒRc<,Lt.?TMءG~6t4,fKsMqD==[~ y[JVOz<{l6%{5vO$ +$`O:}N#$:4gVc1c1c1c1cU&oP4~Wn,_QEe Tdu%,X1|@pcȒ I7$2RH}zi[yW4eMtG:]1uU8A#;"NJ}xj=C]G4mPtgܞJ:(wJGnrL No!Idz4:.iʛ +_A'tbܪq9?AɕUuMͅ$謫i:ʇIH .@q)=UˉēH663*z"#( >1d|P=[^m4kBʨȖ>1jo e\N$wjAUU4=y.@a)N\ +_ە螕"[nt_MX/,|j;2Og`+/ bb;eliLi3kS!QX +QfzAHKi(*䆖وr:Ͳ#?өB6Ng VR#)\Mܲ8hU-9H) m}OEKZ6dnzuJIܴ뙊HҵnB,(xx= %Ж^&]~^&1c1c1fTg#!36xG-I÷E?Ķ^-qˏ?W̥ \ f"6ˏ?W̥ \9.rXd1+cu ߳Z&!d<FFe1( +]. `eW\L1P!/M]Il;h:I{UD( +X@E"Yc1_/5meLl x*BM{UD/Up&DQeNR!/M]Il;h:I{UD( +X@E"Yc1&z'M7Բ{sM吁חPR,CW$++#%kn* +>dS:B/G3kUl/ܵrl0{]I# ^83Me3JIzCHLVifOVOri_I# 0{auCVFGD◼ +D2b_O3kUl/ܵrl0{]I# ^83Me3JIzCHLVik"  *)Q&Ռ|{ٛ&m*i$JBe ɬlTTkTYGF2DbͱnգV锉B)@4 &"%h踸Ȳddɛr&VPLM2!J(HHQ EFEtls$Hٛ,6Z5nHd)JB3g?=Q]45P콁쏹-N}a+q]$:IEq[e +'YG @yٛ#Uqbar rk:qNd㞯R2&q(/2#bj0Q'o;-r.!ƽ/Wq%=˼n1#*fQ +Y6Fë[ϼV +=Ou]mW"ן=^5w:8ePLQ1 +!@ ^i^]RR5gՒ\|.+DefJҔ/tb]cXDb$K[tM;ӗy}weck +&&hH ACH+[kcN!UZoixǷ:$z))P|tWH9K`쇴2CyJڻL2n񫭒c[)ysGUWIt' { QnH+[kcN!UZoixǷ:$z))P|tWH9K`쇴3rsrC[ʶr*T޴֚]JBѳT )knt_}pW7{YLfg A3Qbbջd JR,ooN8'}Ӵ.vY#^lJmA=UXߣ黶-ḯW4nVݶghūv2Xޝ:\[Z[1c1c1cd+jP~d"N2Ӌ3MPU/0gXfU*urkp{^vO29?Z;JFn{{MT+M)JJk1sgmRbS;r|AdP*!降KyF1W+m[MRF ymE(ܞ~fSj!闝̎OVґU-SJRFY}9Nܟ4Y3 +{:k5 gCc1c1c1c1cU>my@͕ToVU._vV1G}fS&B$T0E\D%zºQ!/ +79nCj\RI~Aߑ |6)wlHFoYS-W[Wp-( W۹n$ tr <=b5HbJo`?oϙЛNפiҟ :zN:pRh,Ec߷1Vnw9<_?2sCuciU¼Q1ci3 k "+H:h7*T'N9mi#IXɭvrˮvTYE6m:!o 32ʱc1c1c1c1I?[!?/Ee TexYF`I{%K-o,;,;$V1fU~~RGrbF,kְ%rFT)EU[ 0bP ?%KǍ>=Qlƾ8xG(A@!}q z O<Cڍ$znm}Qx0 +P +QhA!ly/ +^Up(@)EfJ9 #KkM I.5m 1C *}ٓH02+a|eJ phR z:gwIwacQ66.#(rokv +;`TK05)=젻nGX]͌ZJDX^ﲨ2*rzܪv`gwIwacQ66.#(rokv +;`TK05)=~=^Y +ǻiw-qaטbVKlctژHeWU$Ju9@ҟ]'&w}?G[4Q̅]FCgTY /HȠqYTC 'OoKtԴDU? ?QfգX*fvN|a]nb? qYD(Sw˾f9Hsl?e#q)+*@srk6/?:/%|w&>"[/O?e+R [C^3~fhe+R W4- } 7fs7&x+TW(A6tJR&t\"PoXÍ{#E nmnK"5evcny pUBBޱrQZCPPvŲ%t #b]pTapQBB|k/NkMslt^A!+N3w+X($VjwT5twYE׭RUDP?t"VLE)5ΰ7,ejsq]Nz "@F/1&rǂd "%o릡"hvZW,ۆ6K8';rYX"w#V9cAM&>jzXV2I=tYh +w#9c2MPH +a·1>va??",_ˍ̴k[4,@;Dlg0+n!Onk_=]۵f*X.STJF0$nӦ0 V8C)u^`ZlU)h:v}!RxSH+~Sr ֿzkţUo +\ڕ`:HMNa  O__J,".V}L+Z~.Uhc J{W/xpG +G=Wen~cZ2zH +DWUv%$T~kwvq;ivU*W\6YQkRJzr =3=l8{^2$ƴeJ;]V*"vJI-W&31{N0fk5RilI6E +&U8l飄3vEH)hgܮ\m~Q0nXKMRc?Q7I%ԍ#eAt]5ںH“֨URO@V6徯oҏUTI%Ԏ#uAt6Xr'?PxeVge3Մ&=ܳt]H"6QTAU])8@jU$I̒'3?x ՟ҮQo,=?Up/yus)'O聮?C9~WuS-!O~q6/t4~5vw?Zؿ˦hWh#AFy-7eϺ3"Id;&%fLl,TJCҐaiVE4mC"dl4яvDQ) +t$Q2 +Hb3/cQA 9]926hWw֨R&30IDP*E!^1!;j0ijڇkD٢i_R&30Id("/@(f~~fz忝B/o6c~{}>oC+{[; ~~j|lwOv'w}s̳RWvW4E_6|۬_6_W=ܝ޿җ=9uok}|a~o/>-W>/O)>P;;Ox xy_;EͿ:-=#?}5/W{?s/ӧq)qoجp-|odk~{ww}9xgɿs#'g`\G.޾1 +ש]ݞ^ϣNr~h7lV8f5X=ﻻBGq~4~ܿT=ľ UW>1 +½yW>)=׹v[0}k>O|Sܤ/>=L;GRm-뛽^|Y|'~#;G?N˰[^v~!W|#%߉|7vqg5?_D'_lEFW޾Ӿ~;K枇{Hg|ǫNަ>?<>9[sX/3=COSB4G1~~>#+R>ΟoG&sOwwrӡ{zk菱ϲ߳ė}|5}/?www/z:'zr>ZemTq(a,,g*AH*3vޓG..HDWU.]!߄,d_śjt)%Qj{ aD) 2 6xJ2RYD_9icRTG-)3eicRTG-)3e@8yVް@S+RNTYͱ!+*16I*Mrz*DzMks^LkZhwuV62gUg h.tE?c'<58"XIe:*D5@sC5/BsuctU3e$yi#c½UqoN4MFkN, +&*]}&mf&5wjpY3*]J:IVQ"hN, +$"W+wU?:Gs~AjbWK.GC\/ʩeS_M],o!W4>Os +kaC!FSWET [(""UGyRj"]l0$kyD"QW+IkdB 06E6]dHAQnm<6Nv>ؗbL1hEyZJۧTm ()rp("B +dNg՜D{raIDV ȄW&`lm\ +'Ȑ='TʲTa}"ԭ[&;dAWfH!̴aeTP397 D75^(/!$zv$?lV& 4$s+oU@3<{f&vx:WIfĚv[soQD!̫zsA M6kmMpW3I4fly' )< jIǛPA ׎5ר荴ߘl#f/B]vruIUqH#sn}c&ח-T\æ!wF(Xdw73cxY)d"oxIQ0Ǫd5s/`S6QFgJG=5U'DES^_<9Qr2 a`։Y d EJ(E'DGD|cwߟgj U*|W+ӳߎm˳3zzwɭnQ3'FDu)zvvvz~oS/ӓ3hBGr| z ϙ>T<}~;(_#}|:\koo;_{O;{?t7wSϚAfe^QXGƾU=tO}gk4ٷݧi.X½[v}uOypM8!z9ʏ4|fP>!_knK݇n85_硥\n>ͽ;Ow毜{ +~/[~/z}{н3;֗0FT]ۮ~0&#u$xVdN]3R9ZGo oHtTzI? +>sQ*_ILJU&ZȄ+G"rE&Ν.zdKռ3j +."]lm2%PdB*-QU63G"`nm\&ȟE39S#a읷55D(DĪeRi1nUB|'+dRlA7D(4?%9V+C>0)M<@*3 oP:g'1`~Y>\RI%bgPVc '$)V(&fp8{ <ȵ$RV/QiFq efOнIHA(EJQ)&!Y 9L|$Ji ANIB @*RQ-Q9 L"p k[QrGmo]"֛3Ϝ$2T ].QnʾfWoP4y]a5~5+bVٵesOM |ѴQ*H*OŐ( 7Ck=Mm,7W-Q*ѥ "dAV5g/TAETv*q@g|uPZ[#f՗M<]4#$FUGOT k[#%ɱJ~fH Fo7e&uP8,bN $9wcHP1O>dVffӰJ6dJ"hUHJL` [߱xD} kW~*Ye !Ԕ+|,)UTO c{'2! k׾(YKEJRLb貑PT[7?P0I-؎PhmyaB5+,2SJPRQV}ڛ +Rk,)`5zꯣT}:"%QdCL`)flNח<`,%dKuSCvT,ĥCpB-+Z.tXZ%Joꧥ¹]eSQ*J^8t({3d^bulya(4%[t}j˴ʧEQf%/B{:G5Ss ͛z4AuUs_ҒOF'!2*!ueCM6 ml9vʠۏi$rm!H>i H~J$/Bð`]<?1ͫBZͳQt4"C]z-& #3aҶk +Pm4v9{i$K4$@kEa0t˃ͫ>7?=?l5>J+u=_rzo'^n5putگ|9 _f;S>&.ce5G7{j?vn +>Μw|?^|H=_K'wqxEWʼiIhj7_)}w=OtzޗoNtMEl`cV ,vyƠe+E\:rh&tH+$Crmy:m`^)w07a,Eܮ@"($Cc4uR^.]oP_nL*C07a#,E.~DHYuLT)bmy:m`^)w07a,Eܮ@"($Cc4uR\wJcvXdxnᗙy#>R652 (i˼P ) q9O^f})*񪕗0ńL?i7G2~= Ϳrlh1x"ɳ=D5Zɜ&'E3BGryNzB?A(יr}iJ}6B7|je1a9OM̟E3BG)3lati +;%9%|D,"g!U:q5+cAZ4eU/&Q2`$&o(8I2&rSw;8嬵 Wuܳd"u􅶣3)!*G4xLTf{uұ*V%0%#M3+". ^RO!NҤC(bw%KVZ%v0 ZʳJ [dcS1J:; hԩKaM`=h&3lٰ8|UQ+n~)2)GK[~G9(]z!(3jը8~U"QbS'SL1Q&34?ނAӖm"¡xޅPy-ʁN*Kt1[ԡ c'sґ]]h3t.!xʫb$yE\,C]wJ噣 g#m|7}{feH ;I&oT*-:H Hϼ` Y E(ސ6= kl7r$5. &"Cu϶g]`8KhRJjb}vͭS7\&CzMA@B׼8-#>5g.}z@V.խn˄7Tt/xh{s)Z,A+ic4yvQC&mq=@+Qrp74C+: +Ԍk{,l(ڼJk,b7Lq]R){\8O<[T2,I)ai*y6"#{AҎΨ7"Gz!s F5˽Y6rǔm^%5I1Mixh&uA\fK,9,c1c#!xyCY +ަQK +Kq~ŠfvІT:81 "xxNtp(NC@oׅԱVFĕx%QWTk4)RMeQHJg_^ZF{DJ3U*QwcDz5ؽ]$"QQ\99z;^:K8O=,{OyЮ-rV Dз Gp.wYoG0w/ھ~}ĥ w5OR,-[`e+ҩ@P%sɻ{LV"TΙ)ozfWv:5^טv*-u*GFH{I3A(2L!lh{NRVǴQoEʤFܣJy11:b10cu˿g\˜b}?`C,_^t!䍊ɬa4iAzgIOBEٗVzs$aLswU&ej_>p*$ݞrW)@X,Y6":)VIzQra顃N`v|90 +k"yK3(Hl2zkۘv0 Mp~qLju$ +;%֊⭃WSڧa$N!:tQ +uܬSv^fSfeX'w +ۮv- -AZֿ\D@ +(&i- Ul +fǮfi6H4{)R5hhbM T.DL #E6o{q#DUJ((|ʩ*^0N)=3_cxm{;Jiƻj7ʭ6wc$*%$ҽ9~VMO6pHU139tATE:u =598C.ܓ_Wg쪌ĢAf٠$R(`?Vrq(HͭI932QsTpfgnq .ƿEkc>S=&{96 ۹b6 >NYD+$jءr +YTSC0)S}B?YYz־G]WBqWnː1n!hl +hB`"SF0D{G&!DJ &(I:<)GS0/s*lڲb"]e \T*NZJMLBedšn O ehSTRoz$>XilbꘪLCppO!QjSfxq됺Ky0#ptiRv"&/ӪMʭJ-B.TΒ$8 \1c1c1cT1B^4_Q0uFWn,_QZTòòEcb 8Wz~1%jI,.%vj~) =2erVŘf|zD@ +[#gp?wC& %@{ٕ_:S040/(mS =ɗ[`Oݙ*+l 'ht_f_x/AwhwўnYOM;czu8ʹw?E ٴGE=&hOTT&DDsG|ef?|`?E!KE=&ͨp SL=:8ʹw?E ٴGE=&hOTT&DDrDgzwzaS4$b-[%wh%ۇIG][itxhi WScwFTc>fuLl]vrC#)?o4haCW܁Âiv?9=gi +tp"G*[ݝ4[T@ScwFTc>fuLl]vrC#)?o4haCW܁Aո6U ,j5бlb0`&Q,PAV?M2>nl2& +z +&=0gɗC4f,5aYR{Gٚ抂i_`ܘEGfϡFEmt0,{Gٛ i^kL còe#&zBf'< 띅"crE +-c'XEo^^ۄ/Hr~$t|P16:QMUҏQ1$Wf$Q֒rtܮOO* `(ȵ.ů"keO>)0"Kq]HD#ISr=?L]Q3G#^H5($5clt{-cINH$鋹\ +8TA?LQy^$:juo7L `DG0*9@qm&@"ct=&F|1leh#0@1#OchHQctG܌jp +VMuxa9zvP +"=@ nH?xS᱔ +Vm>.zَ^#KDGSբ"PQI3kci=eֱ=7"iHYUvn\ʬy*G,Eds\0Qj%"?iFƦռ]*:"os&W #$ H@)g+֮ի@V$6ttrm6>:R&W*( +]`1Tdd3 ,Eds\0Qj%"?iFƦռ]*:"os&W #$ H@)l!*EE=1 rAH-1f'x@VfE2R|BbB 8ZM h">V*hK5:1B|Jc]C q!뼋4Z-"*f3tC ~JNu +wu7$bi43壜<4Z/"*f3tC 0y#Hy$Mx>"[%̧;`)Nܗ?*Z2:#0՘T!0 +KW$vv8pf r.epſ,fjܴ>kHGq`1wdh&)_pW.:b˙%ry`C?fhF`\ +|kՊAHuPYs D Y=%̸nxㅙm[5-},\f.-e+ +PYs DXiہJ!?=,~KM}ԃ8oiPp3j⏇Mlk{sD]*T[W7˵d:FaHrC6nψl+cnn]*\YY ёB6H u|u*,Q<+YȇKv>V.HYrt1:D`6rP^uuֿ<]igۨvK|vEb N ]{zyr?X.^g {{j"S0J1P/N)J$ǀK}kt>`ְw323tBetQ D(SRJ%ϗۃszP #.QwR! +WI5JHu +b@0D svpx,fFphB j$0ȑE +b@0DIfRY{jWG(RO\I*ar:EԿM@JXn! t~մ]=R# K؝ԕw]X5IB$PhST.Bq3T1Ӻ杦1SS׮3w:䮝-[3d/Dh7-]XQkʆE#8gsn +j93` I*qʗ!8sNSU_]ky;rWNUíǙj` J`au~=nuxl`Шv,Jb{B (f'1 hm`2&s RxԊ +pn_Hޢi&ҼbN\g9&=eHM^sPx5HP:"QCtR6z6u^iQhD"rJs6QŁb OȾ*˗fYg +*s(c #g51׺ޑ]T#hȶhI3s6Qf߼*3UW:1"a묭ouk]~Tei#cIR@yJ+2T9]ȪP9L=u߬Ԧ:[+Jc I"nu* PpЪP9L=rxcu*ڛ DW`Y&h;*& +bXثvbz ;e$JSECT:m{Z)]w-!gB8$Zz-ʹhON@D(n̦xfuLl]vrC#)?o4haCW܁Aո6U ,j5бlb0`&Q,PAV?M2>nl2& +z +&=0gɗC4f,5aYR{Gٚ抂i_`ܘEGfϡFEmt0,{Gٛ i^kL còe#&zBf'< 띅"crE +-c'XEo^^ۄ/Hr~$t|P16:QMUҏQ1$Wf$Q֒rtܮOO* `(ȵ.ů"keO>)0"Kq]HD#ISr=?L]Q3G#^H5($5clt{-cINH$鋹\ +8TA?LQ>ߖ˓Y Y8oeB^UW.Og-ekK=tiXҀbJ6'N +BSJ"j-U FTEPhX$E4d7>29aD";oIPST5I0ȈE["^q٢m]tDT)c:]R$Ԩ +Hf5jL|*/jil6}"*1DDDDscU}_5rRj*ujF3fdKښn#[4MH9aǟnk~Y|Z6O UTbj+8^mkb4,q$lB UTJS"{7l$:Ԙ)3Z—8rɪ}QRDEFBuO1JDH'õ?f^m ++IccH'H\4$;DL)~OFDMGd^i|).'uo+[AC!rQ{Ãu'D@ D2|;Sl)-|ʖQODV64t sN OSD˜w_۽3zqM{ys59̨ׯ8͑z~Dn>7ǣd[#/9]X\VHVqsu.p J{ QFcX&{M6_ESUK!l:J2fEAY1xO 3:q}uc*0WV#0ՠu\l:҂>+o!G+kֵdW*2V5\ &R8Wi)sskLKaE-w$((6 @`1d:㇒FO"bMTRep@U@st?@~n_4[u *L^ymPM1/ EYܐrh8.nY wBޒd-$ZtQ5ӫ(Q\2OH)xCNKsBA5[,t%Z6먉OeIm'34Eʀ۟'ki?⅗6K:S9;Viݓ22sYE,/fdz;FI@CBԼJupv3*C,cU2G:z%+dָrnf39@^ѣ(XL܏pz -K͔q[Hlhs92t8ʖ5P)} { s7ЂP!x#qviz^9da2JdqH5X_A~ 8A Ts-e_!t+p\Ԫ03QHʼnu," 謉Rvzp|`[f;e*T}\eG,SW ]" +ȐL'ny8u=c[BRb~1Fqj= 6X.CxD] +Nܽk&w)ۯi6k%N^>~aBJV"ce&ZFEk7Q5 +Q0܌֩xKQOdW'fkS0z$e^3Y[ت +Dߧ+ =ekrlsx=FpҎ*1CX*DgξKX,j~&j;3\Sa' *ߴ?^PP(^ 4S7zTCY{iBemyi"WLQǵI;1a;2vKMwvSZżU6'ʑ/kXKi!@I"`0z@ٲn9ucZ'vx +z2Ǎ[kc 'j^!қJ5x2m] +O#*_(R1n +B1nDa;RwNyĽmxyqЏ7k-ofeeYhbIbLPW&HzBj &gi~-Wb\u6i+Dv;)%[*Smp$}1YӕQ8>!&mhmVikZPw,II~%:ѱn)銮 +2u(xȇ[SnKۗjxQ<:ё7RG9PYxc/,ը+6ֶFհNVeS["pݴ<[ Asa w-%L<:m@ltۄzNY$5rH+;DAG)s{ {uClzۄ&5ō㟟d]UX'w-%L<:m@ltۄzNY$5rH+;DA OǒlY7fqř܂n똧fM'ׅ" +S܏o t +*mLk#q'{t\Q~(r*9DUЪҭ}VvLZ(LFN5 %9 +gcW7r>%t*l>ZY3PZqDĝpz)DJsn6I͒c1c1cq[}TSj5{X[}z"pԎfשLI%KتiQJ +r`ζZgO*٪uᦹҢ exbrCנc goGYý]|NyI[$Cazd`"ց[fA}?R S^w"ΟpνCrUA9MC~ZbqjF4>ԉP ӠL΃yN*N3i{;t +g' !{8=:xcV *^b9 $築 6|2 N67sVd +BHI}c+$bA0/@~M 4D_"H`{T37`#*A3 +XQ3~Ь^^wwna2&0%I1tL.F)Hcp: '8x[* mI⶛I&LŻJjE(AhpW@xv)S +9j좐rs6l2g闷<>{ೈ^>87 +Œ iS'v t+zvHh4j7`.W*In 33׻tAYC>[4ƻ} +yM#(^h6rI1Ub:f!1oPmDݢ(¢ *F7y"hRŊvJ9zr3IL_*^{*-4\”%g} / )Ȉ협RP!$çKH˝Eao0dTVȴT!{Dx n Ft!UINEDP:gMD>A`=-uzf9eaގqPYQK5|۠J ʽ>yQu)YޢVȭ#:p8/Z2>ԣ{z@:q\o!\? +&7 +q/vgG_uoHZ:;YsJ}ɻ Tl/uM.~\ f '/oU&WY$s ]yiP)604~߳ء3ՁT!}tA$9?03?3ؚ~wH]5vˢv,)}=OiIBOצX]#~,{@y[pŔw%A"ͦe$}ԦT]v!H\l(J>ݥ=09~ҟ?D2E|q4En,uk$|81\o$}(fnwd@34-&{GxگD_\_2R>:TYJPD28j%/xRt #?`k7QpWiuys$-oiP?j}h aM04YD2DE1/1c1I?[!?/Ee TexYF`I{%K-o,;,;$V1f6~UpZC[}ЛЃ\·I>DSZ>"ߑ:^t },0 ayH +^Bz!iiNhf[A~Ai/%ޡR=?ֆe;ϤN]_K /}A^m?PZ@{oSZܸe+#3rIqN +M YK R(oʶY)#NX[ZƹHZW*>ԘVm +*7I7UIC悸>Ŏ9N:F+!r)2B)R(*N$Cۚ$kjtY rzH?mIi&ТJs{uQD@D:J\!F|8eKuyAp?{V;Rz6BIĥfIXh!EzQ@7a07 +,-F.mw2uRC¼B1; +nUi0Ŋ)vBN-l +doNϦf7_l![zX0R兿qHqE͵Nڶ~=()F>j{yK0Qsoo+ylFñojۻ̋XV_ȶA͜AJh(0H~S7K>vmac 9^- 1.R&Ҏ*`=u?I:/f'Zvθl; MLȵjh<*$JT~lc'"UO&V0"刵V$UAL'bʀIdIE]%PUT~DqZrVNj=xzi9\fEd>Q)骊tVMDTQ3jWZ\rcXMꍣ칑xzi7]fUbQ *Y5QDͫ~DqZrVNj=xzi9\fEd>Q)骊tVMDTQ3d{w sq6lصQr[w)euEu9)qfe%!sf{{_5+өhꪍmTF*aҭV!D$DH^6;U+ϪHl(Pf*]BM"`f+o -.k~$WUS9UڨU!;WMZBI"'8Vͭ*|m l+kuENa[,u=>keJXdD{DAFe &0]~>R0Bf~ֳPQLҀ,c+E83vgM(V$?&ƽO'X!e>m[li@2VPwq$&ވ7A6H4N&0]~>R0Bf~ֳPQLҀ,c+E83vgM(V'͟K|<w&E?Ķg󑜐։m98EM}t[:(C@Z 9#i"ΞOPwH tH[}44֯mZcI@ NCCWXg9*0t" K6[zВr:ώs$F9M]n*g)*څ0tA4E-liii_>Ɠ`[@78,sDU at;4Eg9u ɾU* dv|Ǣٙ=v͚2GbR :'9 Ś]pa|l!MڑhXBgnŪ7lr8: .D +$\aVV o:A>D2IVx!Kɲ7ln8: .D +%?<'kUu=EֶI7jEc +M ݳIf&@P/(ƥzn kjWB9CE4E"_ +P~"f0:K](%U4TR+OR Oo2WΗWcZ8yP3Di~2 WΒWc "yM3@kS̀r{\Ejs;iu'eJS~k!dξoeƮʴPө*HU@N\ZԾVmf7ʼn]L8NkuPo2_AI5P$XT9?SL5 -S&էfx)Z瓀Fh蒿o0Bn"CLa9؀`.-j_+63_ĮkHO_FtȂ7xP i,* +&=>߿$?/ʦH9_s? `>xSU**<)x/9Q~g?ک?h6y-F|:wʣEVޫ(2sSIOu[EN_H*;/XHq[c`_K4EP;?%e)󦽱Ł]L5zE/V:ڞ*Dc$8+ʞ1r>}:䊜T#~w6_x?iP%;S:%@i1 +m@A9<=5g[)'O聮?C9KtDw"_ŦI k%P,7v߀TmHggxS_M],  s󃰿*O~q6/tnTj^ŀUTwZ̢ +BOüAt̊n骀t!/^kP+wZ"B"MEEb%](Lj5[3ηkEFQLfc" Y C{KۖkP+wZ"B"MEEb%](L +yaL=`jzimLjWڝ6p\䓨VeC +:/E=APظR?~GY5gZlzĪ7oTau.DMQOPNn}Y<6Yxz޸tMVnWNvyꀺ~)NSʸb'7\\rZ#X,6=bU +| JR"Pm&(SU觨'7[ǿtyey5.{Ώ蓮]KۙvzD q$ņ i +k+!~pvT)կ&Ov(5 r6?ѓ3?O(-,5 r6?љ-z:(v|kʷ<?݇%?{Z(v|kʷzD q$ņ^$R-6RO\I*as~ChZC;;Ÿ-Zl_gexhkU, +k+/})GWXZ]J\ Xm'' ai3]E݆*\)n('JC +y)W|IV޲_:=*~-8$ι<":HF>,}Um ec{K# 6;:Cܡs^o!7sVya*@P{>߿,~jS,W|C,~jS#mg}X\7FLl#j tDHo÷xmqf,D{AG7a΋پ9斝-!)nS2-aZ"-O6rҮU*`=Ý#yLs,S]ٶJ,m{OHjx\J($_J8T8&轛ii:Ѱl"253"-tg(l}*R +.qL9>ߖ˿Y Y8u>eB^UW.g-ekB& !%X=a%w`E -\8/Og`tɓ!搀j/c'"7D7}Wq[f2UX[az{=1Ι0|\Dե` ٨"xL lp7-^LCL ,>74Q{9"$1Nx ttxі࿗:&frmnTF]%L"2[+J`*f2/z>a윗|sF:R{ĻF*C(C! DSh8e012.>`dx}?:Tc헞?9rb4_YɤE>;dQ&IR)'%ß(.4Q^.ъ!!$cHC&DLLL=|F7וu*SMRaG%0 (u2bJ~Uj^:=i'4jS2E&J lM(DXEC +g98JLkKZoZE&БiRk4:L"P !8r`:bJ~Uj^:=i'4jS2E&J lM(DXEC +g98JLNZ_USFUMVLx+J'u,,q1XhiMkX7Ʃ* ״I ٓ~Ddݤw +@cG4VzV?P)uS/o172 +uI:H0 Phֵz\j2{KT{}Бm9WLMGpN0DsCOak|^u?[I,vrq3L~\^u?[I,yQӿwNC}{{zzurl#N4ϧ翷_oN?L>PoN{;i=ݽ?Ngwq߾{u}>=:zurWh TA0$Ǒ;sN?HDG-R/xe'٫& e@P L#-oqS/ 8  +_&L + wa0zrp"g&R}0`P/g\D OD=}rɟk2JYpÊtbLp`@:2s聾8x<Ӊ 9s}-B,qă"WwߟbN*A+@vd0? Wwfp>y] @syɊ +;2ZY&D=.%;}F?އ(iJdb'$ej!*[I]%Ьl(2 i+VoT}3358gz(kfKcƿjVb^nHȓט)[@YY!Uw@J'{4Lc #F6^UA`ّMi_2z^陝;שDos_N4 F[5[R tTL=@fs7>ι` Z +[@KrL`\<5 u'DVL%:gsX87Vӕ,D,#uCYKGJ5Wi',Q%S0 N9̧5X3uL 4!cxivkGF?l2nY?b*Jr@}/8ޜYb$'dLB2Z:V.AL9e ʉ*Jt >㿋nvx%_MZgNhe5:毲7jp/_):g=ݍUHEU76M9lf?hZ̟g{R^qʌ/a +5ܵ=UJHx Cն-Cmg0_?1}m k)D3-᯼wv#t_neSxkSdӟnom|w%[=_xCPԎi5#c1c1c1c1c1d=CmE.0v }h0Ju;ĥЗj/H"O3奿߳:>&3 ~KGOΞmIGNŗ_吧P qzp1e +ᙌJ#ĹkQZS6!ȺQPX0-en)kw'Uҁy c$q~6r}qG@r^$ۃ[ZڑnwXD=;暷MczʝQP=:bz.N=:;T/F@kʐ4.q`6SVA[۴zqG1nO\ch*=Qfp9kh%ozU̎M=wdQH2Q HZ/^qɑR4I2L`kܫq OP[0_roLoch| YR2%ga&"+I!^1tξ2"SN S$ :3}̱ \7rb ]H`Q%RP@C8O6W6(NDoq\gvZ`n|0$̠ >򐐨rHs&%AЉ)NO?1~{Ҳ..yNl}.XҧZobPYtYT2]7*,DA&iZ:F>a)X"䚷}%tWjUQ9N9D@s@@z @OZy%jj$brMo#e壖pN2AUP*0@qfcT1B^4_Q0uFWn,_QZTòòEcg kh񪁾*ъI-J-YWikC +~8Buɘ8pNiGs4\RBCFdcI**8RT;0P A.鐊wҧm +53qW!bI*:58rbT{0ӰP A.!9[ch +NG)!!l21Tt[)YA*]YX( ]nE;ϒMH}!]x_ud5a<3*i95[BZ]LUPq5_|α6ڸD'Rh[\X{RZIԻxV +}C˲=*|w;u,?*rF)ikoJHBh[C˲=*}:ڂjKPIemrb5Ii'RZH*4lUn5S.PSTJX *)`c (3*EBMӄ +gH`7A(^ IX1LF,#@pm3&Q0A(z/UʨKd,R9 T  S2eї^ IX1LF,#@pm3&Q0A(њ[n]cQ4ڪlWa]E+70sD EZU]b٠ș ΝԼЛ|jZ +rDejX#fdub&ePLh.ɮ_&B=2Kq*Ruj31u*bΝԼЛ|jZ +rDejX#fdub&e7cp!:W_fd8c5QۇA"iiD@N!UW< +fGdt쭅C?Q5(=GkU-]9P@P@&̺  y<:BSv=d|tWZg$UbATu]xc)dvGH:lNT;3_ҎvRHAE +u a bMX*vIg#!2e}E?ĶL?;_xG-ヌanj-M]SXBk5rTukِ)`xSFx@=F(1l MM>jux=rcujXSg",{!#:t)ƨ +(1T?1$Sep[A굼kmzgr2Xv3w",sW5"ȧ"(@cDZ7",\|xzUl +EYf BGtSPPb~1-bHiu/ Z]zeL:"k{G\3(&UDH;h&6vȪt::;Wn[2bOꓹ`Enebcν~*1lB_mp/`Ձ\Tv\jQ*٥Je8[aoAE_kp^)Yf~OqSڌTfqp(w,ě51UZçqAA#{z_Gk{V⣶'pHR@IV*S.މD#{zAˍvK8l5b+nױRG+s\3:2e6rW;g4T1a߃nNV.4Y10wJGz-JLL81 #1 an@ԌBb_ Py)8f%EF0DH;Am]J$ݺ$0?g8.zvYulR'=Mi= 5䢋&E9Y)ܑΙX)S [W[m؉9_w_5iY'SjidVnOܑΙLS LC^ubdҹ{HLULE=Fʿ+gUꠋOܙΙLS L7]m]mb$}޵~HդffbMduZ8U/?rG:f"1L%0vVs?x ՟ҮQo,=?Up/yus)'O聮?C9x8:zrE&Ž.lJne&ΦQ"f>"HɜH8{@G?O[ORxY^}kQJp5WMDu#e<". !Ss/;9w +Cn)D۸H<|WdErRI`~>s֣8Xk=*w2GJ4xD\C h]Myl&cr1)w`oz1u}M\,%=G,n(ѡ]ٹY3H꜌bnQ'ޔ\ à-.Ooo@r4gSNB2+MZrJ6BFn]-[Nr-es4a&}ENL:0ѲĦ븿}W +EڴڅJ1sxXԘCWLR8HzlTv3"nȇ^ѡ&WǹC]6וqPKNK$;Ywfe +Q7iC2q J&(f=LXW S$^"怚"2~0×"¦2STQM$dD;RSQq= Ź@}\×ΰZSIܔ{P{NC)E^+eDTt,"n&QAC1C75`Cثq:bg1& GQq8dģNlNnv/= &]FBi)" G,dGhJ=Q满Qlѓhl;qr "pAv9=>؜,5)v^.zM~R*E@X1Uv0z3μstMtQ4%Dkd,nn)-* \- 6(WHM%ޙx+ѩZX}DǦ#(.sbC1RNIUaiEEzDLNt7mu2;6q74ZWBUVfF:V"}LNt7Fka<3m I9%Un=3; Ҭ_CW~Z_+g-ekxl{U\O5󉮿+K݉x5 +=wt^CY5%;8ǃ_ЮGzL{a$vR[aVl+ eU5ni9o*FEWʲۣ;P.H +ešL{}nmJ/Ez:c63$1LvYT%5/2xݷuTPQOG^l&bdFfRYD/wi+\Z?Fԩ{_T[v3iKIS2J1y*'&EO"r'7m홫t[j& h-"o:MEd0QSȜz[DÍHkUV, +v{JZlK*`^2rm NǴ +^ XI'h-q6Fo=PPO${j]h +ᖳWi5g* + bX:K,oq +^F\NZm'[ z-bH9ՁU0-1.'=)z2V~qMҽHB[2IOKD.%*iF)Vn%皍s+y R#ؐpv"t Ƭ%S)2SWS(}M;ˍ{lH++I$:`occpu$za%皍s+y R#ؐpv"t Ƭ%S)2SWS( „o/pEWFLF`օMνfzBTY R>'yƉ#`Qp;jPxvj`Lݢ09''RlxDГM(z8J!vvh EESbs NN'yƉ#`Qp;jPxvj`Lݢ09'&ܳ^9׎acuo-o۟'ki?⅙N/fiڋ۟'ki?⅗4kE;u%ck$X +ow4EE4;Gd|9+7ɎjwIj T'?' +GD +9 @6+[864{S9KY_w9=Qwы060wH0 rVn7k$ΨOX~{4O 65r@( yw^[k͉dsJJZc$3c9hOXd8&*-frB= GXf`P'sovHV(zɝ[lyŻW(U8RRFGEFY@} A]1(t[F!qI2Z=Ʊcc&<|R"INC2wM7k}fZE(t[F!qI2Z=Ʊcc&<|R"INC2񖨖qOWm8fvobTTM]q +B_ĕ#"LޫwZddl[9GXl: +> +xPCEl6(&S=iNq^Hiʌ чQ[>9{}G$z' k'ff:e UW+aGƶ7rܾq^ +qhtzcK[HT0q$ _t'*!ت*eU.Pai49:6faa +.* +]ݥC}*VZhjD$*ugo/%]E +݆"=SgpF(h*wvNvk KMАAĥmk68xLE# PQtAPUUD{g+i=I n6>=eܳ`ԝ +>ӨPe-5l; T`NӖIx(vD#NQVMs=h+5n~a/{ٻHd#JMfms{2l6݆b@0'{$|;"tw'(&9/'gڭ;3ݽGeGݾcGgog?G}\߷/KU=%c|\?owC{ ׻sW߻zv~׿o_&9{/Kǡ_Y1c1c1c1c1cW'b7~s3>Bu (eA(" +L,,)$Ct`L6%:2e8wj3-yȢtuHfؐ陹cvK ESjP)ǻiԽ!+RS) G7P +~ah Q"kCf_z,#p]bٽ*= +*ַ|m(Wuo.4aZ֜9~]/kD%(_re*I33]MJW,qRsraZ,J2InnE9l!3v +b%0@!@C7;߮-]NS.:ղfw `X!Vj)HxU%S\ NtV}9?"(UR +g;( ˥J*Q3?ԏ]ArDw|(tEaIb?LGo5et|?ὲ^WZJe;@HI8TmlLy" DIP `@0 !=ɳ4CB1NCC@9L%1L b{13U&oP4~Wn,_QEe Tdu%,X1j"-^EF?fTDUXEɰt_G2\,2jq)@D3DEI2y/&ґr-g! n֋%RP"J` %b'b&KC0y-$q h=7QOZtIBSge/ 5&^&M/"[(B:A(':JLE0 "O-)l&e&ÿ %fEiڻqbXȄNAYep(h)֛[8夂;?W#[ +i +k@C\oPH8󲋯.szt1[ٺ4|bG~P("<S6 /q5Iuww`G*C#8m7BF}۾_+&tw?C fL&R.#RZ%PN*$NWlh6Q@cGl99!JcF9ב al&8;0 @DXx(ҏ̜,m :DFN>FMK[LW Y;Ak&UV8ouY6k<|3 +}TRO䴝JdUD\܋"E}"gNҸ5ڬԲ^)$ JT-ʐ2}%dU"'rY+ީ9-o*7m5dF ᙅ>*` 'ZN%]*w.QnE"3^EKze~obu,9!cbD3֍Ej"UiQx(93WEvT'\=HFKDأ`%1ANH DK5ފ,K{ԥb1EeXF[ %1ANPH"Isf.N{&( #RF5 +?J*b7| MG\rmC*ESM[r"y3d~(?1a,¯tP +*m( T]hh{$3tnQ7@ʓ]fצӂQqPV΂]oS%WZ">"3tnQ7@7b8Y_xd\T1lP.*If=nW>׻hrH,lj(}#;*@_2NveH5ql]e2 _EňJ,?(ƉŐΚ*rzJ(hNv2TmY*oV*RbV@ݵ$a 媇'vK~$xS[^.2zfUX"bp mAQea DgM9=d'_n|'Akk]4P=rĤ֭ ?F9s9.M6 +9IJ|r{0 +}ӆȻlirR`8SM * ?|8)n j x8P-n\6ZBEtDKx.4@A<9IJ|r{0 +}ӆȻlirR`8SM * /C)RWSulJ"Ԯ@;Sn9u? +媑H:$*wR"R/])n9" 5sjC9V eӽ,*cCcˠ%1n1" +sE \֌2߶Hz, +HjDpt?A(wx'OBȏ۷D[ "ZuE01Z%4͢ND=McBLfhM_;h\M*x,)&F#SB)dv) "*pXzkz+`ze.)u: [5{# C[ٓd"D-ZЛwmйT$T*NXSaLG)7kS RADT)%o?99 ?/##x_E'Ƿ"WW?<|{珒/'_?~ד\'__;|so|3)[?~ה^B|{?/ee?Ǿx+Z8y;1U@QgG>=zL>)_M|/.C}zzrdh=Wu~fԘ_ /ƾ&_Ge^wKuo%bkYjO|uLσ|c଒g|BWz^g^rdh=Wu~fԘ_ /ƾ&_Ge^wKuo 4!uܩ#^9 +h^ 3K*\$j ov׾'y'㦟fY#ݏu^1BT.?*V!d_G>LHmHme{jn,QUpqGUq7v9jއ7&$>玚9Qdv>x 5PVqZ'i~M{{zf1%xhj|vٻA bjQiZ U=^F"=yk* +1s$JF&CGQY=bњkZU#cT{`:QuYGv{y$!;+5#Ȋ&GfQI ƽ`Z&kV}Zs*BȡcL;"ꙎhY[b5ݭ*1 *`V(#=żgE#3(rYm֮)mz,çOIv՗P: 9Y&cy gKv>~'d^ЊC8pby=I)SDNb D(=KO|k=fqfE"%8v]ZJ;Qc l$H'1RED(=Bv>~'d^ЊC8pby=I)SDNb D(=K}oYIVt*ɝn]In!J2o^VZBa08`}1^,[ӁTkeŒWeWەBa\@D=7-'VMxjMBCRɫ2R`@!"!1^,[ӁTkeŒWeWەBa\@D=oD_JEoڶȐK +2.FT\kI`y/IڶR^ox# ѱi;YIwȯ[yW읻A7Ci`s VF6ŰOa䧁k8*{v[vJ?f/7K_z#t?[^pnpml{NR|3?n+^U'n;pZ~YVOY?p_ z>Ծ>Y{7O>}߃To5_|_{Ξҝ$$ꟴoL>:{j>EO[=q!:x%wV}cD_;>ͺ|U=o_vzcHIN=A[?hf?/}>t5|/抟͞{=߳Rvwo/ӕGɕ%uPs}٨계 dNEܳ7O(PbD}8d^IUJIGo#M4z~'~gXO9Cct9ohJog2<(c÷m¼?ES>yO9Cst9(#"OrRJ8;}Fi#U!?c:}[S{@S\O +cw>7 e.J8rZży&1x+d7 G+!iJ^Rð=vvVvKzguFqط h܋@)WY~ˆY"zN}|cv5yK1w1$hфMz1uh܋,@)WY~ˆZzׇ~:OdݝޙGCќ|Ev-d7" +U_?ikFwU вQo/hW +,^FO⋖$VnfE1NBKjbjtgHW6ΪEt} t4v@*. 9@BTl*OjR-B +~)c:` t4tF*BCckچآڵu %s]0zi'7 P + b**1NP> ySu^؈OÝ0QFlZ)llMeTEtJ1 " =Ll_Yq $vˌ15jRg:ID!?ӏf :;Dz]N}m?gP6bj,g6I'Ib)6  R~r6In;eLuub3o$KidzH:p/enrrSR6YBNN慲=HiI^+Y/d\]UBe tH"K])@R:wqׂ;*5b +RZF|tH"[e)wRt ⵟE-T)_VP owK$t:*}pfxU/ 5+WeTX.VZ+gYj IEV$B'Q8ͭu&nc:q/99*kMlaTSE:p4QM4Dni:߷8ݮFncq/55(kMZ,npr$i (t/Q8ͭu&nc:q/99*kMlaTSE:p4QM4Dni:ſ$05H*sQv38M4y5F +.㕕 ]8I{Q?PϞ;7$N=i%:Yei,Uʝf$K]e'yTUc:~P9 $qjӨqY$gQ ,VB咒0S鮒YC*Ϟ;7$N=i%:Yei,Uʝf$K]e'yTUhQ͈pjr=Pz Vڏ"͎![k_ʝ1L/ah)qܹx:/uiէQv6Mnr=o`S(d3=9}3r{n].޸.JŲY<|P97(^Pɉ #%\G7.c=ZEiT]f1x`[-1LN_L=}\w.Alxg[>Ru\+c0FF)S5xM +nD&T +QQSX:Vk1o"u+#臐ѕNtF4̬uts TL){g<3qTJy$܍rGѝ _ľ竆W'ZyÒ6)kDC1]h؋t]F",Xɶn?aI}/+:Y8D60JZ&VV>..(Y(tG88M4R'Mֳ:.hN8z*,-,cR5ao |,Tn 9A#L$Nw_]PsLQ"]F-bj++q ~,Tn :A#&)xxڇ!4*U9ǪEg E9Vf=ݠQ7@7b8Y_xd\T1lP.*If=n&>w+;M⡎6ާjJD}Ef=no<ņp +@*cٴ\/RUu/\({ѻD& +|Oh ͯwX5&ZP G F%r9+I}UYh ھd9'9-NkImz6ػe!U`6YE~P3g!4TQ16'ne6$4U.FU*3⁛jHUOY>H5ql]e2 _EňJ,?(ƉŐΚ*rzJ?Y:H7ZOmkQ,QIR@ˮF%/Q9dn ̢(-!u6)*HwA۷)eɊʉKA4o󶭸M0@h5T)|vaUbdRM#(dn ̢(-!u6)*HwA۷)eɊʉKA4o"\|uQ28;f9 Ba) ̪&0*.&/P! U>:B/jc*EAQ#LDA=7ԕOoj;¨1JARDTHDLDCHz_ * +^D!P1bd" +& "rP 3ϢEM{Xh h .uE;ӵlN=n'KYH3wzmǖ*7aDƥ.:&phKe}W̲fd6vJ +/gussFY#쎥kq呒Hm jUy&4pAT6tJ +?xs֧#Υ}X݅2p͡-^G'2ɛ';upq((dFZ-øj 4=^p\Qn1‚Хz`8A0w 4:Ox7nVNՋfA%X`PS݊T&>]JV]йlE$K 4z b؁ꉀ)ׂ~[.&twtv.[2 wi(>s‡/Pv`0Q0weovM?u۪[LVhp*kXb +Z]UF)Wj㚑Tep +Y +]%tnZ+Nש0G#&*J]YEV)YGAb@R\>M"ki{&&[^\tR +lQJ&v9#ŹT +,T'?<+t ho[-h;o+^D)@j Y)ueZRܤ{f UIp\#?`zv{OWT-{-LL`\ʕ R/qF sׄp֕j3>❦ڝ\#ed"և4dLPWd1h~lk%foNkNK`RrĚz&m&PTT+O`98nqJnqNmNKp2RkC~&k(PXT+Ob>/;SσiZ bRZK,HV~re̻}t@<N +e< c؇4Ej%?_ K + lga[ƛ=4lYbz; Rl{Ɲ=(BWMRDg]A]_Y ?{?6C)CYv>s;7y}}{ߩ5=οj{>) Cu;;MN5sQ0>w]'p}{Ӑ?.߷?މ{MPv3)-}ݷ53n}{3pS/߷zމ{MN5sQ0>w]'p}{Ӑ?.߷?މ{Mt^S6٭6%}wY$Jqk%$pp}:n.B*ȡ +`;)]zgcakLdl}@讑ȳuU9!LxvEBB³T`_kdn:Y#d)TL9J`;)]zgcakLdl}@讑ȳuU9!Lhv#1^AU^U@v)IU)qR͋N K?&/y[б hT7f{eN>|۴G!O {͞]؍UЄQٞC֓12` +Fj,J#YH"^g'oc}+ǽ\%4i7-nʜ|eŷiDB5A>W"V2;ߓuh ;*v2lņIV+sO+~=J9gܼE5ATwt.7õn#vnmLhiT"*OoALg'&پE6ATgT-ɳ6n#vnm ɳT"On=J9gܼE5ATwt.7õn#vnmLhiT"*OmO:O9{DNjއrqsK]!3"ŠQTY&=Y"bG·nՋ=v=jZ.Խ['nhX^Lr)NHD +.@1Iۢmi]k>+OBh^(+%ljXģJKzIM(R72.C1Iۣ}a[j;-MBj^-Փ4,ZQeWB9$TKތmc ^V|^ i;p6*Eγfu_S%KJcB׾Bm$&f T*UnFM H)֊( [(c9؈]\X-u8٠a)9J"^gpxg^ PT6% #Z*b!0-/䆗hźo!~ժL\+J(=}0rBJN"lANHlK +nzOH޽8:?w b]T٢*v&-{ZP/ߡͧMuf)PO]5h!rn^`ݳy#z@>g_)nKd۾4@HIۑ1C26k-@2''׻~Ϝ~3z@zt:ginDY 9_j>V%/7Ph!(r*}AկtgUVT?$BK1X 6i,SP!N=o\cPZpCkny&vXε\@,TBn +78y+Z;t*aXc'TлةB[;IAbg1cPLx{@HK +RnyGѯ6MJr[z )L1~F<]"8{?GJ #yFs;uI=t:z HZ&euiL!!arĘ9c}ݙ}*!Eb(C!%9NQ1 SSAx +"=? ePUDH讉Β*C&*&a"Ep0LfMmRn;W׻PbAƼz͖TQQ^VSYП؋(nG缞>@/_Ϣl됚|{7nMW+dxv."-m3R૪GS +2f1I?[!?/Ee TexYF`I{%K-o,;,;$V1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1cfӟ9Q`l-yZJV]YYHMmJViEFAsp܀(:Ur⫑%f3t ++RV97{"Q*ښq*EdeEbPJs.fxG*y9v-6+]LNWCVfmOJeWBPC(%9RPW5Ur?<{]jJ&s3Pj5y[SR%Wh#P(C Nsi.0Ru=y3PlĥI-d6Y2 T샳4PN.ާ}#LҔnXUzm!cL>q)76'T{fI`a.2-N5neVPxn=.y9h"uޞ1QGOwlD?6;iRԫ +V~M,v %&ݷDꑷtbzԉ#pL 2_$wHc1c1c1c1c1c1c1c1c1c1c1c1cx J{&ѻ&XH1vjNG(MfP9L(zH,,rj~.BnIO#%Z*J2A:.?dU3J 8J5 QQјֆUAʕ[MOR4Dqr!B+Og{j +b/_}s3hU~ xSږrc +Eo H.JR 섇^ﭕct3fi1/?k.7+OvN1Z*UAń-x4Wc"g1H$B1~ _f} +V"w-b>aoD a=jEV{<ԮoW1c1v/" +6$TDzD+w )$J&A+)Q0Oȵt)=/-#z{c4j-aMJT&:lXv{v~j֓p)ɛ"m,*9,hϩ-Myjd)ȕdS9Ĉt:I] 7Ta<$1Ta=Kn7ŝf> WzpT:_.]+7;5E9Yi3۷V6\ IRJiWJ{ .Q7OgLɨ +0ug3_bOp G9M)lI.J[O.YKԢ,-iy vhJ/(X::7?/NKx-*Ykyaa"c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1ccH6M" +S =8Y@KuJ^dߺZTU$p{?D +ce-)zċ9MԢQP3vb1NS00bC@D=<-vfCYjqv:C]EBBJ1cv[BOFu֣(/+J +RG} eIhsW1LT@C=t``~Gʚ0Khyd>+5[`D"'APb&1;Dq1CO!GS*ڋ5CR6}dPʧ˥'cH~ V~-r{1c8£]Ult[iͦ%$[y ۸OIP)PUP +r LPLRSR:~u:zk՘ٕYeҳ(A;Ix J|NA"\5}D"b8jG"!ѹzd\;`ITgVK :D.^/zHf +R$(}%LA|<2㓘[G󾖄~-Qvxaj; +[ 餋_ DY4Qk4tr$3-^:'fɤPUF~ԏt%Tr@ab;_k5m@yE\—Ze8qP-XJp*Oj1?Q^Iiz*c3}'b٣YFj/(X:#/ueed1c!Iy>9쏳׫aj_ *N"Uk:,}i5ǹQ1LP +f Ś΋ߑ^\ol|KE4}ex;r“?vVAaR1L^˔5 F޾Gwo3+6+KG'{ T +`o0Y }vȷԻ?[CGWOӹW,)3ed#2]y>;ӏ.Ԯk\Z,:{I-,9GU)Qܞ}齵5qRi(*8)6-]UB&<*$qT=%Ǚ>ڻ{JW[8g3+z2^;QSdثʨE01 \TGkr{4fϦLNMKk˵ʛGlضvCV޹UƬ"щl AyIk"ɺmVF^UIW0YW "ucL:Lbd{xڱEiedInu#$B&몢D1"#IFcA6̑ZAG Ws!"LUQE8cDGIRcB=V("쬂4@Ud(DU]uTYc1D|331c1c1c1c1c1c1c1c1c1c1c*wg 4Mo =vWN}5A+i Qu<ψ6mEEuuNcV huXtLju9sWCrH(ߺ7bM%1VIJS7V"hSsc&UMfI$tϿ=A:i,qUCnd'<{V"3vZ]Nm5\U颜E +$w ص9Iee cR{?;\ @*L혞>U%#ZD19YFH1b&\v̧1eRvN 0Z9\IBEҋ*5TFmhL:^ƥ:uG, +g+I12MpU1QUZd8 HINcÆʤ-؝FAeacٱ>&rtUk*3&1%!s]91Ŧ{\v[ЌCnCyxMj"Fꜵ7Hz(KKSlNw-`v1 EEi$޵v 2leKpտ<>^q-0,z;2^3m-mG S;Q_I&Ri +p,[Vu dc{p#n/6IϽjD}$d&!D:,\#{~_{1w:Ѫ T#idv$glLevS*'9q1 nf#Suqc[œ39fc7-1HuH)N&(i+ܒvnVw'qaD&b39fc7 T1Hu8H)N&(i径nhH<{]l\{#y:LYME RFn1S$Il1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c"C~ d+T*5<9V] Ε2{爚d_UC&TܶH ƾ$qas@>+1-vkXU$W@>G*t@I$gz?h?o2ak XNjn~8N!-])vA +'S9Hٸgb%شr(vm΢jTIB9 ϧ<4E&_a7=ff)%6N5S"E8 8y챌c1 in] ƀal LRl?h4stBI^(U2q]%_}9/㙷/T8?{Ac3}`f-Iv:iڕ%}0\2Xz!\D8WO[P=Z'mc`8z_.[;Sj8!Z03Z%0tQ=z?<@U<+r xJc=u5gb(K: 9f9 +`ekOO GӪ3Ee Tdu%,X1c+ݶ#P;x'g~Jf~<qkt8ߒNzʼ5<IqMvS$*83Ҧkvj`FY%ElA/P)G&*98r)M;IV*]%5ۢNfrc{@ +#K/.\ ]v }}7eN+eEO5VxR]QTMѓP*fL@-#u!Gp|Ց2PRoBnf1sB,#~9=,һ⏼c}NCCOܱPb$#dN9yX4Br9=Y)'wivgAKbE?y8-%" UTt1Qɽ+(J7p$t;D< +] +&*JR6A賗AD*g!c-5}G/ܱ.\4slf6J~uE5~FU11 xDʐ|CT \0F.WfXS*/VEAHF yY67G$e`6Uuǚ%Z.;#WYFSEOHFyI&Jo= !U·6cF`]v,^T^&Rm{oǚ9Hlm{5 CpI6r0kBB9J&)t?NA}ǻ>=e7K-1RRPt#Lewv ԯ,?hbSInčT>neReHMv\8@DDlQ<{rjohXzFTźR$c옯ղۨU:&ve*$f%u˭(:sO82'D{4fVA@U#$nf[I_pbj?Sc'hi픽_ +{C +Yd]x\g\c޻nURDD 8;Gs&jk8M^@7P36q0.= a/AXx2f$$Xk]؛P +dW"P@(!4>€f!C9:j)pϩv.€;CoOs&{BCj)|(x Xc4>xh6 V3VV2$ܰ-j()"bњӑQ:VFUȊuuIgF"h+jjQ$*bȄ!C4ɨXBEj}aY")kc87!@!#R"h2 +?}-9de\[TpnB&BFB,A:~2FVܮҐmG'M3(*]Utv `3KJ@:eB>64MXHUq(*@DF'$Q&89y\!`֏°$@D%"}!8ry{=`#aA\J +>ŭ9;03@=?@EvY?懺LaXˬuv*f]!!^&SP@e ]yO>)i";z}8?lTz & A.€f!C9^&SP@e ]yO>)i";z}˷1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c@ @C碴V+ZBXĿA W1fQ-1 >R[&h]u3mH&z6hX}Uf`AqqHzQLG?CzF뜍-f5HO[H׏\* FȬ>BB +'6/3~͍-|Dˆ9Vq :{9C[l},,C8FYLS߁d6Sk}zrn?y\vMA ?Ahhk~MŶrwh;//M~G +K +8_<t:r[ 硛wI,SR55S)`1LbSC@@@})r1NC S@1LJb:`!cT]%]4EdΒȪB(Q"HtA5lO[jSpg %۸AR%]#NCd3v-ʓVIД7P)s,Fȟ9`$s'7CA:]7^J!U<{spihQڶ}m\*gW/^D2XNu%J+AE2,#\/K*+:ZϾ9 )8I5?!{;=Cې=|nQ ?S3%q-MBN.,qX'dnE9"EBht?WU+1c3>%~jg{qdTǞ?].g?|;U3,O/'xX<6^OA +V'xX<6^f?볨~v]V _үu2xث?Go(ǯts+]n y5"[&gNMo#HΏ5ˍ`~Orzj!JKkDZ ;gY'E 'Q͚QT;ǧgxw^=NMJFQjDeBH/&h5pl*Cnǩ)h&ѩ*1)J>C[ARo$䤍f/teQ34rstIB37LkҍVUvR$̤h1ZXNbE㐖bG"uTL\*&I ʼ8AA㖙jFx|i&$]D,ȒR܄"8rP7D)2fi3zQjQdx W KIHr7HNP7D)3+[^3;n}-oUw:B2YoM%]"!ESSW>݋-{N\gU:vUyy7KJNF𤋮mDC]ǮiV<4+xN]kNdLƻI6"dn+J^FzDnŖ'AYJ^*Xf#]I6"tk*N!Gu֚C]slzc+) ? ]B2)0lR$ID)N/8u?_ +&>wC83d٪x3Q0HHJ:!w2IC(ȩJp\mɭ-l(Z6bP]Q:+#6%TL d!d;BLT8OS(h#ˮh͒3fD## (A߮% g")9&u]D5vV^8j\bJd;qm+dkHѳ FA;6O&0YIe}#@K3|m}Ǹ5: +M9f`B6nc[13VOSɩDLPDζ4"$ò1f\3VOjIOLER"br@%{L>&Ƴ0f7v1ҭҘq'Od_DU"&(w"Y5ͫwNmb#c +[) -fW6NbP3˩_rݵUɜt4!L\~7>׻Wqk22)cW$jf@`X[R >q\ͭ+Gem]Sƣ`֫䔬CGL UpõQT@t]T4.:Z˥XɪbeDQ:bcwXwQ/`T&xz|@V4c jFU'G;3,"&7uWaŚɮmnoCIV- -)ƹ :J""n%]/i6)z&K#I^,/%ZQae%70r Fy}Wa$glRõ/p Q,(&ȸrt(/SԴtiMFVe'6EѢ+""ai\5E#i5̚^Gj3䗎:")Ml[TWE(eCS8"j0#夗1/w"r:=KO|Ll&QkfRsd]")B.PR<\ɨ_H@tzHx5j^:۫ucꕫSDf5t+[.Wmv/U!1RL}.>덫khl][zv +~)jrW> +@_74{Gqkj[*zT W lMAȊB! UϽ*bbB;>Aq\m]Ϭ[Cgl]RӰVFKV dH7 xHLTR7l|dڛDjJz3[\F!VZve*EBe\fv +4jE$ICo=qdm=3kZgk +hq lp5斴AHJ4 W 2;f9+L dty񽠧4{Z5֕[rј#^AכV!Xa U7I;M4™Ι#48=ǭαk +ǣ\[Z#W*0fT-\,훤M0194`[Ⱦ+[ :[ "7B"/j01aI0wn`)YeA2IUOGr`E!$'DKQrPY7B:ɤdYPLRp"G!d'0`Gr~TYkiGb grk,&I*NWPLVA$HC }Yd[ +&u]c$QE"UU%"iB sd + (&(uVYS4I2QE B&BuڪJ,)UUTM$LuQC"""UI]uES:,ʚI$D(!!DDD:aӇ y 8ٔDҔ^ݿނrVt=^$K).RzSoYTiJR}\Uh9<-$R]gݎb,iifNX[ +zǩ>#]j6|dmeR,ZӵɮYMbUn ( +d=I$8Em">wgkLNO[2p/7W@=I$:U⼃]c)-'ZI)!+"2M+c`\:S^N\Be7+9 +iaFw:AK6X)lRT4G()6!$4aDK,dc:vAST)nA)~!.T+FSxRo.flkpO#ĻQe,BVɈ/qMIら ;x]UW6{2Ld=T&&@]pg '*,}~pc#'?:gpB)pM>'3@씪Rb(f3@a8 H\wD8d8M<T PqfeLQ9c8yLT@s|:ÄBKqezgYn5#k*5WQy6M!c\p9E&s>UC|E)>?JDԴgа%[zRNcH8XOB,-MΙcv˿4(e%%.RAΡ>u2)Ho c; +" tc*|j6R|~l49]{i@ϡ`J$˶pюX[ut2O ͹f3nX1:SB\tejv.T'6W&FTr>H4>ncBW;2N +%G^ou&ifɺlu)kG,sʂq JzpfLsWdU*PO4ݣQS-dEkݡN^n?]?lD)s7S$|Kg*d[FG36'XSsWDU::{4N6Me뭩K^r?\FH5}$}cTlUcEd#2`u»"Rw|rZQft[XZhX+0M'F/Op)4X& Gq(ᵀGжuJ&72)k5;E7HI2R&5?Ǐ- +Z +.ʪVU63LDXCȆ K"WU$BR@Lj;>`yEǝ >U5QN ~)H|3Y؏|`Ծ)EuL$1~dy;?Smɚ>qvrdRalmj#e_[mvE1SC)zΦ_͓Vi:Z}kT`eYB1tD{RAE` QyޜCeTZ>}qS(";Ҝ@:=jL Ks~I|8wp.kfjAdfK{z3zjEߪmz}_LO2Ԇ((WE45n2 (_X6HޢMVnR8Ԇ}P'&bT^J 3zSuPMTdMBBJr1C@~ʚ("gIdtIR5Q3 N0r@CH E:? K_9N36Qsfv)5ܙغ9lɉ]B ҏe!(r?`_uUdI_#\IeX0KaۼoA>M)SdkDܪQȴR"iQDEEcŞԇ*b6O~%/fiMY4yp~ GIe%ZfE "c +D77y9΁ٵ-g +QM;Q]xGe+)'F C +)ٌ󸱌cT>X]t݊eb.E0*лfL*|*^ +?PoeO[𸻗TZakRlm9tINtyDغ\LBz̅)eۗUbu:͒~ezPmժqlm/mڃLIH?1Ι4q$0 #/uf3U"c30?yWmFw7O>Lyٝ qϳ%S2<$>2 A|"W?e7ul|"W?ekc:on*J[(w?w{|zJ;?ȗI [/%fy$M?>l $j(gRS3/UszzE>tm^67e~4" E#@ 򲏞+0]ۓC7@㡣v|"->n0)&ڝL&:ps}&exhݗЋT[;1L .>xSwnNq:Siv8Xܹ;ۀIhZ,`׽)iAʜٕSW GK p=@eL:@?iAʮr62`jȇNhIuE7~*spFKfUN \/,QDM0tފoU.cf|'SWm2.! 7ײ;i$[@hG Dzo#Jo 9잧8*E2o"e;B(F2'Ԣ=:iqwƽvH I&LPMG =$J#+j1DD&'wGhUj|\8uuoDV^NhإLE$'2}M;8V迆L;dЊ뽶.P ] iFcyGp񇕍?ѝ&&cRj^d؊k3@Lra'Q흜X?_r +in&tWEuukuUt#U1m c56z]4Hݛ-MZ5nPMͩ蠉DDDj'K5nNfM* ZkJ#VI":ji?h3M:m f"٦lA +ZH@M2j'K5nNfM* ZkJ#VI":ji?h333?xۓSR:36];Azi9{72.(t޺QߴfK̄}nIMvv!(Xӯz H,R҃v(9kYSWtY/T$SNPPs2 NVleT~=\tQvV$S{:"@?hv(9kYSWtY/T$SNPPs}0XrT:+EoSU}Hlm<6e#po+L~;!H%9dp~[IKK3HMx ]$ukuu'a XnaUk'/0cLP?!<=OW^ަr+x\>bWύ>e|iowzN5_skrԟ>};w+ 𯘬WC^ޣUW/Mi>I|ݟ}4;No~o#751ǜusy'.d Bjm_W]sg`F]r%Qs"ثTL tH1vuCGXu2LK]G[p%Q$Mwەe E"'/i֏ i:_WX1k+uclYq*"k^ܫ,$S)0"xh~~T4zuK=w]Yc$݄ugUA~͹VX $R)0"zO5w]i=zD$td՝4{k]Ef>[D$&%e7U2ii& ?RqDմ84"KX[E1Bn|ٺ ˤ>rLDHBCqTqƍ G5(HD"X϶dty7eI {)%$YOQC1"e"d! ?RqDմ84"KX[E1Bn|ٺ ˤ>rLDHB/6[׈;eE4=k;>226 hY!efA'Pi7 +(@q骘 :=a8GWSfE~:=S+;?%,)1tAj@[Q0HQȇ׋zomVA6ٺʡ3`.0z{%''beSE7R25NH-9 zjBryE➰ܜ]jt m["zc MDHט \ -騘(cڍ49CYj?6\ AF:]V-NR'C$S˴cSR{ O/"uCJ䝁 +PRa(f+E'AL &ٜXz˥UkeIKNI87O]B'T:tm~Iu&Fbd]"tmŁP}5SFfc1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1crhnOjUL 2ӤlTHAUt7%nnf0*jO B2vs WbJW~BL2L EQoiRmmVTE$P7n4*2i1MOapQA>0*Ҵ~old^OD_r^awE"9IOnn+ƈiWsMS0BKv\^GS7r@zu%,XvjG$V1cdgrU&huôޒ2oUNʍJ:*=W-Ȗ!ۃ9r"#a|nosZh*^lwचJ!\NadTp2c1ʺ%N'Ϯ2CXTk-1KޜI4+J6EfJ.2ϋc61ʲ(##_<[[V!zJ8)&W%Xc" źXrICtnåVZ_q(ǕN&Wx:[(QtS:v][p qrșN"D9{Dї-r¬z< + L-vJ=FJd\X!&l;}PWh(Q%0Loչ:,tl$CMr+|*G\C G>ν31>1]Cxfy|zJ;V9\/vgǯts+]n y5"[&gNMo#H˱i8!7/Sܶ_76x+!i)7ݞŪZ띱'0@+[0vSڶ +!DL+uքe\6lISbcy0p+q7C(@Dy֢?Z`4n!4ev0pTJE+uքe\6lISbcy0p+q7C(@DRx/U/"BïprcH3b3cɕ!եQltIv"$g=_ټ/["M=ZL73Ye\S-W8M>HHI ql)^ݧ1g\zգIڛn8ɜ3]4A!!$g=_ټ/["M=ZL73Ye\S-W8M>HHKBrUpl9V [Kt62@-+44f@8ti1ϩiosW&UzD 7.WMX"akTIK<ڵDer 6 6]SN뫆λHNI8pB-ߤe^ +mP1pPlOll=ymW@rt&AtMTJQg+2O #/Q(2aڒzuN<\FTeel y͓Ι=W-6nӒ];rM\%]p.کʂM +p6[<9Vf/7KUXe7#÷$䬠˹K:Q2PTAC 8)~'2{5*Zm'`ݧ$(v䚹(J ;X]?;S)Nu '0mH*yM݁:;˵8( +oת%slAuV4xo#1.73dUJbE"PD=U"~Qз`[HJc\ޛ&˼kH͉K9j T1ټE@:9T5xψB$(J-zrnGYmΓʿ:pW2+JQ3WI rk^Nֈkz\ʺY@N 5@7U"LGn ]!jA%C7#,6Ie_Aj8n%S9L42ɔ! 4cU@LHG?@L)L:B ctoiD~9$)RS )*uL҈92 rHS2&ST8  '0&=s$yW[I6|f5YHe[=zPAjq1ZE;Gc|P_yMh.ݔQja9"]0l~5~yhл=uO)U:( q|s=s vm<\NAvW Q͖( ~ɀco}Vy®?]eГ5}|lW&YFB0Z"Q1Y9U)vĝ#nFBF&\\Ȼ.!~A%VYuec +tLUspZZ &5zp@2.P6UUQӶ~,aQVnQWnÀۢxmвH딋Vyw2ؚ$;nl,aQVnW$;޳Ǟ +=2&Rg[[(T4tf&6JWc+ ^ʁL,q +_ۚxRͣ$eh6j]1.WUqɤ.ܬۿ{X0(FʫR'/νmS2d%(Jm=RwKt3J8U'nn߽*MeU)H&/m_ѼJ٩fђ25.Er{+*8UnVn߽MeU)S?vZ:\ +4Y8:5KZ~rPw%jV"Ѳ@LiNJA2HLSwKHl@%HzufE$Җ'[(VX +{BbZ]5C~q*HȚnEʖ͐8"ۙP*niUIN9dRuUbުT/`8HLSwKj^ut1w' ^ˡ[^0P'AEk76[v5N`RARCG'ڼ/Y6Mi1? phNz؊ĂQa.X8]Û5d֞ӳ%jlEzkrA(BbO@\2:`W#&ɭ?'Ty ԯZ^ؐS>P9̉]cpGHo{WFYs( .iQDE6W)YziO 5bxUc}hiFLT 'U΢7P)U@J?HgSqm_yic-(ɣ$: g;hM +UP [M;iᦡl_o +c- (ɛ곞YX* G׏ +i @z_LFVtAs(:gP +oAB컄Z\8=#h Ҷ}!MB\b؊8 )ېD@!v8z[YDR-(fMR\-"Ԋ8ʋ9uې7B컄Z\8=#h Ҷ}!MB\b؊8 )ېD@!rAۄ&-aܲmbck9H=)-;BV{ IkkqLpX L1JNwkH7cɽ+50QbZry뷠DǸv.$O5:VIl{F°I6T"+SIjZZ)W{: 2 U-b(V $tdžEb +i:m\W+?QRV 1噴Kc*6M1XNVժaO}DT `=kzPqyfX.;D +**TS(}F:JNCk_*BWty++))VK$.XH)N)BpAtΙCk:yleg`Re- ȹb P8u'MܒSk_*BWty++))VK$.XH)N)BpAtΙCB?+{VIx2[Zڴ>-+ f<(1hRD/%;r]\0f@jڼsW)`ZF6].2I{@A&펡/׭~o7lZ?PZƱb-hZ6].6E;@A$C}RD/%;r]\0f@jڼsW)`ZF6].2I{@A&펡i)yU~ִs'rҒA^xpJ1֠^IKO$οTddlr&ZŔT(j[bIK?"bX*'s%!!aQ4d0@8 PPw$WQLćg_rb}G2R269eENf-b*zu4fM1c1c1c1c1c1c1c1c1y)Q8j}Xݾ(YX +:5E$RS}ӓV&Q(UR9q.y3TrPIN8zgP?FztՉJfzK`&jL+p&n!ў3¹;GEdtxf˕Tr):اTȨʺ4pbҼC|3_[ ȾJ?>չJ2?|փScqJȾJ?>չJ1/ϡn|փScqJȾJ?>չJ1/ϡn|փScqJȾJ?>չJ1/ϡn|փScqJȾJ?>չJ1/ϡn|փScqJȾJ?>չJ1/ϡn|փScqJȾJ?>չJ1/ϡn|փScqJȾJ?>չJ1/ϡn|փScqJȾJ?>չJ1/ϡn|փScqJȾJ?>չJ1/ϡn|փScqJȾJ?>չJ1/ϡn|փScqJȾJ?>չJ1/ϡn|փScqJȾJ?>չJ1/ϡn|փScqJȾJ?>չJ1/ϡn|փScqJȾJ?>չJ1/ϡn|փScqJȾJ?>չJ1/ϡn|փScqJȾJ?>չJ1/ϡn|փSg:AD?`aZt>+@]obA9[M=%٫ zlUn_o¹t+|փSgmWN&] ;<~QфEM sRBXkyPౄ(?C<WҎ Uו9>b,*_RcS"')DTY}t81#@o9bM\{qeu:ꖾøsX=::7i<K?Bj/DfXtK;[ u7 Vf"δ~D2PhDL֝i7Q54nRŻX5):2LΑoN~Gd%*sĞ#WX{`r#ܵ%Zԝ^u?R|S%R!EW +IAPWP,NVټ%d*uTQ2 +JZ=eBUEQӐKA'0N,q[sj]uۻNǮgldOLVM-k~#00;rH:`gCE CK{b6 /\q)\<1 weXV+uԇlDH4J"Q =D-#'Xw1ffe1mxZ h*CȞTn5KCUL.v+|KW1L&G%]31:810z:ve&g#WrԍMY{$dUR1]s d;x(uN~eZ%Wn7U7UiHRP,l DXd2pC8ךGLk l!v p*&)(v ۬,`׊bTŝqʵKr3oXno4׸XA8`ɪd#NDj qTP0Px8jv1-~ 60 я` *M0d܉$@ +B=@WDF`1j(Mݣ&4P`f!"plBG1bl( ۦ YDBHPi*_i)$l2*1L7L +v D!@ +B=燎LȄ-w'";fɦlj(X#;hi"4uLR=ş<(QaZ"`;|I&Z&Λ;73򐉑A!0^0xߚW۵,}lϭ_yI&24s9ĺ_L JzϋAitCrrqr(ݰ^]یTAC -{ gMEHDȠ +S0~8w?5j5O>g-ٗ >[y۳K?dﰿ&|{ +b:}/-ӭ)[;nobe-skߟ~ O˵W|;CyK^_M[W~Ӿ=1h>~xǭw7epKZxō%-Ҍ³;!Vu"U*.墠h%\:f^ NԶ=?-a$lʽ27/[,CN6!DC*C&UGqRjKcY  +aup^7Y‡V5̔tK UU'N~'j[㎟簒6]Ne^}\rpՌs'fUlƿ6i ]$";@DGE::K96b =mOHZ4PLS DK'(7 \5A< ;fi(󽳪{\u^Ë z%Xfb ᔔs&4A'M0}=#yk[A1ND-. Tt2ptr$\Cރ d^ؐSOYB +([duH5vb E&mLؿ2)ݒj 6J1G\ˣUlޱY@l#"BjEN^=+ʏ"Do[PF}m8,a+"U8Jc{DxܷO,\}vU[/7e(/yP4HȸPtڑSD0GJ><kjWܚst_hlwLJ57IDFEWQ|Z72*e,+K%N*Z,%O`~7 FGF_ Ab@UUC(e;I|\%uZAKEᤖ8i +ObXGUU uT)K%N*Z,%O`~7 FGF_ Ab@UUC(e;I?mdɵwWV yl?y;/X`{a5@kk# +Vv D#*Mr᰼oip %o2uo& pi93 +o:nZ+_D&")`21}F̚E;`b*R1@ò T;$#ڐG$nѹ]^جkQ "$iPh܄ ӽv*_5#J=}FAu+:/Y17 +L"Yr93^8:m7U0Adzk?MEwK6t 9fTU<g/qRUzOy5+XcY!.,b91SE%8qߍvyW|u$ +mLN,~"5J" G7PE^ME>͝xQ+,>Z"Nj}_5v&1L* U&AC;I{5NlǓ~5]Ҥ/*{Vr=18 l(LCr +X86=ɺR0R>N]Xnld@lWQ?o %g䷒ +͑!e=e +WAUg- +nE9AcvCw x= jU$R6%-;bH՝gED"'cB*S GH%-kQNp3xw5K4U]1!)E\@xYŤkyXF9&U>&T,rfeQDUUa$*_g{ o},Ӄڇp]K#jթ{ Iq@LEQF~R } c҇\{GV+o(@V?H2i3U=\a|vm㢯ep`;P wmZ r 5n6(ɓH +( +U=\oʯ*m؄I-ɹۓp B&lw"V` J)F) "mӛ[kg2]TjMnZЇp)nGl@<<[yU2O7rĦ)>˖f1U[KBqL+r;f@ܡ3C7>H9!z$BMrskmsxFKm_["cBfx_i- 5E *fWkMP"=fH5hئPlB)>8Ž-=(u"OHBZjI2lr4[6@87hI1L3n1иE dMۉ5EZ'olrD[@87hi1Li-!iI@;xvhETMѐ~`[٢ٲ1DLNe,rK/c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c +endstream +endobj +12 0 obj +<> +stream +xmSn0 +"EChފmA_JZfaц+ x2ANՕ +\WzBI0 W4q Gx@rSOg{<9=/5#m ^$SX #̆,H$:A䓮c@g6z"}6Cev%;#$+gtZYE5j +fYM|BRz/@R]@kg/jy\Dw.ww3ʀszB\Y9rw'2E i1kY R=iypdwi5>TG>TR+]=/4W[WAxW-ŠSm7 +endstream +endobj +17 0 obj +<> +stream +xTn0 |;$M`PVt]oKIQ$S3w$? +ڏ@4ױT~ ǜ9r4PuU`̈iBh+!ND3)bƚ9IF)T,ٞ B3r)}>ݮ.eh_-$|7jw is%C.Q8&Y#~?GjebzMK.ݙK׾ +k3nأ<i0`8?&*:Zc}3UDjYuHA*cel'N۶zA$c8C--}rΠ(S!k[pep?Z\7u#J;%WG؉$t{q +jcq}Ўe22ݻ8aFQ /** +endstream +endobj +20 0 obj +<>/Filter/FlateDecode/Length +496>> +stream +x܉0 @ +v 8-~)+w||cc1ׯj>{(1{;f=ΉYŬ c֫1}}GP}Zc}mvs\O\w\ϬW\ 7\+\KykܵȚv]ˬY:kԵt][9k̵ɚr\۬>kup\G~uv]Ǭ^9utݰ]W>urݲ\׬=UpU\%zW UĪvU]eZWUȪtUsϮʾ6[u![Gvks܄=gbsLܗ='g{ފcE{dޝS`:>ob>>ej>dosg9 +va90vn3d29Vvf9|6y`s16wͩas}$67bs76 dsJ69esat +endstream +endobj +21 0 obj +<>/Filter/FlateDecode/Length 3494>> +stream +x tU;I.}Ty.@eEJyuVe=(ǢQ\Q좬(R)oq9E.UvA6}fL2d2I'dͽ''LgMZ(OsGX `!p4 * ]zf'X_!?W !&Ϩ sd˷"LcZ&?&N6'D7 d}"5P o Gf!g!K~:zˌ[X9}\l-Ҝ3S z3enM%xPe$ҞoΚ]'JYZsǏm$Nf (-ߵ7 0֖)XngpdDQx["CV¿$2xgG,bW:ֹ!Ce>H-;lg6,(Ak9}X'$Y*TBh?tߨW f\Q/q|91=W#2,EyH\,G D,1*4kq4@1-GW}6@ed}@rĀw`\o!2bž!f9l@:g@Q%2EEƱy[bDo {(B27gVM 7Àet>f+*jQ TE1jЖ.@K1X3bkfׯ!e5ѽf8xXPQHeiWjڝBX N^Ǘ$qH~ NegvH4Oz"Aژu+8Ꮔ%9HiG}֖I dක`fZ[ 9d)k}}Bagiܒhi72+)1ҀBZX1aai̒h25 8miXEM b)j9--F-CLw5`i7+l<9oK .jBߍApB8fgnRݜo׻3Јk$=cw M_V5c)X0nw42tkC// +EQ,J=j{ql:-dacehp2aڵyEl- +JJ=k^ Zulart +WZt֖)1UdZuirow ֩Hm rhSvdmjO;Bנ*-[p.AJdˏ:+D`i6o 7~ڔ:em}2n9L wKTx/ (L0r K+!&=Û~_6um"9}CZMkgl<*:6!?J(H qG[ڦͳOWBVTO9=9l/%9/D*|IбLEi}t'rG66ۘ"@n\bi(,^?9]Nqh"֖NƲ'ymL@zFޕ6{0 񷗽)}][YR/&w,R0MY}]o遼)+Al?9FgǹLOkxE()\L&dU2B)#:1w9? )Uf$)'⾌"xUlkuZZO6V-!R\-K`ngk{4yY‡dDaӇk hZ1D7eC?kZD7/yE*2Hӊ%=0^-7D'gſ베йϖ!V[\UH՟T\H#KM_VU)cy_K6KLxl#nrs>2`qm4%ݹKie?hrqw_gQQ˾?erqyjȐ}~u^GQZճ{KPcCli5E4`CJg˖ҧ ى%lH>M =Tس%8)1m$dcA;C~٘&RVX::F-n# `AbE6jio)]NjM3Kwְ{>?"PhX"yS<{=;t)'<0?޽n #e7Zm) (-Ͷv22*vgŋn9Izjf(\2sɤjfhfŷZjz>R+K/-%;jH-m7'r"0ji,-_zOJ/6ŪgGCK0;.+qXɶXNsM,me> סtlmN'H-4WvyLZw>RKhZ~#D{7LόZji7N-Kt+3vNbF-5Ml]PyRbaMMkh16q8زhצWN4.2K VT[T2(p-9l;67ROP[ƫjKDZfbU%솫lbJ-u ڷ%:^|=o_,ҘRK}-k e ]Whp1:Z*kDǏnv?j[K{l"~M( +2J-6}LTHUǎ -QB*DNj&]QK,rDf)ZWʮ|R 4 E}yr#84#Yum^$ji,`e%-ک6ul,-j!ovB 4%z)jQK *893jiPhu 1|TbnYE-ccՁw +RF> +stream +xڥWj;+Hg .0{ޙߤ'vH0-t[v?\tkZ|ssej~-_BsBܻ+n\~*&K pˋ\.{-u^R/TIԭ+vE[*( vnA^0g9nAa w!*-#IX-RKmErcSC LD+*~w4%?њ鳙q"I +ѼN|l}r/eDsQYp9O?elbhQc0՚!ojRY+JFuO&+5:L#JI[bq{ey~B2vLxt!,bm4G-MN!^g"9~rDq$^.&!,4mP_-N"տ9%81J. d}%৸5ƭyI.Q]$NXJ+zIݔT$8{ +m<̈́=Hj)6qRNMuK|I?|#{/#!.S'ߟզyߞ]d5qz'DjǐNOG)FJUzҽ+A :3#PǙ.-e=AvˇD +endstream +endobj +28 0 obj +<>/Filter/FlateDecode/Length +279>> +stream +x /7k m=x +endstream +endobj +29 0 obj +<>/Filter/FlateDecode/Length 9249>> +stream +xy\yǩhզ٣a%&h˸:mƚ}n7F!۝h!yO)s:וN~-M?~؄ T$  HA A@$  HA A@$  HA A@$  HA A@$  HA A@$  B/^xijjjJJJvvv^^^QQ>WRR322n׮: <03g>|8!!_^^Ç?Jrf455O ׯoݺuɘ,)++Rʕ+Ǎ7j([[[@oTTTdd$Ros(Lo ,^9 /p^v7n3r̪*M6!^KMMkV#۷CBB~d)TϟOKK֭6E/ٳgɒ%͛7+26mڔ"`ܹ3k֬;vrsƌh+++ 5@/ٳaÆ;wS#L4͛ZY(++۰aCPPP~~B.q@IIv?N/^^G"999s̹{.@hjjA#jhhȇ+INN1cIw4oޜ'Ȃ-[@p'SSS\LUUվ}P***;vTTT[ʕ+$ 6mjccëK*,,\|wH (++z>~bŊ%B4<{Ahii))) a䪶lQ ` CRL(}}}:w (55͕JJJ6nطo_UUUIC!QSS;x`)ȑ#"""Feii٢E Xm } #pttD*n0 2ĉ[ %9s>5k(="BS-Ct!C=?~<''@%%%-((8y$ 0...Ȃ'@ ܿN L޽,N~~~]H0h۶m˖-e[?n"FKKKmwܑ8@?Ѐ~޽!TTTTdT!qp5 JJJ2hRx2@sK|2 Jy ~( ~ٖD~5$BTTTHƑ"\$Bs>B+U!1UfMQRRbdNB,PXXHeìEEExj+A^^>CpUQVttt+|YflWν(Ѭ$:}l:;;;gϞeddzׅ ҀP[kW@[n۶mǎE+B'~ݠh>-{T<٫W_/^E1g UtmРA:ujѢYy]ɰr/--|{RE[!TMDD-УGkkkSSS'@5J]h,qa"OܹDX[cǎYXX@vvvnӦP1r(>F(:n:z˗o7H \011 &NԼy/M߯kBcC_f~~>ŋO#^$lO>ݶmݻ==='LлwoHBzeipMݻwoFr3J'Mp(|}}:v_)%K޽{ݺuނΈ^~=uT9 +>\՞BF+#F̙3QVSSS:"oӦM_l+3xY<Ԅu<@ax722-ݻ_(;;{ҥ>>>W\cY_fl`˟)S h]qq1ʘD6,>K| /_D)5~xy{eeex;aNNN4&2}ǁ](^p޿yС#F=H___Qu,66v۶mn⸃W]$+\Oxx %//) +"KKz:w'úp1N>}ҥTrݻz8tNލ´ kZ[[ڶjJUUUʯhM&5Fߦ=N]ünhhhLL PW{nѪ&e``%vGxUnnnNNB7?}'']^z Qcc2{@...e<( + ¢M6 0i"xB~P XM1ٓڒ!}J3gE4{{nݺaC %uguC166Fy~(#Aԅc].;Zv̌ڕ///i<&PYYq~ebb @JH93_=zŋvvvL0a׮] +PEq5_till,"h~Pbb"0`_"Q"e"_~֭_ɓp ]]]k[ + 0˩ݻ;&e˖>|ɏeP\feeUCĄ?~\*) 6LY +(߼yg;wֳi~~7j}hff @/BɓgϞY/pYZKv'O0)q=zDjf͚d_D^bEqвe/^ԩS7of{̺絵au턆ֿG(//fnsrrV^-$1cFe ƍN`?+\4o'Nعs'\&΂%*@eeeDDıc;sL]󍍍yNNN'O?~|AA5 4H穪"FV&>_ + +B/TTT #G#,;,,Lr /]0GCC֯Zn4͛:8;vxzzžpgϞ2e +|'ǭ'ӣUVH$x>HDHӧ/YTʕ+_z%,w.\@62w\6(BFz :gϞ d͚5x܈-ǝ4i$FFy47o Մ$v`nPpLzY;w駟/.[ P!,PWWGSyNa``SC!,UUUHG%,a%jyx&~T Hq =̘16Dwt|+/Z^śۈm۶F(}tn{9_NBpݻg{+Lق5G--0>)X-@<Ǐ-$nEzjuuu ---..چ`VZ\RuYիWy;wnnݸ?o}c*++ D4m/$$D!V]j,O9994|`ŋ(@III'FPVV=zO pqqYlb-SUUUJ?}xW%1!!!\kذÇN~G>lVYgKhii-\'[J@ee%̀!X18%)S 8/#7o(|Qҳgϰ0g+W^ qhbҥ +rss7$9ׯR2x񢬬`M/Yiii`͛#yzA boo1? -G0idJJ&&&@UUUff&5}7nG=H+<M0ֲeV'/_K)ܺwLϟalߟ_RRRFppp2d tRSSFDDnj j"={vϞ=PBYY†-le龾RRmΜ93 gΜ~ !@u +i5dr20X S[[_~}]x]֭[kAuj-$|Duu-[蠂%-֑XbĈr ۽{ѣG?W[WWewş;jDZczyy `۷o9rܹs|پ}z`mccjժӧO?M|ZC&MBiӦoMLLQVo޼Ucqq¯sΰ~Ї;v `Æ !f kzJ^/_`hn߾ N:p˗eE;ե{{+pD&gb۰aC˖-/P 0~ؚ [OǏC!g///o )7<\#z wÇoժ֡C{*AIIuttY:W_}^2f>xXYY1;&OJ7GB7'coL8A4;1}kk899qyނuI>-4c V322""Beeej֭[wpHي<ӳ022b?~|9q<ߠ[ncooߤQuVYrr\ܜ P;vlѢ{N*cff%r VO?|,~?zB@cIj&_kkjjrGqEFF?N~|ɉ~t.˗9TӎŽz>+MA#s`|ϸWQQiаS-FpKs'F伕(" HA FLo +endstream +endobj +32 0 obj +<>/Filter/FlateDecode/Length +56>> +stream +xA /Rx~ nvnvnvnv][ +endstream +endobj +33 0 obj +<>]/SMask +32 0 R/Type/XObject/Subtype/Image/Width 92/Height 92/BitsPerComponent 8/DecodeParms<>/Filter/FlateDecode/Length 3286>> +stream +x t33'IZ*ڀ!">(hU ! Z!Ԟz<@j}`khi-Jk} bxcn6p8!3s7ߝbA,֣`nzzs/$qPl2t۶|EPx, +8rTƅ"-omU \W݊inAأ}Y;kq +qĈpx gx%3Ld2if}\֕&KbtuoX.՗Am-2>zD[d.D_/ O޸\5X/^xE13Lr~4#_f1ٙT0cHEbR[NH)hA[`˱nq +5c(W\>5Gq |[ϑXexG4%?uw޻(Nlذz!x ŞM6eN4%t(p.LࠆBZ_foA(8pp*&\N3ϥA.ك4}"B>ER՛=˾a,εuA!s~"~{S%yX.Kfc-k?$}MZ|_^ST{ipwF@rRV_ꅜ<8AE2[Aȅ˻Rz.Usk|߉VKs1 qԔ +-.I/>}7zh{>D>,:y?2EVڥB#=_e98nyUeH|%|s_ȺhbEQ~$R3u%zd)bͩQ3vKno e_s#O(!4Ec֨1DυtD@!KD'[y:PC,u]):kJ)uTh-MU$b`O97Sr1PlDdmpxu`kX Bcgg:˘d.$bb +n9L>:];ף?&[(\ 2Jd:%*Z5%\0KK k#;~BصAok~#}X[b?qxeY6|\](j>bQa/@r^!Yl?y4+c܏H$m\]d 7Yr?@=F:Bb$r&>VC.L-.ںhp 779y:c]_/žrK`SqOQ4}At_vЙ[-~Ց㥏9{C"c$~\6P۸'2/&O7G 1p.H#mJ +eBwN: '/i|fEĘtހ/Q@G,R{[j;1OCvV!Lb>{~b1ǽ>#N殘>0}&rpN +|vY@ *kZE12B肋q#Ggcvc%g +޹#*>PaokjPdGi}{ +:e2E+mW=1mnrQs<\eKqe~Y)tRޗn'T1 R.^,]]Rtp6wxbI\䧿CRx!` X,b3gGó\K[ B;Ԥ.DpI4tM }~> t%G_"75bS-rTFyc{nŗ p=!~2})ȢqdZ +c1Y\bҦT>^77.sK9k;%>\"dXſuOzAjq fb0f[P}<B-7 žGO2 +IFOU C~<|#Ax/[EAp.!x zaL AF&ĆOݻw8#s&M7-?KH?Hra~ E(Ҕ4 rh܏1@FÈTܯJð`Yxm΢$.6a.$kd"t#%\مf%n}sA/N,+ND^2h/|ڏ4DBG1WYfDGBF3RejnN1 FVK^WmFKQt_³TϺ!O4…B>lXn,KOfBc`1m]`h!&! o1EE #J$FmɺY20ҫ9E=2phL3c&^q} }XeUoDZ( +讄qjuYhIEJBQt/sKMrI=Y#kRh* (p1o +aO0"<}S3b;˘Q*/(gr=MKsoOquPӄ#k^i0+䍭qyn!?8YR)T H!B#VCQV>/Filter/FlateDecode/Length +2128>> +stream +xyXYϭH{j4!s+% +Y=PCi}2ǧlYQYTJnЩ/l~kЭds+m=e`%=]Ydn:eVSg{d=''ݗgC}_iiퟝycslNѸGL:`cd;=ͽ~rf+`vea/':OQfJ\hcH>މfVf yjuKh0ʼn W|ޫ#f)iM[FHz-1½wuL^l|rBc.;䁅%on[_eW^8bEGq<,~,nku5Cj&׮%AI?0<P8O;sI#R\s]u& 20Zo˗U<>RVQҥkO p-[DM3ELƑؗazwhqj_8Kô%"V3.is4XjZ=2' +iGbz8cR#Ys B֟'GM o[оeÚ5WZa#NYs_C֑IxXw|WGYr]3TpkYre;ˤXXr("J5.u%w +|޸E'2|aUJFj5MhSA,P3:X4.xD~ I=6Pš9DslȚ茪:wpv-Ywz`eȼw!6mQ0d9s.ޱ2 o;{BJWmVrcƃ70ܛ%R0rAYQ+ǦOsq1r˺2w PϠ 0xk~rw([ظS1T|{f1+lܜ\04q]S`1qd,rGg`MͮBhr 9;;:J6b S['P)8Ku*qE2rኑIC ũŸ]Gw#{%/")#s`O:hBrK:wbNФ2lf`NkPUd)_4B@"ō9B`4~ˀ&i-O./4l}&%hLMSS\eW"bs)!si[ O!kZӒeKѩ\&VHBB0BXo'HqyRq#ֽ:Ζ16Qܦ*W(7HdTZ ,=bxR.B>j䂣 LczwxGϫڔ<{b8M@ܳy_"$ވ\X*5XEwﵬDj1As *^9;!GAf䙷B.zD +endstream +endobj +35 0 obj +<> +stream + +endstream +endobj +36 0 obj +<>/Filter/FlateDecode/Length 818>> +stream +x0 DCU^֛XI 2Ɏ#ٶm>,`N?}l_ !7q[ ,ܶ )mq4&&&&&&&&&&&&&&&&&M8a 9|YxǢ6i<o *簦1-\RH(g_#DDos)!K8J7]rfE]NRZsz*Zr~`hM%A7耿ZPXXZW@dٖw^͚ ],}gE)ZҠkτ^JѲV@ ]Fu(ZZtᅇWiRCqǢZb-Gs2,#jBhR>"h.i`#)k\#@ tBq_QFe4i3¦2D;]e{WZ#..a8z$/1ޡ}@[K{:Zz\ $͹/*8Qnyu꧰_ M"u9a+ߩl}z[Hї~@@ :O /63o|GSۖov'3'L7Xz\.E +',.@G2GF R tmz3G&%8W@lqt uGJn{IW/{%Qu1$K*JuB1hFܸA2&1NH= 0f=ħ!s/CmE=FZ3 +endstream +endobj +37 0 obj +<> +stream +xڝWɎ#7 +H>I6@߂ J嶃 h4Y\#/--?O)5eqJx9WL)鿴<@z6ϑHvKz|@9nHrnYv.$^T()ږ} ,U[]%QvzS5ڍ%UNrBP[X#b [QVR{鰷mzmM +OISЇ˖փWOJ% vwx[g/ߤo(aZKI܆ə㻕Zj)9 E ̅; ^[rY}1oNs8ap\xM+lÀҖJO]MYmJĭ z:'R3dUuxrm(pXIuHSkS,8\8wksy`!mn!1&6q7w0)unՓcQنz't-C̙,I6NZK\dYNxNs.j \&;>oƮbvkM *夿1-2eH[=ۢRYz2PXQT?Pv3 a-jpɘ8rI#kFli $8h|9o3 +/i8$p>U]L/ +[FlPzchVC0f-z"9w+i][.Q} ?1D~4x%=o[i+6=W"Zp־;c+Jxᾔ*0K>'=fl u#pdrl5k'j1~]3͋ i.2Ýk +8++ FRq)O!\-?ۀKQ(6KcANS*踖X-hR#!6~/FCS"׋~$tstCi_؝ȥB]~]Z8-nėMyM%}cLGcّjLYɏ+RwwވpR/Mk(&O˶nqڎkc?~LWϩAGw 7O& +endstream +endobj +64 0 obj +<> +stream +x͒(y + 4MU[:l氷m+rl7 dJ2d**,GP_cxh~2 hE9 x6U؜Z՚@ks_"H!r hSKhr[e/FjۓW\e (n?_*FE +{A[? l%ӣq:ޏ`;]75Ur].ߜ-{ﻱuv٤m?0֎peAQ)kQ^E-r7vJ,ܲ|acZ401QvްApl, +~AQ9"m *"gW- ɔʦ8Ê8If8MkҠ#UW%²vEKAD:iZw%[2>QDӱ䝳0RmoVP9Po 'Q-Gx4߱}| +endstream +endobj +89 0 obj +<> +stream +xZˎ6 +J$, + +̮"]7%-;v;s'sA`eɴyH3?y輋*QZ^/ܬAb +`;Ak^4A5qGi>F||mwkQ6_b]gsEZqܫAQ\aav!NoZ4;?S}M K%^` - ~7Aat9 '^4=b@ o˄%f-J;+SjhL}U.a\=[vc@D:&N;Ao'&۬s sPW@Vi5&* +$F/#2pvg LyF32":C_f^eNCzGCCmo! ΒNH4h$!僟it fr蔁|8x(8ZczIBFν;e95Fޓ,7DH'FUf I)jlG~N#,F Ww|KpйJ/+goiF^ψ(ĝ2!3NO`t1Q~:VGA8}LIK%BzlHW r=1Dcyߴ8TH:J]5mR}~9Hg'+0JQ\p`&?˚@ -@˫&_v^Ŕ2ph\*&"c䚪#e䙣K)$ ,P{mhߍ%"'3C[,O!5ce\&UTt/x~ N`JxGeiK[G0ranV!U,J[]>-t6WqJKdMBmc)p)l\5_I .Z8)x W7`ܘƒ0 n@>ŶyԄ-n؀< +~ZG޵q{q FSnذy0c`wIgv[ +endstream +endobj +104 0 obj +<> +stream +x;0 +"EC[lE$nKm;Z)RH*??A ?ħ@cPl--؀AlRQJKKJ>?}g\ch<k,m,epKcI:(xHI:'VoRF!Uk'k5(),ĕ]Ws79<[G;[6z}r5$, >$_ a.G,,}wN[ip3 &Cn/~?{f,Q:^lec"1MIWX+Vkpv&V{]YhDncvfLtDMChVj +2,Jq3YGt'ʸ20 +& t`%*m ,qF 38kkH(}SŷWӎ8f|"hYip栁=_IȵuDFkČk³wØUXaB)Тc_o0˜n$q a}T]kW'Lќ[cs.Oڄ`5afnw҅~ Y_>n- +endstream +endobj +112 0 obj +<> +stream +xX+7 H0\H` sKo"$Y] E0v)ED]A3@&(5h`k +dK1:`g BNN+&jX6jB|@\̈́ 9z:Y 2R8z6E$ASM)Ds'(}/y JN?SXPvr״D0;Gw!H-%,7s#͖ +le'5hCZ3(#K96 3bW7C^4f21 pcQM _K;R(ZU2?5 s]Lƍ촸WcN7_l_/t'iET!i!iA`qSW_D3h`Xh`vYJYݵX;4)eԈDs`@Or5u|P^B0UNԀA4ɔy2< B-&0۴5;۔\.6z-{JGE7amW +W#A>0׈r2YKzz*o$hAaUG{ƔL1ci͇24'Ŕ2D̤Z; [:mѧla[Kmann?j@A2>Y&k^>#tˈgދUӜ> +stream +xUN91 y|`N$ +:t,taw dYfƃdPrAذ?3$8h/:aI"9h@;Q&$N^m{蔌u\8{G>XG> +stream +xڥZn-7z_+P&^j2YlÙZOU> 9խ??ll).o[[wc/|ĺES/qo]2.7eL1Fj_o=4hs6ܓ3W +oExGa<~3ɷrrT{u&)qgv1: \@oo7.\W?ŧopjZL^Om@+Oj_|mo`Yx}Ӆ$+ ;Bwͅ=>nօFL6u:W̃>fOy㴢Hb ߒ51>s 9 +хUMQR 6kWN95G0Q,)*jf]i6R,A(>O>$R/VJRʙAi+p9}͕Ӣl}HMKg +0CHI̧4" +}9=!<-}ͅyS-܅@W<{S82ȁ2|߻J^+.cQv[FO羫!B+ΪlmLWL}gQ5}1[+̉W|S): Bx)m雯?xFx+9mh ձ<~WzQ@w=pC0 kS핬}={UX켩_HPu%ie*7nݐ] Buzc>METb]VhI_ +S4C쵽IAP8 +&?`慓kR^6 `=eВ; Z hR_.Maz(䗥ݚӽÐ +H2ABTs j˖-@-AٲْWVQ49_ZBhkS.uBD KH蟍{Sg,il+|V+$EnCΦ=xA5%^|ЎEbC-uM V?qC-nݪRϤxU +fHzXDʕ]KJǪh~JoS`E #]8pq}f. +,P6+,#C-f }ΰ !޻|ObδJ?gpi8 6+&-QMaLۅbe?viKэ#02}fs՞ SkE58\ u +LgOQ'2C +31}H38`$G,-r$/=OofL~6IPϜ8hzI3V +JӋ_ +Ta˴c_PAs<]i + kT 0XdjASa^]Nۀibsr"+:Ss;ĕd7n;Re>90KCn-[/J-{fBη1Z%u*_89uA),AV-'aBWw-gˌOfL!}`zO4v%g8BeRQ6ߌ}&F#oe3(A1͝^tm/^5Gg+߁rjkiӬDwG'YҮk٘*ϵiq< C[lצSt>ÂJN,p|hR9V*@4tʱn̈WtNC)/=EԃI0q{l=G]a4CV2ZI6 h]8VDt0{2bUo㎱d7U[o7p+p = K(p[YS{>y^ Pc +h9=cc'0J5O3U]!vjzXqL՞e_z{gW-%<<2%֨͒xCؼ7 w;]+a ȱWZ=YAqIv;g67u׿p h +endstream +endobj +149 0 obj +<> +stream +xڥ[;$ +~ ؁79|EbUDR||/b{SJ~pk|{\\ޜ7kǛ=b.dLh᯷~q} w+:~ʦ}s}ޏ|gc&jf[##qn[p/ۏP"i'SjI2m;0]0߿)+-{h+Qe!ݍ+X68 Gm -wڿ}zxsl4RJ[uE?mQ Fu"&ۏ;o*Jݩ:m$? -5RFZ;}nHmٯiyڴ:h#m)6g̛u73Ͳq=WjG/GGk/>2 q(7۴RkۛOfsHfcRN&VoR3䯃V{m= ,ی(}' eFKꅁ컜y!^T$.L[6}n;TDÜSKp(L~>%*g:2YJ3Ubo=o 'I!)6c 5 QhU_!'^߂qYٗ0"ABTKz}P|wDߓciC*~^NFq b3&da*lYtUpgJ+Jkn &!axsg'.nu;3w}rG 2.`T7aǡ~1ë M|h>1T04-ڱw-Q׀r>tG[-[.~?FRm#*ʜ`|ʱXn6FgHNƳk KٰټJKm19=+y\w?߇Xv8G 1 #00!+>8>LP +뎫F\v^v5|ң +)\%];`(&}C57s]XZTHa?XrQgj$VP#0$cG^7J0X7.Mv +@+g3bWXVF*B^9qs{wq1I%[9kjJb{La᪎X+|ۦ`⎧!N~ϔ%n%Q%9x'pfq +ݞhiJk\J붑ἶMQ`M |fE +YAf O7kj <uq2/)g3U<$N#N餢vl+M?DaB/~ct|cKf$0RIo z.]):$fKo>SԾ'eQڕEGFߦ +;mޗq [@_(bRE&>nmlt_i>U?މ@2~][abuiguC8ڍ)S#Tp/%xtb0v>4P=4e0h^dV"S]Xi'4sUy}<ĕu9gM9aJd[ c+pυ(u&3YĂʀG +~[VrVƷs[y _'ҐR!]O5H'{T꽏́n!OIa3w,ar?< I'y x㨒Da*-WnQ_YgMrmԌ+VMy*Sh[Mv1ϥ=<ŝG_~jK|LRj}KKӾz*GgnK T1U|<!O!-`vX1}7y^ +ӆ" )t0pr*_5fj K8#5S}3gDq~@3:- ^k>~=nL\م"IRwoȌ)Pk1m?nnl贻^'];9 +8cGWY&P=]w5"ɱ]'׶ܫ!I_ y]Ż!2B_^B_C6Nb4z Sn¯\k`b=@g_@^M CyzRtM$|;Kǰ$$ulkO%B"G545a +!8$&gG +nf\PyU{zŎ>-𱦂Ie:.q0kϯDs_6_KOqJk +~˿.?<s=Jom-m-t*bڣOܠxCnr}rMsVKWv1HqcL`Ѓ&Ň_|@p:&9uLث< + +scp8]U$wFǑ|)J*.RӑFU߈.OoLztFGpԉ&<Ĥ*hyn1;cRcyMo>2h^} <DP,>#gt+7GF@|WeL}S"y?@ +endstream +endobj +166 0 obj +<> +stream +x]K$Ƚym`nۇ.KJHE(s]]va%"?>yE_/\b{ʗO+Wvme&ڍ݃-(S mN 6=tk+fn]HFw'[bArMFS"1,Yŀ6d/;w 4/u4.Ķ*Q>ߟX(ϰm}.Mhg?=?Ľl, {NնK^n7;j6cC?c׹9KO/QpU77݁Z!K o\,߿.|fx-n0Li۩ve;M6 C 6ĞS < +P:_ ̿6ؼGz`5H~WN$d Kȑ-N]dKbn灶 +İdS jR9]fmA5 )$W"9ΆW,:0Ds7*gݮ| + nzxQ[ATy!h#G6i0#&I,Ttfx (oN{.%)Dk +P(EBzOV@Dh)Z{XL-gJgOjmWp:Z:URվ=ԄuzT=Yi] fW;<ډףb>^reQ˹g;?q=i9&^rvf_9pho®ꩽ}V qQ( =yDn듏i͞b&rڻ2;<2y[ENɚWT꓁i)iw&"aT=%pf`e# 043(iVJ'9h+(v .Hh9nw3KF+:3cbؙJFo=XXy<ٯNd{%J˝Ql,- ^.; xؙΚ˚neAFTWFl}Bzl(UFB++"m2=ҕ*#bU2x*˝'uIa>e*w-}`er>>,u )NEk{aAL.+bܕ!Ϝ ]O_Pөݟɠ&]cWP媸ΫUU`V) E]DWn}ZEJX(cUfqIS@sܽy= +Gߵ`[Ĩ55RZowd5O=qa7#Z 6OGF^ޔ]Qq{ToY\ %&.Ӊ࿣Fp%&-w֐É>s:٣ 1wor^$d^3q@FM!t5, k):((Bwo[ٛ쭬s|?.|Zr)79'k%d  Lձ1Ɗ>zi=*6f7,`dH,\8Fͬsc@Ρ.]t7pbizퟦ'b>NY,t2A}_}[/ uQ_xQf&YgxVfVesX]ͦ>Wמf8<vDpiRӻ}<4Kg&::p0P<*և?%7]-N<3h4hn?VB +Uܢv?ت{HYk򠷗TJ8O*M/t# k8P{ +\sÙ=OO\suKWFX2VsͰ~|#D^MrK ]8S *=$.Hka iz7؟g~A:wܿnp춸g,LbAqMּL:^Y]_o/n +@=d=b 7z<bڵ`"S?b)ؔK-ۭ.+VP +^d5XёF ~ťZHqh9P!U6BwKfZE0 eۃy7oT1Y{LUGӬX "Ɔ>s5XTU/Z {ӵJN?`9x ȩ}-}vXbF`̤h}FVkr~jSxoV&+C{{KXLvRZp#^5c1 ߭[.7B|_[kk `~?Ȓ*; ~˵Hn4!Iͻ0Rp#iQW ycb⒃pI`n}7BxoX޵d옗ƄgĈB”9Q#Vg2!(f|r[ЊZOB^ rŠEcE嬕/hH:/X`ց;O:? Q(#;CYvaʛo-]+ + 0*n/t5Eݍ(|}#U l=4ouVI3jOè赪2>l)Z)Rƕ\p?L\͹ɺfARy˖˨܂w _Ј^ rр+7)3\[Ǹfpwƅ|8fؠZ{_Tب*A|5yrwM9l:4*@u}W<؈W1~ ߬^ vE܀oJ֓Рz{WD؈M^%$ +&r鞐.jˑP`AMz7LU`{Ax̡`7Kخ[5B qv=0%\"24Z4w'/䀷H;/nPV! +09tZ24P!<V) "E*ĄS1-"'Eգ+`~^x(pbG^7Hp[y6[B5#ǻ DG׼+$j!MR~8#,?s |H( +5r\x#v0n1g`S15촋 T<T:|`z Ѯ#VWbkxrs=BBkl{ylu +2zslƹ0樐Y@p][)IPFBrH`) Y~Rs#sﴏ-XTݤL4 e(D:mXLh__M[Ѕ3~p!8b_cXBv`-eɥP4?P"F>`\JV4 CCcҔ$8wjZ@Ė)@JbYز#EUGgB +5E%K_™:V+/;ww +r0CN[#3H3߇x$IJ>rv@B'HI,嗧5/T~ 06v `;ry^Ѕ3] "R\Y>$q 4"An_;p(!>G:`{VۻpUpH8.Op@Uhԫ;u߇V/fU#:,{1 ]%",|q +v v]_uk(AG9\Áp  +dd&&fd%ppnWfaWyBp5H:̳I HN%vOCZ/Cȇ(5?+T9ׇo@5M}g{*%YvkWJ"EGWO o@E O?k3F a|f$$bȑ)>FGhr3SqVz̔"XX2 M7Ba'] dTr#F(/R4<A!N6gJn ;#}_3?6f+rR*ӧ`[ U?'j53-\qOJ%Wejxj#zT|Q߂0suxFB8tu{'.ŕ eÇdw[Dyl}䉧2h[N,u&˻ ~`f"X"1«[~݃TqJ\q^J_45TGe _"W# ΅*K-\c]=? Q06;#^EW "D S3GJzYZ'4xp6 +7n^\mZ3o?4_j9z5WPy$Aʲh/ByWFFtmHUWA*l/TT%o6RƬsy=CiH-ۨ $F xT',xe>8$3í67юUgQ$#j'~S]om둶bT +V}r C{}ʇ)*EZ9VVWxϬsZ%Rr{rM{֮Wն֍] w{3>&;^$D"5?k:`Ȱ 0 =[lA'wu UH#@NHඛr{~Ak ŧ-ng<|q5.oOבڼk# M"Hc$WJqhh՗y2F\]ZFeTؕ;Hpf_ k))ڭDwF#0+4Mq[Z=p_ٗ97$3wȒ2{2<ȖS lzJd{9^ouQ ƫaݠۘ\C~RBXLX ѹ,!+2˧.$eC ȌF)rl:5vd6;T7ZKֿ6! +g{ٞKI((`CU nPr$bնũ_c:q/Lvcā^|NFH+s!֋Ffbی4V~rS܂ +mc9H59 QӽA#t&Ԡ@c1`遭r]2^cЦ9>[wǽ%t%+^{[bAYde}D  .TiOǭ*l65(k!;]-Yt YYo?{n|S';T3鄙 2߮E8m~#Lٚ%؟zeFëJQ6~zm0A'8p.CM%,p398+{dseHR$V(Оo }D%"4uUgeadMRɦ[! +)W +J]-jh5rKl@+%" "ALFE#kSfg{F@"e;5-n&Tx l-aws1֩縁XXSG1r +ˎ.rcPuj/{En"7d#wĒοd٩Ef15S){>Uww}Id${^ lDܫfWNWk9CV|Gi=ەa Xu nrg¤ >PKi8.{\xaC^Rq Z\$d*Mm/0A +wR1gZ[@ГQ +JrՑL y5EdidOX -,c +ή˂Ơ"D1ž=&DYK'k!ZT.y? +endstream +endobj +169 0 obj +<> +stream +xKo8)> 0 䰶 ^OQ-[8VS"%*ٿTg: +Xgxg^޺?jpn:wTUp#LgY8UW8CT|ⲧNoO3Fx4|x)KHYIz5ַ~u_&Ѫӯ_ޱu +>w_W ~#F懲WS)ŻK~ׯKL){y `N|LؔckM>S8CKA^;B'X(x66JQ fH~Nc챹EFt=g#ء Z~NR$K( R-BB8ȯ%\Bau0SŤ}?L6t +aNh^^)S ss0azi <ĽiOZ8L^$5L1z)n9Kg&u<0*@FQ0Xz?Ѥ/], s8u>'z(T:,PS- +s\o;/t #CԈIq 8QI#^P,K6) ţB% +~|ҳ4|i{xW7mE$tY;Jw"e(@ +b!dZQb;IHP~o{ )smc[jk'QpU7Ymsn[SJj%2kDE;y58|0b--4l2TVWPR3+F +6 +& + umҥ\CL0lo;Z<=N% Fr,a)1ܖ Pv q5ҁYʰsfK3w5 ۻT -T& ,;~V/TS`F-5H O\QrqKӥs݀ 앞wո#{hoo~aߌJ%O;H9ﵽ=\:~'_CY'R,䱍~#W ]iLZ˥Q7 2 s{l7rD'2_EAc\2ozF:2j7Ds=F42\2oHh\##o27 ]2N27+@n2ˇ{d>]2oldn27VU Pάӈ[:;*TPler,Jf>4 UfF@H@\h( Y ;>Emra#}\j #rahoy\h ,+sa#}X. =UF@mF@mF@mF@mоC.lیо̄6nJh?2%40/Im>QJdLL=?EuJ;h %vyզ^kgJ{( ic2%Rh)o(6dvg{ U$Ѿ̐>oX*Uݾm6 ʴyD3]< ms+vM!-"&Qw}]WޫMAu6ڗ{Zڕ{uru7QԮDۋD51rgv%^"Q~G9pG9pG9pG9p'&p~G,fd0o`iݕ/t=Mo2g /s){ +;}[QaǍdžf?}˅r;:Qډep㭇^o?zy`xR-8>g~Nx?co%YG +endstream +endobj +172 0 obj +<> +stream +C + + + + %# , #&')*)-0-(0%()(C + + + +((((((((((((((((((((((((((((((((((((((((((((((((((("B!1AQ"a2qBR#$b3%4Crsc&!1A"2Qa3q ?Pp,%+-!"B$@BEЅAt]!HO{Z\`WxP64g-egtw`WUrIe˓/n,7؎̗a {c_#7$HF-}\7+l–>ED)Rlf\P%2]uIK@7Z*4 xI,}gSt, ,jk6ţTes ;`M)hC\;Y,#ps>f(#mcn.5njԤ??'<]K^,ij$CiiU8k-}KX ⹊ + e):*f1Rkb,V)^4C Ԩi~9LzguE4DyM%\{coi)mP˨KP뼸W!v˔|{XZiMYPm5m4bϨݛ%++vITۭXf97-f4Mg7VJ.MStʬB)wq쐽-AZOH-+$y2=[,ϽUN =ZOC;|5A7&men+ġ6@.>낈n+w~wN}4fDm&TH\\AEuC 2خfItV 'g O]X ꑲ қ 6`8{סcy$dG +BgBT$BP  T!4%BD  TPH$"JP"躣j4m3FƋ璧ko{XV(5}] q7qz+H>:F,;q]uwPҶF-ml/1R w ͸erhJC T*eԩ|d`%9-(6O9_66́Qi}S??.>v-sd0ϐrl*쐺[ٺS70 >tG7x48]m(x6\M=cC#oAVkQv5.ivN5R7yŇRlι%$nM-[LuVhYb0>AAYV"`k}"FSH@o r1jik呟ZzHZ ǣ1I⅗{H ע^vMm]H)y*Y\^& .usǛY-|,I_&' +TFr:x] l?*Ri?+w6=ʍ#-,o8 &H5Jܽgrpa40?wgB4cר۟AH~MSD!/kVn^]J lxd-MyTŒt \G)F3r,Up㼗I%T o?h.M>'V!WRism"F֎nwvFPmLn{I +^ 8->%1-_IzTz]^UВ7_)Lcq`>!jT;n9j<|V +n|+xpj. s`ssH _O-g&!RJ9BD!P莨(@$J  P BPCUPh,0W}xMfzZ'fu+t˴J׫'í# ^ONŪfm4Y{r~<~E,\H=c-clXËXT/~m~.!O`}$[M8ic;QlSvEl!Bf +/)'%Vݺ^}_"iÜ ;kM 0(+5̛yiZ<*qG47TYMe#\GΨ$\_lo&"uA Fy}.tLe?%wX>cak;Ս:6Fp ?%VLCWOaek&cl2? m=$-6|RWN,` QHsi=$џ,} ~Kb.\8h^w +Vˏ{K ]!.{.=ϲ@Qp!GZꚳ\?=V8:i?pO_@6O "WX )M 짉#X.+>s[8cnFc,:ԅFvqZT2ntN.U\ekd$e;p0>)dMg,f^dTGQ %|oknR}xs u3vqVM$Ѹ\.gƤJ!i + z$@!@!@$J!@!@!4B,YD_37 +Iɾ$yk&夋LX1Mjpɟ+w$2OS$msD}o0 `w{f=qo>ޙX\ͤt屟] )cִ<_Ufh#F+es# [X%] y2@LyiML>줿eM]OLo 31hJ͢0456=V0[ww t>\Ӄ7$+T P9+54x][6gjL)h\r U4 |m?DYl, KӇy%m%3!qvEy3=X]cAI!whuU^"˗[ҹ숑柑*u{+3ED" +v$^݀MҨ'-r7TFEy&_'Ț6UdkhSbJSTsc^Q}7ʡSJ:]N^ Ґaϕs}-Füyf'`)uC̒SmjDehێbߙK}Jˁm[쬶&EN}S3E7O&p7q;,`K;G - vuRT=-T많6ѣ=SoFkmQd6 a!lsG%p!][mǬ_nsMߺk nEdXw&}m$p06Jw5;_tNy.aqP՗9gO]}&DH矪Ժ팦E^4]X]R'T@!!! $Kd#(@!@!TB 4{`p +a/-"Q򷉩&Q[|XDP]l*]``qc~j.o%IpT5˻sw9Q8) opfͬpp}迪^=YN{@SC]{%g*OKMG~^<$`1-:`arF_?K;X[ͥ Ƙ,t= f}ֻ.AǛq\lӞm5ciÀV>DXHVhboe+hC,@m|X3FA'w(9.R "9'-y'O{6S 4"ˮ)??E|ϥZ@VM3spl0Pm-9袗N$M x}.d8, 3iop0PtYz_ qk"It  *'T!R RJ%T" +p|_G/ui Ea_n^%}fO?/ut3uuil_+:Yڒ_-#Ϥ_-2'/tc;By0 C@ t^K88x o{.1Yň0>mG+[ F!ah + iZz-b˔SfM .wUX.,^woq4ٶr;6>I>^:)kK+S`^nlJICn9ni%@!)7}2|ݸGĖ:mDz0'e]#X\6YiA_<}kjm[HA來`.J* +BB"*D)BR%H +_D2O3Bn%wETIjSNW9WjSpPm]^F-1%*Ǐ[E^@4M-ԫyn*ҁDòrP@7ML8]60Zdp ;p>9Yceo]6`4#ۗ[ƂZ;.y;4cmX7Rhkz.N`Y*F< t6MSTX  @2S"JR,#=z% ]Che3:& !5K) Q cz'9ڂ,[`pgD+/jQU\ԛTM A 58nao[sQμX,h54.[  'vƼtvFdp@WQGe!!_r "n%i+sK﹣i_:Mm>'ؕ'Ozuۇ/:! J*A@BB@B(BHJ*9P|S%W7 +x#ýzC\yծh{4Z`Ӊ/Vq#|Z6DϸuQ֩Zv &i*ƏDC*XZY'zϰ@vv~+5D;J鴖5heӴtZKZ$mu'|uF/Z nO+,:€qurŮQ +UxU#:T!hvA7OnN Rst9P1RyCf2m߲i6MAvr0XejMK.А{-v^zT-ʜ$sZ:ܪTWzU=&67*@ʔJfNCRZ@S!G? ++!eBv:]' xvϱ]1YF4~:#Id4Ln+9EfyFey`9-kBУ`%e4P/8}!z-=9~ ˜WIDI#oIV$h<'|]3^Fp="gH?`rn uOavJ2T.MDӑq@~*ܧD ی'7戜;o9NTKvḰJ?D-쐋qh9HDM6MstNIM,otq!ɤeD3?TT`v\zgH vZF CrsHN_ݮe;/g;p>WŢR0#x6~ dz\A5E# cF >N{&BNB! +BB"T )BS'T!TB M6Hi(6.p %d ٛqcZr}2o.EܛquB8,Z=C$-=;hsI=]tx#"-6 efR,ҌvYu 6iU7ݿU?T=T[m~oŠu='059($䧴Qrn&d $E)*-ɵ}7?iXqԯAYrw\gz8/Ns{sE+c/$gmE$ h:~mv-v@\n9Ubp8CfM#KpXŖmrMϹ[zL%S#]L48e]4 ]hʈ43]`S7 Î,JI'4u*V%ꦸ=HuF~IJ-őd[Le5Sdpg^>$7@fNMtlݿ48 N9IX%rnK.T\& L& +)8㺉Š<(k )9E@:1TʉAjvi[m +nz Qθr\*d0?좬#?Tb6[=N3Yi uMW}yìn׏WeCs~J*PH qH"H"P*B}k>2tS6n.WN#oM!Ӌ ˖sۊ217H)JqX`Мǔ~_=*`$\ЇT~y hM Fpuu贛@WE viqE-XNɍ#p09Oa# 6_>Zk(89YՒadR|sm}7EuѼ܋D?cE/OLCHtuI۪DO?RU+q%AKI[ +j͒,x:#gC89;eM&xpe ?td88N/-"({$G{ %tcr"6)^x &X:lI2^cY¤ &Yqp*1&PFE6v/VucH\l6@FJn\%L'.:Y5:&U)j| #}U +\{# 9NwU5Lsdqo(a$@9!\VUH۱['V9*r#`/A\.rBB9PBB !*DH@!/TBb[[q5մ1 b5#]qt|^˗~xTsekS=d~٥:FuR_Rn?LoYk\G\*Za\ͻ-MJ^~a;ڨ'/n:e<](Ų69@W1reNkA, h9cKwV +.>ݦUVYjqsrU{Hpiʌ8 e#$X(Tp6i v I -!*?!eE9BPLp6c6*]9ܕPURj&LL5A:\γwܬ3A)f8Є&+uJ :=+tF~kxsEOK;O~OŎiMzvn ~Hpr >tqSM7 I us9sPmXnzj1Īu~xʝ2k-R, +>߲lRnud; UD߯.`@uu p%XTHEaVZ>!xܬI)=' uh?&`&6[kQkY;vyJ53cr'a spBBji-GE3@^&wUGW#ӨS.;Zm]^<|/D!!!R rBJ`j3obM{cDT۰B-zސ?.>^2(\dwp#Msi isMteޜT- WvXo` wBjd$t囎&CcnniSkP"B[\ l6˵y$RB+7EG˜ěvXu rہbY!Vs \Xͮ)KN g=c4诐O7qVkဥv+-iD0Mn@̜qچVTb{bUf6-Qe1I6X!!ǜw \ 6_K7ާxkIAɲqoCN\㟐]y;v=otW/CuRBBB )@*D 􊦁2kݶ+ܥ`7<_cF8e +V]~Hvج{XWOw-]yQ=p zARdecxkp+ϞܞcwZܧi1'`qe3tN4 KӆS[vHo0I\0[ VC n B3`G?RE$خuD`\V~Pc>[w8F.K+fcSmHey!y~Ct. Q^pxZ`hu}Եs<.3dUt+QS}➣lov+t@4agz'H@r͗TzZk*vaE6/sAk+өhXM9orU6']ǏQY58mjdqT`Zjc)kI2;naH#츽^≲0,ݽxߐO iZݧn2Bcޣ>slR ۢ}4c~H)y?Pi] uY/!.u:Up4GPޜe]K\KiIp-m.m#e˾;PC@m/&sL+f#sOϢ*CQXU;q`%n֐z&:B6%M땮(iotQ) |.csn6Qd,-XiiIZ~cdkÒt1s#lcs?y k6OTu++mFG +Sh .67 c_g?|s?]\ ٭oˮ+5|oP. BBHR! {$@!AB ^cO+VlH>}uqhEK00#9_7ˤs&VO}ĕ6#ZkJ=^ˍ9L + "LP'UHӨ `hY KδOFM ͮT4:"eSJhleF.WXMd Rn{ g +VB?H#$X1Ԟ_>a `<\dYH68tcbœ"`%2FI{vU4kMk -:H&qv42n2`- ni$o'ꬍ1*yHlsIlٽոc"Zv,փH ESqvS߽9*U֤Gy略LۀTsXct~R +"v ++=XѺ`,V7JHo`I 72'wItip6s,PT1,p+Lз i!X-@‚' +F4Zo親n3)wJ#sa#Pڌn9McF#vY|n) =DAhi5w5G(釷.OK>.{:g78I^h R1rNo{tzIpϱ fāXUx1|dt+ c u}N???.rBB +B*DBP *!{4p|C>2G?c9lu9^mKou5ћ Xy!s%GU~ 3D08飈F.FW95z[˸|}1.374, $shZ22\:Ǘ$Rzs7xm}{tLIZû FHgä<4o*F4u;A䐍mf`t˨ݾ1q6U=#LnnE8xbFў?E0mpns" PHB<ײCvWd9jp-rhF/k(k9Z0m j`i+BێFVZL +Fx%%CCH9Rg8&]<^0  ߜSG겮Mo~mqS-/cakpԤ7lrB`}W\m]h6&HQ?T  +̛GDƍDGуV3T%h褆P-w[ۖsD m.G]A<[ej4sxz'+ē}݄n+jz2@m`m| x~K-w^f&3Oo?+Ki +3Xn!U!@!@$J)PR%B@T MsCdƒuX]EJ?ut ᛅڔQ4;rczW/(Ĩ +ͽoupT0c*H1黖2 eW> $`rˍƨsS]T/t { +Yr⥉RGgEJ\6h{)#)vTeid]agd,,s,n?T_inA1#cbp9zvU}ŗɽONTTn(7#}A$<rTi.DeaW\8D#n[` @7ʬlq&.<ӎQ_ {YԐ9Wsy !q'$&$ )(O-.J9ɰL۔rmoFQQ4m)m|D5h#mpJ7ǺK1`C:61m~,@-~xNu wS.|w([_5\1 ~]Ui)o˧})|#[)hcFr!!!yH(B:T!JJHr'Gf3g|9SM,F2T>[g0B{|_ClV*!:&^m=]ݱ%܌ iNBY@)1bɻ +kT9򲱵nBkrlJݎcNўT6jw{)ZA>sz"vhJU)ee+\/{Pkdn3S^M{ $ h? 6y^k)Ԅ\K$3V`8P@ZM)e6B uԠr.6TYϵkQ+f³C2.W3;Skdn%d^fi+~29D[%2LOߋX&# +ɿtsm8K#AÞBI1Ҟ\-:ZprMȦ6$x6=]% |cZ `{R:(=U,߼6ww[zp񛯗|BBBBD +*D +*"B9\tI~r]B,gӯ%<ǺGMK}$~bR}r,Lp 2yncB:efWf`U- kQ{ʚO1:9r-Ytb˾O7u_ +F&;sߕ♼Yʕ$IsŔllMRo6i>HP9Ǻc:,ʛmmjBWV,wMs]U>OrBЍѕ"ۥpߎ3qPT1asdq|Iqc._ɔե%"BT!!!B!J ^B@FɣtrcH\H<WR8{tϏ:>՝&ݑ- +mgtɤcÎ7n+9\!rk!p4w^Iyָ&sTBBH\\+#v&JgOk6Yvl dxhraI\vX)kA{?57'%gjpi| hTV2#wT=W4k$mIi*+~Vs@j'5i:McI; )U"Id׸š6[%|-.eLkU6)jcmHCTqU6LswEVmSc}T6 \I9Npc*[{.K)CA..=_ |,͚K/JNNHTT!*B:!*D. TGP!Bꂂ.!W#ߣ2pz¼`[#Я?4{>5$@qQr88l^JbPlodpT:@Ybȉŕzڏ- ,[|ci7g~krO. ;Vt巻|D,m}q3gf2hЩH9f!p,ZǒRSDEd[~cqC\XCFM쮼jgnorTVlkͺb8 *~{,7-M7.\qH*h{vcYlmk9%ePE܎*Rn ==dhU6VN7)83'8Ep.2Β78\q::"洀M(dwUj$빸[Msq9ĆU esr`쫸t9Zy& n3N^{ꊨc?U4ϷW=*D/KTT!"* %HR%HBJDB>HB"TPR!*BT#w0Yy. U1W9y鼭j{cy>4o|]lyi$TŰu1R٧ }ZߪR&UE$pA+Z,-KUt[*$"Å%e7Pִm&6:)[ >fjJR#+1Z5;uf&'^M<7 #XZ1q;Z斷5bmY:\~i Cn)#ݍ!H5~-)nyUJgXob[73vXH@wU]C@ŽmH1 +\lGYgW KUU8#s8U =@}CpF󚿴']MZߪC:3B=,!Ĉ$|]QsȲF\! p{wZF7aaTiD9jߚo=1uдT*} {a ~ucWAO7QzD !Ӽ|RN}}HJ!JPBE@P)HR2[ovP4ּ\&7YǛnV"p'<N/)#sQԝTE; q:-{&qTQ䕮a#wX [Ta0l{,."3oe `nT]PM)ejzLUQ;sqxU^jܐ?UPf[<.gcc2kMэp(i5 =ByK#Khcu{(;MrÔ:m+@jZXË_X#s /K̴vs ÍE%O +x9\'hUS:OP$pM3a4`utE'#ԍ{xʗF{* *B5i*vhe-!uR52\gwV#Z02/Qg ",Vhp+_B:*r@9T+9f WWEc.9U3| em&~~,<$L cZR$JϖD@%H u@ !!!"BBH"BD! 'D.ktT5ҪGag/U?Vvh +{Ш)l:Us]p.7&ǏG  ZXu4z{"/vN + Xcr *TS]fF/")iIںJ',ZŜ:U59*HX? M_qIWCRTܐ*յkݕ,RwۿŔbDz$Q.2?yC]n3Yy?[GV) wabk0é5r';)B0/j8`g6:tԲu#;kpB  eu?E#"o#!Mak](7E퀹V:׷57}]2 +P 9RUHDdweIp rʶ4M=c#nd=J8ƀ` 5}Z2/wrܞwuq QTR!!   %HP :PBB + +7PTeCZ7RN;Kq_U9UvqGʬbpm-@ aF:4 }BJqKʐIK4ҩcH`ǒnMԈܬcqMA2Wqe+\7\dŖwU,k =$$*&ZJ74tbj SX +`^؁lFb,{TW{e71sGչ f.&K`_#g:FTZ2awXns(ƆmpMS$tCqok$l-7=Xj}B{I7Q.{_0'^ɑGknU`X m +h5w N;(Dl|Mo dcV}zr|)L^ɞ1H+ + +]. .\BrF|!*  DP"!"H R$(! +BB('BBP p=A )ll.q]Zک[8Q*zM䀾^~oBt Ұ#s~`A,{R]5fٺukekZ #S:_>1YR@p7 +߾ܯ],Ff[)e{ +e 8=HXM$_nN=] !-q9S9:)PuŇ@Ӄ{[J4pThm$&4ǞѻT`ѽﻘNTmk6M=L԰ASn)//)i([l֙zpiȽ-!kcX} r`xʖdd{Md߅ O,E a[u݀q84r#ٳuMY s8su"Is=$B=PD#c@[~&eυZ:njʸֲ$o*/*! +B*D +  BBB @!#*DB +󵤞)u좄q.[LAs`p}x&=FX'l2m*^ú-F-s~i4)i}?DHSPedÕjL_]+r8eYtl(*DzHp{n\YcT.Cy!6hAoKI{^õx\?lXeiA! -kl:ߕƮFT[YcJwdϹ%),aP5ثO+c6qyZA 2]aDة\u9s]|S9iqǺU#yi6F\U7/YH\RAi ,ѰrUJI`V6#.3{JΡN;ʤyWtgAxhz8 ( +}7'T!!@%H!#BBBBB +E@P     jC#Zi`Um +Oi}%`|Y}ogMl8:Û) /0`'ܑ;ȵl&'uFI7pIRh$,.;S0 6q<%׼9&>Z}D37(Źγ\H/%16R`> #^cXpq~/]6αx\c!u`ߑϦy{ZB~r/y8M}+xNm"cͭeCk7a6 {& 'ud߄MʲAh667A>o6,ѻoO\F$?Se_r _*ΣnZz_*VhdLa.?+#7#<ŃKky`pFƋ^ rSZjZaLc 7NkE!XvOc@Ax6&' @u +B&in%<:`oAI3oeۋ/xQ@}9,_-uC3h7-v~73t7KexcTH H콇B#"hu5;hm2ځ {d8rjDz^N< nQEPHPBB +BB,PP)ƒ +endstream +endobj +177 0 obj +<> +stream +xڕX#7>Aa'3Xj(ځuxZLX|U껲U٩.U? c*>tVm (~W}U?/٬%H'z1{`.06{u油_{bpTy6^p]f\YۺbMD9mp. V.p` +2]-- +@NB(7Z%șT%iP- IC+fpi֡_z7Q;IY4fBp_Dw\%y! +sirfO7PnA Fǣ|LF>4YRXyǶC2ϊL(G{diϛ#&B'*e۴f%w5:Nvd鄻H KPB>aKH1$yLY6 0,kSvNː$K9ԃ0|~:lϬ;aQ5NHo=:+3XH+&KK lHG铞bԯ=<t6g<51s1VIF:$5Rɨ;2aAf48 \OZaskuڨ|@K\\|5̅z{no.Q{ {RM"c4 rµ8Iلw 6ՙMtnMgae?jUZYZF1b}֎#XR!@FC^S%QFrk>{;ta@瑢پY+k/U5f:atAִ:]pIɾSP$Üsg9NA7:8r#ˡwVx  IilBʌnRkhi\eU/M2ܰIzwXL u~oϖ$/qu @sq@lզM(0B}hLZ0kќ4y*M73]h=5\ܭ%3)lԲDzݮ֩f2WpE:u:ѢЌZ>^l0X)lIfCLhS̸,g5ڞhjxƥ}Py &*)`m6X0եav["q139L|凃 +endstream +endobj +192 0 obj +<> +stream +x]K$Hߺa$M/ Xt00::lO+X6dſ}#f&[OweaU$1\~X"Z,?/\- `58.LJ/߼0A7}>RJ|'ORj_񊾤KWâWj̲Z%8%V%@T+*p!O+JK\7ڧXiHE%\w#tWN:avNm5غͿS%s_/df4\k'I{N2uE 6CnrХ%5u A[AKP U+I5HE&)[-`~^w84ytEP^ j@"vHL L(\dˇm^jF WB:3}DPB]~e<ҡL]Py*cZ:fᬰHd٬lZ'4~B!^xepI)7?v0T]~4^TqQ +ungNp Q2AIfVpZl4a>CAuhLd +XE1]7،sRHEVZbu^v>%5]f۽cX +7.,#,&nE-oŦުJSR)0$Se[Ԙh;s?hd}ĕҞaBW.˳A`+W + D:XNo?BoN.T:"9-!/'*[X1ۄ'M^3mkz[w]-֐R tWHE9w&7qkIaB,K? xoQiW.rk)XE Vtԁ5Y_r^ե5Rh _]uJγ$'8.A~h{ Lo{71O8FJV5].^&.={I/> :d]( q6_7nFtg0lHo"@-F4ƔbRT7n-CI"7$*"u:~a亞ݬM^[7npbvۜvl0MGм|:^#"?q5Zg5XrMOIj4ml:s_\#W=Q 愎%pEN3TxJ?TKUuӬdt'a~#>6]]۾$ + o!]&3A@Oq{͜HA-m"u<{ig&qc9UL&sȜiѵtW 93@"SY0N99ӇG2#'Z9,ċqOGCdCkE %@oPtudXAUjhnLfo yDNnW$}.G+*{~Y)Ȍ/$4j!C-6#RK(GX́Ȗ%OMVlH@xiExx&>'k>|(s|ȧTH Ir?#˝ s %BQ +vk{4e+KW,ڙ-Ǵ8|W4r8;ZBUfP1Qz.i< PN7Ap<hr2  ZQQKyՋ]' h;b9n²:I3挕y.CA`ch J5Ǥu:oO*`mZ6{ sɦ#+,#TQJI7)vmء48xW?CWE^nt^_푦 h g#{84a I2T$U}oCY +endstream +endobj +200 0 obj +<> +stream +x[͏d7WtrɤHpX)H,Hy(,povnMr}ʮS;ja]!R"Z 7(ORG)5H x ~[µSh-pL[ +<:](~2k\ʻ/A:ÚQB^k{{7 uLrKEQhoPG{?(KcϧrJr|{_hG&S 6зSVO'*?Sǰ1x˄ocm԰,kq0fǏ1A݇-͏~mo9S|3γoIdσs|<罻$rgNNExv{o2nJ8 ]ӷc6l4p]=V+at]KГDˑ|񛧷 U +)"CsЅ1Dr~K-D $90zh%8a V¹2yъeu 7\)<]oѲK!TW<| <0I=W<?zKW,:XV5[3oMޚ'Se,)"qI!vY]dj-f`q~ teQzIfbGa4 bIqT*T*d +RؙPIYyTJ!VC <(&r|6 %3wں\ )^dml$,bu.+2;[n嘒>qxzBWbg%*æģ&0eV(b41'.IZi24:UP4a)z7 GD42\+aB5wv@_"[X#2¢vlF)*6Qp& e`-:GE#Z49osvL".%<6M!` +jz7hrp)rlaJh;~C܂O9ИxQP=x[٤[[ƬnnWY~ftZ[!5X!Wq'SN +Wnݙ>Ɯ:*oógg K=Jj ,nΨb8*6JlSlS~ eR(C³43Vb.FߏAA Av6*u 8}]d_X*p0\ *HTv +e?~2B ͪ@q3p|U&|R~#9jNQm%L bg+V'Fz/tGP՛6s"> +a}?]%j,3t/ [+n1aƃۭ +; +>0TDx` up`0cN%5=o~qTFqJR$ݫ_K "(7G2XR J#zR3ӄ^\2mCt.fcͭPͤ?AODџ ̠"x ^E񢔝0^l? 2aͷ|v7g7^ͽ~5 wV6}ADʃ+|M7icHTϼS:>]˗~%LMh,MׁZ/JMt]/eY;BXFtWY*+6V5kt%\NuçbEdX Fױ* TA \T[Hrh5Q3^W|̍+5A,y*tL=NKQ0M}UI ';>$@ +?b%ULj~[X[NrHdɓesѐUOfb +3Z3wDBOhuF*5bRUsݷb,`YϠKr%}{EMylj$|)IE*vHV,: +>7rKD[~p +;1@}6 Z +Ru;c5c%׻2?Q?6w DF5];FC#B:m?q17:Y'\:[p)80y΅>[-oI=?}+pP-͔}pC0D0l㴊/eRu|91Dq.+UMH­6)m)jzǫjX)66B9ح +2.!eo:\!m֕?y +f"h+6~";1P/S__ f}E?wbhj&&(2~afaFewiB Dn40ﴉ1үI L/՛8>ysYş ] fL;+_/!w(ѝËjg֋n|r%̴4GA/ +"J4%"-7Pc)G7Љ@q%C ۢa9_SG*lB?TCM6f*CDSlEIG5pVyi0H ffg+ԮGOU7jr} +endstream +endobj +208 0 obj +<> +stream +x[KW4t= MxC p(ώd0(~}d7Y,<$XϯA S(B~=| Jh- /xJ%E5>(RjO#UOz׍V +b>I餔YJ";?. d4t02Դ-]yJS"Jļ|8;5O/*aCCy|2pJ,˴Bcõ/4#g@MYþ#GRHk4pt`ȓ+yen^+Y`GNƈ!rl[ie1Je%vR#׍)) +-)[7#Ij#[/[6SF0[632'mKc˷\A$y*P,v:I+H +[2MdEA9oJΖ+S +gW9c/Ndxܺ EPtBrJ+i<`FE+B|]2;. )t7!UIc=b)'6 3O`0L~>|! sbmlP2c7̈́ MRpf; '+zU{eSB8N4W-)ݒְH5:T2q:w3h, 2GѨ=4=R,?ept5&3u `\؟j9x j].FKY$ڰZ+. icŨК> wxdYiiT13E k*?2!3#jR#4'[-Pj)3{4ss.0ڲ啙U"?2ZG^'N0XNy.nFTJHcQq_!MkU&I&e ~.frTJɔ7isC,uXi } $j (ct trjdĬ#e\wf#dq5 +h'0V 4tBmʞ0^P IR 43x=­m\'D3nL[jzyI{3bkp"HhX@RouŜ0dLM2sٲ2,Yؤ&D /gkA5j7WOĢDamZ*fltrSꁟ2u~t,+Mg_4aS p/! Vꁊz f-@NlBŃBKI}hxɎŠ3tUuE a>g1wO^k͊ݱ + rܯ1[R'U}ONeO^J(9)OkܩI.Dq8E%=[5J澛ue51 :V/y+Dh!sC۬ =ӤiHyLYFi "SEN +2nAD=ɘ*E `N0Z<[zТ08Q.Z0X01LjK=y +!]q +7h)) b:b7nAMto(/ +Rf׿µ”1*uBB0}!D%|s +c~S*lK&@[JQXT3=Bk{ J{D+ ڡYX'ɷ~n8_I'&b\:DÝxw[$.}h3(bV#z|CtHԶNS?M:E& xB|~ BL*ᴝs#Tm!tIV6VƮw +`vtꜫ}r_]7غO+nWF Iu Ioj$#@tTK [AG7Ut[ߖ>cn$/w ½;:Y,\1Ѡãm{|u]K[ EwUv|LqMNvn>u~b6{$S۩_ Lӣn`D>^)x~oׯ # r# \Ym/@a-Aū6-Ct8W ݃ +HkOPܭ)#_?u0F,KҎBeEyTXiQcd߂t2C?eۅtT|Any*yBsczqv*_gNUqѓ9XWmؙI > +stream +xۊ=_DJթ{Cy!D@wWƐX֋=眺TOhW0ܫHO-qyntR"Z >ό?_  |$}1.€#exT4 ibDԎ<_ +xR~VS.{nn5%qNPWS DZ/n3/i 9!44/ 5:QXB 59鐫`~_6HK4Ti(b< n!0 +glF/𠺍~fv}򤼯9,,Lo)L6r#SCX!OѸ³|GbA' "HbAqɭT@%@ qK+*` +Yd^Ii?)twOp/'KCu (%.ܝqθxԐkei+]>q"iMFQ,OhVJ紝wW# +' wfCeVV͕sF{D#$>v5 d, jbr:W wⒿ%|8@Iۮ]䣓=dB(g$Ù/^'e"I NE:d݂q21rI(28ɀ(t(Z9T~,EԺZ]į{$6ۢnLثw^Z q![D+KI+?ujJ}Fdj~H')C9$F)!*$dQܞI,JA|>v4pIGQRA$;6(r ɖԵUw#箊TۂQ:R";d8@6wFkR cK42^ӗW"}i?\a6\4Q#su( +(&~lh&Y$.6qĢI&s)xv̓3 +{dB3 X<1D͓ovx")&-C9=:/j]{i$FD24Bn/uI@{i.& 0 +~e!!Un\qƽreHjWT)hFcv/>Axd/}+9;`VuqvO +ahc)oK/J ݓVZV6V%An>p iZJ0HbEj1d(q42ۍM'c)MHM9Snݦ^t3>ʢk ;O)& mJ&&F8X]ܴ:`4F! +epWO%iS\{ep +-o +3uUp=_]Ni:p-OI`&"v,L[j;A/V]w1 mvG5z@vJTs O` ĠN&I+6:P{៿Rdu%.v +5KU3қ{M︈vMFz>"# 3)"ŽF&!(?x4Z)ʂ 9UuCQUoG rS J1ͯs JRѱȇ6Tٳ4så6)]cs4:H4/r},Mq1Utb>ݝU-P6 +V]Vs-; ]EE['Эb-*^Y4YxE&().}|pe|1PM;V蘽s燎.& +M]@kc w+$Tom4px- =|h|&@M'DzuUyF#|6y]a?jrW5*^&UgNe E +`F`$4kUl92q픏yiбjarڛe"vk{P{xhk꫅qXa\ (i\)G>n2(sIV:Ng+$kj"om18p?@5*[V^2f0|]7KfvM?@5#wQ gpHaGݳ^UFV*eC]n(xؚWšĕ2E:Q"F܎ NǏS7Ϭ^D}'FkS,,O/>8_RP^4=u%3VnɨҢHPK#euZS ̊QXY!͕) +M18D 5|Ƕ 9YBOsLXƔ[ +Jjjx)P))$qjD6#W8D>+elȖpV-(I|qdgp<"ˑ~+47t +'#<БuN$(u\}Ɲ&_#ѥQT~d~Qμ\e6.bZ)m2d$r|ʸ~K& UL/>繯 q2Ko2ʬ avbYTYSEφsef.xWwQ1ۅ[/Qۗ"՟gܧΏ$*hmM)eA{qWJ-Dž]s٫Y U -,ڼ5'8+~%^/bo4iCnn{>Cq%$2־y}SsP7Zn>4^ҳfZ8idcmbd޳ʯpԧ FL=άTuR;"x}ɖʖ\VLj/w + @*,໲;-y׍ "ǂ"!n;TZ?OۚC|Ål_87aA۝ӧZՇ٭TA>7VcCMo0x[SOv|Qy={}HW96-'VdݏCTWtKtJ #]E=0_b"5CѾ奏v=P]+ װ>w@;,V1 +ШSWhdLOXaMg@M +43j#ax#QF#a=W~{" ?XYws6 %2[)-{G;E0l1qÄx IIɜD-={Jl(PژlQRpt) c q²%t*T+s6QopGx{_']f$j=2}=k\ѝ؛ ef)whyּ}Ky쒀2ڄ=XH>ܾeWfW +endstream +endobj +225 0 obj +<> +stream +x[Ko6W9,K5顷r{1P K^;CRZQ&%f0V9}T'Gu:g}߽vJ` t V]1lV4N*BimpAGڿ{0 @l2ueizGke*W#lEO%GTTYT +hQ/.Z:G$0L2bK>jB9EBt c|)>}wlx"Su[+&k*|keHT7BM}B$S F𡾅azU+ʚ0& ک)=WՉ)f%B3Z`=0D%vY;У\<, ta!:Y? Aƅ& Y@N୔.,y+$x$DP%GD$k9[ НF ``k.PiSj+s-NPN$E@ y8OZ BI # Exa$JhP#v5 b\` +4\4a]2ijD,gs@VFO.],"z92WczhuSeIi"f:!bĬ=H1rgPsAW\@xA )MֿM@SPH?Hein"رDR1N/{Z G~^טc =3fC4>=4M^5߰g3LM%[~ijĨƒ&ӆDz7ƕ޴MK} S=Z` q&$$ FR 'q*eCW9C?K8>]~$+λ5l(i0h chVN\TRDx'Wd2~+(b]l{. 7+IIck&W`ɴ&*^mk;vSB5c%03dNMFZ8})'=Bvk K"(ڱgi jHx }"bKɟ70tمfUo7dv5y**P]Q^2:ҙaGNu2lӊ|q;rf@-j'bk VR<& H9wH2`_bO{eeFjv2cTKԐp +6Ee xb2ir{8+LK[dFw=vQ bmA0NJ!iTv_%|.1FMFJrv`qDmD<b.npjDZ6%ĩ^"Mﬢ㷬l A:I]I#SUFRHÞ-[jp*^\0?F8.js{궺=+cDިaSuǪ&2l=90}qhsLڎryFD^8 +^YU&R<8Mq'((7%CdfC Q&!~,tNI +$Mfۚ(17N-uC̿uc+D┒@+,d<=F5/,o38$1)Di;KZ&e"';ӳ>ݎ*h3!5mMXȹ3jEڶ/!ЪYv>@uqz!19`3ȵԶR&}56WFDŽ +zKn:8ܞ񢷝f;[mю ++cG^ Rr`ً'(<$k(L I!*y ҘuaѴbߋrEFp/!!qhQMqҍvp bХ4<*O,/Uۣ!@m<9d>뇽?],v +endstream +endobj +235 0 obj +<> +stream +x\Ɏ+ +: at*3rh–! `:> `/rʬZfᘂ"2=}?I⟚G0LUaC5/B؈YMT]\h4Bݖ\'1D7i0WoZ邥)`]jh4ap8'lףa͛B. 4\ 7yě#D\ލH(IcSl [$|H'%y$:!?HUʣ'&3.˚?, ]Es\AYdG~&7󼻻"S'(c08'(zMޙPDd7R!@RݿD1? `XQaZ2ЎbdWXnx5ߑ[`^x43Tι.M`5Ž_YBc%8/*m|hd-p` ;keǑ*#"lԾX. +u޵+ ؐ9JB"r9YENgE-ĜۃR 6z&0 ޾ls 5~CɫJA3t#Y6WCQ{c;#ίL݆ +t-dHujX~o R +8ezehuZFb%#8VE L›|ܙNf v*x}!«&o:FBhS"0.-soVyP ] Ur?UXAGŧ'\xͰqNK@Yi#':iDg R;*a왧Wb 6"Ȕr/GU.qڏ='ںfoOu`IpƎp$0::և0d(^4sCzR7IvBx`J4, +3 EY>T9fQ>~Ѩ{z+4TpΞW}:1.E8oV bs'~b?>]6as[Q@`b*ѯwmY֖nISmvsXܖJ1gTN=Y969oεn +WY k n=='B{QR>acp8 g)k|jmo"3~ + +xayu06 [^./"wS]k}Lڟ᚟i1Yot;%\G=]k?G*AZ^iy P.e%?fn9ُ^UZ(U\Z5LI\nQ~e&P ]JDߍS1ļ{[Γ1/3cJKh,o*AA>mUsCx@swxط3y9q;6ahꙩb5NCtW&y}EK!3}r%.ugNY[8krTnz!wC~B+z'u ɎJWuvFF5qU) +[F>FƒbuY•jl{ǯ`*}ZV{pyu1" `OSSk5:4w;8)7EBj@q99,KsdvwUOLMx@5xe\ ĕ;3%~N̩/nyГ5 ziHHU6j!na;"Pn\66u۔i(yn:LH^iJ,[c{՛{ω}h 7ާ"[: }}I{$#E-H2:ܲ>‹ȳrцzG}nOsnϓrBP]_U\ m Ȗqy/ v2V꺦lVy>[>W +sF8vU25Tspmy;N p~@n ™=Rk-d}O.{Vmfû ƱSJO@~Tsn`9&}a #yzfjqHM OE> +stream +x\˒dq+* E_@#k"tzayo9UݣH +q]էLu/ ɥ٘s/kQ\?^iXir|E߼]~e*(oS~+2I*o.tw/֬:У'f9b,&3\r[qnhL78\공T^Jjs4K;S*y~aUӏʧUW$:/5MiuLH'ksPXbV_^er6G^V @T0l9)_&Wa[]k@p695O +$.3&)Z +=ٚפTtu蝶E$O-YDbQ_TMό7> |TN,//V{,K +_> +I]'O"/zRWYߠ'<}'$O#/KhxM@K%?~ҵթLuH`phgl_R߹j<<' n5Dǭ216 {72gn\[AӲ6h3̼Ch{nzew^Œhixm$T側IΎR7nX-X2ELxa@64׾L~kBw!wYU糚 bGnLr6O_(W>G-0;.Ƽ'Vq^M5Ke!m@c@ͪ],g)>25z_X3b\PAyaS[I_>"Z9Pqx K&7Wr?,0ޚY{pZVCfx-gFO Y}ȚצlSh(Ԣ+\ ۛ, $eV >];~>SG*ֲJ6MMOzMs %rżڶ5J.S,'t:ўZܑ^c.;J>R!p֔pRnvpz[)!ZViͶ7Ofe;N dկEjxE_3+V6kb%6VgT&*7dX&>!J +mʦXsYV<*ҶQ]vG9YZ]Ɠtd g1/WOB횛uӎl5"R0eFssڲBP_9ǭbZi~X^l1&={%zvn˛T&=cx8#?P"I.w`ʼfvC^)-^t})@`9GXųڥi*6]vuZk||_\o=mZW6iż%Gԇ̏L˞˲Wl Uڠ^vĖ2F؉IՔWqXz<+HVTlɜU/ȜK|XBG.CJ$O-;brI] + Zk>BtlΏVJ_SS.n:';O hX>Yґ/90Wp >*J+g= + ݱ,71Qd:S><8>mAxve6n6tZgH<ܱS]rx*yu~٬'Rj0+enS.?? s/,E(HSeX4dT@Oh,'!hyV>F>>;>}À%^WAbI6mOuӋIKfѾ1̧'tpZوgٶO'{J6'?tg+~mv[:gP3ԙЖ*ꭺ!I8T;zW{a|x)U%+Ch d=`Ej,zj (VVFj5`Ip4u X\5`#g[V68hu.z §OJ42CCyX FgbbuU'X9.5捖F-`Q썔7P'fS`M7T&yKV4{SmUȣU= ԀU6߅MB@f lSժFG=je>YX,9{Zdo[TV wkIJn#`o}P0}PlL[ y[V"C +XQ'X U>a<)>P(55o@U"rA͂x6z 1#o5Cf>cIX3@Yr 4\E[6Cri>C6MKj[,9 +=kt tR)SM! +=kR4`5F@0U8n1o5rmX!-O%Av //pе6!oWVĸyeB!Xib`]}M' }(<ޠ+/ax))wo bN<#4OwoC`{$^"X)/0!F[1 YCuֻPQo|+On1d Ѹ7i`-ukАi3>0}86!lw0$Ro{SFE|̲z|]""[#+Rog݇c#/REގH4B=uoFn I7^#;x{ր P;V#;* .h)0Ԁ1z^OBA$~kŹ, !O  JhilENHY=] DYb-3 cG!>#1$ʧ@ÐڰU)'&!EXF0'wǸ^pk-`jm]Hhbt$AKu,:FXhz';A[G y7y1y 1Հ sRM=`< Q~;RIjKv)%q} 2%jC -`{ $Jk بI}$J/O +[UɓAJ,פzIɫ O69Hxc(qcGֹ0d9`a$Jܺ=AHXH7ATX39(Uo) R73 EI҈Xt$[D"|,w!3nc9|)A}* 2$e2o}Ρ#Ҧ{k2 I`mY,CLB?NY#fj*P"`&{zO *f$mfeDu$QVKbeDȬ#Y 7tD2eV#h\$2ί`SkAt$T"i==:"#Hv`<&! vI,y&3J"R ί0ц Rc &yX[Rɕo1Gw ٕAdZ*` =B&r,шYk/ʓ`BՂ yhD0C%"Xs+-'`B%U#8p$] 2PK+iW ]b:W +%o~J%̕ܫq{I0s%j̕K+wH%"h{cMFւ+)9XA`+l!4(YWҰl~̕D,JLL+ Jd! Xf^Ƃұ.O@ѻw_V s[v>-,wU׌?WV|.^fXJvcގnʠ<(=R;ӷ+7/%Ԭۊf@wBmَ>ܼ|uĶP=orW{i9[Z<ޗ˽V^G͛Hw'_0jYSXKDusl2wx/ +endstream +endobj +251 0 obj +<> +stream +x\Ko\I+2KR FbXm< ̀թgvqlHhSU]n}Mo +--ߘM={o3v;i'w|m|珿~QyVlJ{;BƫӛʲLvmps}{21TF&糹hwe* 5Wn]O6GظlcaR=fL6.|v0#*m><vrQ"iVP; f;E[-2jwcg{Us9|iQ7Zmu;7n.p6˜}pfąU; n-U3{ƺ-=6Z;6>G _~2Ua1֞Uu5:8[waĉsXrfdE׫6:_orxDŽrq`s*38}h{ҺS_La^7X(" 8\ƨR;`\x &e'L߱Fsyl!S_=%_$JOq3xivMle*;h5S(ΐ6TT8=J,Z f 6u ,\q<78o&aX,.Ah +y4ZQ-̚~l^K-`9)I` \+*TEI ' +X Q5|D4FA.D[U2Q~gV&|JnQE0M CqFnR W%Q- asl! 2м9ۺu`mfjɧX{ʚ +8ӃvX%dzM*V| +rFt)֢8a`#r[%BЎT s腍 Za"r" WQU?ֻ4e3: +v㪒H&LAf[ljEO ܬdEa3dX l${([KJR޼J67{3鄐Df>-t0=U6P " s #@#rSqmRF;:nLGeI.m`&5W)Ah +Ȣ/6SH]1OT?NjǮl@F؊eUgؕN|!@Sc}ܔɿ.wݧ:>#郞z{9,S5nF5 R ڕQC޵ #w8#ank%)("1TLmQlݥ #( +AUB36'8Hn7%K$Eux| ͕} @mn,ui2M%3fm(2i%c$Jc +*Ep:6W=#y]>_By(zQeYTf)wg>+x-2ɀJmJOj1r]ˑ8+Hiϭp;*?(;Ϸգ2]OکZA\8'Yn)P D@e66P8Z$Rc*8s5Wq_8Ji~OypLL{r+r }i fQ9nmfe[ lwnZTd2<|,]٠.,H&nq'aeAx쨾jds͖ 8݊k'` l0>^n eS<~*b-8bG=4)9p^:櫵NE]41i׫{}_oZTI.6 ?̙ry6P ; I ?LQ `~%g #rs GVp?гWP7IK"f+tHA~6g# 1T8UqB[~$3ޏOv* A%p^~iת6;ޏ z讎seK{5O9t_~ #~XU x?GRZb#JJcq=Wm??7dX#ޤP )$Wğ6V4O?̢LG?LU(n4 80;KGy#@.aM 2-3yBM,uB+`@|P<􃪪@D܂ 8g@Co:ȏXTDI rCXkA>WC+o|_pG+r*,>uvpJvqjYӜV\s ,oQ+kdPn B[} Z_!xw|v~`>p.Q0V(Z$n8+ivf񑚼TNGjLbȢWiWY;Ԕ~/2r+|TZqE xP =]g HՁ{"{x).̄*>Öq*d/ 3Gu2܃gm͸ 7 jW_/^Zҽ1j`g.tK +qE 2ە2Შ@ޙ#ͯ X۫wXL;vV=7 ˳ K(̑YfDt+]zt/B6wXȥ5hGBy +%< KTJђ^w|߆AfC 9s6<2܁3w~1o!|(}U؊C_},`%pr׆FŦ,q]}ɟ*+l)+@%Q"lEt3鋈ek0G#aN+. _0 :B.n0id`06EN00E+U{,ɪX|V K]09<^MƼ\78A9r/>`;2Zm/5| &{U?;Ek_v3o~_; +endstream +endobj +256 0 obj +<> +stream +x\Ϗ d#xnP Л=9dwN'ߏ]59HGyy?$ZR,k._._cbZBb)6ri%7?珿yIkIr[rzmhZKZS akYmf~ Gnݎ-^=~AZ%&Vz[V Ϳ>X/ Q^Flwˋ]O)dp_J̨Zm$ iW&GtNp(Qn4^0 +М҃YIc ء)16կe_6%;lG3$Ȏa ׇL(s1IVdvo1KŅ1@{74`h*Ƅ`LlZ^,R@,nM6=6<DžtNW3;y&om '6 + sk45oS^ 'JZ`ȢpеL;33;#:Y}'ʹ:w49oB8I ;~{6@Ő%c<@PIh߂Z{rWQ!9-0w%(s6*s!~sEJ"gJ{c 3/pg['trm(w-'Аtt%T5'}34vw>NYHFbcD X"٠`FqEg\5mM1oٯof'D=Ū>kʍ>x +z< Mjyýe>6srJ!|e9sd&8Btd6KҴPxE$ +EWC֫K# iMFn^CsF;2hWH@3:R. uT[ڲ'[4=j5j-U=72K2Med.'2Wю՗.0Ք{{ތ߲\% +mkl ${l65$ eM KYmұe'NM8ujbњq!˴%&!@ZOynӈ :;)##ꡅ(vЮknlަ7y(ڔ`{5]2{t&#d'dC'b4SݦvB(Hwk^I_I֠96S坦ec݀t~q~u^ud/_KȼR{|\iMm|;?GO#ڡV;[OgyW? Ekz/SRX}:h tSߎ);kLğK]Hrj!,7>t)[z \-_GX+IV*dHi% +-()'t :.!{FȕX6a}JJ-vМwJ1ɵ֜3 y0Qr&ǖ*D>ab"BC(X*"5X TTtG0d "$>0:S`("#Lq"D!c CP3.Dpedc9X Q][%t)BfLK1=c{+I*^yEkiP(iMڃ\Rd"D5 ;&&F')NYD,Rc> +`HL i~B,DZ" +ae|JNH\1 RHk `(´4m |34J.!XYi Db*?@iq0>9fg<6,E/uro@PDpy<\ Hi1bo] vxiB %_" %$0gȬR.SD=߈`(%{'j*.pL߱-aيW։2`?aK@UHI7*S''6ELC )D9 +Ga bAJp?%&!BѺ5CÅXю7 +LCKv*`Q.0E[!6 Ђei3iL2Ya aK#bQ;}Mp'(t)x-J"զ<Hj¾TZR9X"XHrW^vZ6C9h$ï@ UVk`XyEv6aJȎ|A"bĐ)S#UΈXj!(5ՅLEvT>Tj[{-؊[:uPxoOt!nGDƒ/H+RXRT0*ꒉxkSgJKRTsT"W`˥Шep#;j6'HcaS 0z^/)89kfyh9Jܝ +y3z}Jv[nFGp[7W+:N~ʆ9QhyR8hs/M:+[f;{+6(5k#3c;C$Q>=H x*ugX3C`{?s Y>DeUz2أZZlb޾FDG9Ψ|'p +}p}ҭdqfy~T}XCU cY\9K#ew[9 oSȘZhX22sVx/j[w F8/jA?&q jA1 㿉ڷa?j?!Yt}Cvڏ|e"j? +œPxjv@}\)GԞi6+P{ЬO +4457cS\Bgq#fС)v̞Q[SS1{0TA9 01R'DS`ϙ[0VuĿG3'`ʪ{ƭ+~{Mn9)J{ؼnAB؃hlT0|9/{? (3M=K g!U$!ޮ (͈=c?4! :MD卐Xxqك ͈, gyFhS#bϴ* {c0 +YvȞ?N=s!{xALV^@{8f,O=kz7l.("9cn3hy['>Oe=cȂg̞eu #a\ŸL=hpA{V ZEA [&+ho9[;J1 %d@C \۬^R!{-iM!©#dY*N}6k@;bҍ};k}zZ(14EJb٣{ģ!7Ȟ`;͘=uVdY s YfR19= $z camC 8陔|{K~)r +3^GS|#Lw1s"g77;;gp6Q| 0:fztm#uN;ӂ1wm|!64|+he%g: |Mq!Bx878?]^VEwx]ݺ< +o=+f^i;'K;^ h{oz+߱ic'Ӟx{8ɿoowڋ,T?Tݳ|cˍ,' (ܽ`'pXAZ +g~s{ +l7]hYӯǣ!91۫W'.D#uQnJΧ!XP3ү|]"Z⇷b谉ޙNQ׹H~F? 2|5F_~ +endstream +endobj +262 0 obj +<> +stream +x]M$7rW|`t9Mڳs0`/7|Xefvb|Lj`fG/˂ik^13`yn o{ӗz >J/o{=?~~kю~zltXq]Qpϴ{j [{i?>=o9s} +ǽ$o'$p~O=n6k8{AǭO 4 +bjlGGFT=~Ƕ {\{ +SPhE7*brTg?p)ʟo3 W`t7{{>@p&:_$&eߞs蟿ykEC kL_grD;?gKjT=P(B_67YDTi"M9|:}d[B@s i<3LMZԸ2`2=egԙHEYb쏝+\ҥq$`A}O5>\¦-WNI\j)ÀR]EX2BXl-G˟a"Ӆ\eK +eUeW0պzDGUrXN: f]*,a%)QbZ~E TFIf RlzTi0-;8z(eP:ڽP1W!&lxpXQqK3}8(%TέU&K +˿%8콶Jsh֟\^:-N&4(XkBښ n)U|?:=A`Nuc$6l~US`~<\-`9⑽8|SUP0y=cH^GFo;Ar<䘝Eqdsp 4دe,`F\m`-Y#{15'E1.F|Tr"qY. I`80!h(;LHϪ7fV5\`:\m5y&˂sL #BP^zu t&`CbM^?0"X[u6=bզԖ{Q#Y]0[G 6ėW*HK[˸yt1k[-Yhu(EښE ,!&]N~ i[jUy`4Q=O3 +gΞ 'vRO~$:s.H\07|}H,ȫ/% y!}yw]~bZޭAnzYFǽ:*;8F_)XZ@}AX*?2Qߟʂ,909]SM{Ct`UY`%I΢lRA y{ ˲Զ FלMWfib1wbYZ-.9ZNrfo +ї{Yᅄ }:K#or܆g}.'nOeu71̍Y>CfnX!PKp]L:,Ӌ!=R7[dR˩I`S`6#܈7Vg(JU0cl3"K +̷c(|kV[>mƶH@)C$b}W/*XK0-xJWp4n+ފ̔ Ya&IE&-C$x6h0bOB + kfda[U0J*BkFd:CGH"悖l ,3i]C~3 !`uƀU2Gn g m, Vg7fC˳QQd +/`Lcpv^DBƌ0bVn\  %7CF1 8.67Á }F}ͦ!#ҎÁ 9d5&? F@G@ܚI>ףD9&] ,,!DHj89* |`.q : ,DŽ`T)܏07(jq`y sHr1 bRN`}£E]h!FCQ+Yb=]4̾cV{\Cô kw Yq#&w<ÄtI; /fC'5 S0/W`UHB{әp?6[sGä7#P`0ƌE m@K%Lf!2t :+"LuQcZ1GQ4VTӘ/Oo'& O! 9a FL"$'WFTgtILuP\ԉ(oDk +8({Y r/p!s3y `F*Q$ubSa+̐$d|_vY,bB1q%qW&̂12l"1O5 OIm£ Y78#61[|o:mYT"pU 0jZ`+L/&_|2]`=%MO4UA%4Y/ ᎛gQɚNq( -4KRH,+iqwq}0p][rBiyM,/18be&s}]28w.. ̍&ښJ2 F Aʜ;G.&KM!xM:\7$p= E&rtH.rP'L@ ֻ`ctbb GjWMkRFVe*(=1:&$G: X|Rq+3]:!2OaItYs6!IM#+sE2P*bRTyrByPW~,Bn##R!4[<0 +p;u;=!`Mk#޽~\Uq\!S㴭|ܗ+("jM3.̇)ҏfi|  DJ4+KQp/|$CQ25/xaܤДhN /^F2*4~2/0t.ܤ8ߥ<#7)Ԋ"|9곿{칛٬grh?L-dο~s3Fi2Ckd}J2=GYg'/̿Gf(-f!*zve`g0ţ!(wga׳=fޝ8]~B3q/3LN⅛'3'I׳Ȯ|5mk(! 3Sr|ɘEN0p.]OgKrAmS_qNFQ>BZO#_bTFN,zۏbL0rݙAiy>_n[uQ/Z0ڬ|J(Η/UDg$ұ*abB sY2zahi]b?3T638ڤ7zͱWb)2 ;:Xm +endstream +endobj +267 0 obj +<> +stream +x]K\qWRBp'.$S" 4Re|_Uu9s/Ň.meo~UU׳%_-y γ^C嚪7ϵ/ߟ-7|>|$]~{< ׏_~=\߻]H:ޙʵpCU;?\rf]kmOS/?^. . ;5󚻴rjS\چszjPݶS+QKmkqy׭'f8Y/u)ѯw{Z֮^O ڰ +Spcv{ omNCۏt-|Za1w_Z˵ M~PX`|\v-/oL=h?|[X&^6'_km@]ŮΔ{yNS~r}ܹy<\B\u|hy~;g=XIF<'lSqQ!o`]ךjĤBs^Sj05IOݰQ\ķTEV84ljp)[ҵTٺ,# օjkI{ɀT"ŕNsdgNæZׇrB4j lXKMP`yT@,tKS bX]M% F Io$4&+2pdII+3ahW1F@ z 8F֍$nN7@g֍٤+u+!%b4) Meb$@!yyYKK23ad + BnD!vj&;ӨnQK~;uN_ZGx1f@(*VKuzi3d$dfYu" @H$gdD7ܺ)ZW9rpJNB`ۭZ6[)6-8'.(X aO" ިAȊ*jLX?Gap QU'!3b+= OG274d@g P$GkM !LY9fA-z+kZ? __ ~ Vq*i$;Bu8rS070W/c`I+X P%uN@#Y;[uVs ew΁ A<4lq,%Zo8صba~Xg-Z90(/ $eA FVRJEpNiC\qaGr|Ɂ|9YĤ$A(px>IR +Xs5]c(pٰ[7uaU>L& vLW!Vb.Qi!80 Lnp;e ==5/C5p L ! 4p6rZ61P$c;f`V  61NEWsSw%hjry֕]yr2Q?KAZM󆅆3lȱz3[YZtzDHǶ Ndj߱XqL@!Vr :#[7 EikA@ed5, 0,KqP\Цq>wbGl.Q6U "]Cf#)Zp[?P:TsAAA kpI &$sءA?1phjGM'YG`_7UfX%c;H E 1 +wʹBYG~Kӭ#)NkBcixf cB}Zcc'F0cB{Z3hiwbs9I𠁴ѠSP@v[ Tp6aѨSz`BFʧp\J#a !PZ g!H>NPae[@#urN88iukHk8R\6&0Xpп@h΃C74E Xe\j#AhƩ>@CuL>JԠƍEŏ>AJۢLӠN/1R薀O1~")98Og 10Rqq-lZSُA3 (>A+ʭ$n/ Zi GFWKP +A#->B/tA#5嫓VkJ5+nJH*%άI+ `4j8L0.m5]Mh mINUI X>H 8^]0 .r4eî ThystDK|"&x;lLJc:o8|itaq<JJ`n'b+)yp\`K= ;nG1p 4.NhaRVgI $('/cq!Mޞi &Z DKؓIERJU7qrU:R)mQd;6m-HmR +m +p8  +8c;89M9aI;GW4bBEgzVFV)-loJ2â-naW[#K(Ćr9k${8d9zQ!ا=PjU9bxXb .9SEcZpYS牴8Jx"8)Pӌ\}Jz(:mXFkZsteu9z +8Ӡ3Q8rLae7V +O +9օnP,WlKe@wq*AJ75]0$?A<<8(0tjYsG]XsNcD㠁ɞ٦hSϴ蹃)rNEfZ{͹-Hʤ ] Ʊ&C->%h)G NԗE0*Œjz >Z-X9h{&2eOaㄋ@=c_y6Wi,2nqq>m}؞/{mQ"Wf\8$t{V}Ĩ@ۨx%fjk'z2]?W@7wzcxh<'v'Z/\z|dGX:1ޟzV.Q.y@oT$ux.w4MC9H=N~ OAi0KO\ -]|-9*m6dc`)O#3 gLza=r)}kԄ;:HY[~Ohce\[sB?QRt0ʱF뗟.r w+8%gU~t)'[edR)Ga|uا2I;R#D\#DS#,C>@wf5R_kH\z,05R>ojg])_|\S#kU#W#oF騅F?YSML{֤b%a1ilt'K*#~Uؚn]0XjF+2gekʍyptsZ%!Ivr-I3jOZj1+aK3=TVmy^s fӢ6v{CÉ + +hW0Nht 7ڨ,2,iLU{Ga12*,E"b<1s0 -H&/,9Vb};A^lV +)EV*;3!, ʳ0AqAwINfNj aQO[!emg~!DsbQ*U,Yitn+KaitO!ecg{qSc. ؇9zegtK q]ZWg3==q\ %_Vl♻[za1UbPPM]C|}lzapHK&:r%C`0m!;FWt0S )n4MYiдmPO$X2SԾ 0ί F.ss99܄Hl,D-֡'A?)1k4jt4OG?1+γhڬ;i}_b3yJ#mĘI>bLLZ)&Ε f>AՓ6)20Č" x{RMncM>_?\!_|߀ֲGG,;!ln-,//ٞpGv;3LȆ Xbsh;9` +J%ŋe27WO+x2z;` M)g,/S9dq5r*z瀥U=74Y{rOYV}!qΖ6d{` 쁥!\<k)Q=4Ywi[Ф=tU,,0J-,!zV[>/.Xpn,#ux˚ Ig,SSm,ó׷K(7N>倥WDvZX뺶nc]X"3FvKex{kk5ELa{`yJev[ƶ5 9,8 +'SOW^bc9.X~ۭuG,}B*e55P5sU"/,kGvv;Gv +MqZ`kߢ r`yD;oA(>Xbqr²;Er>\2-'}Khi.,oa +\@venYXגWae];+/ Tr^yՑ\bU<~W{At]y]%K,zDȖUH{u޹\NVjyyv +A-nnCԓwfhamo$t<;[8?]_j +:ZmJP۝ᓦ +Tp"k/keooOyYY>/]vKW;7AU$feݗ=X&+xg~7Yx1J~8= ou*7/Pc3toQQҢeuzh <~mYu:[EXNaSCqۿ}b=^U\Zl"/v㭓X۰1>@%ݭzeEf(Dze2zߣHeYdzh%j~`1 >Vq} LG^޻Ʊ*gέRć4$Z+)FcvZ( f:/9횓GE=?-3|w˅z|dC;a'[^p}^=Р;,KĽ "wJ.7}޾9Xu:1r}*W*v#e,=QX/kb5+tW!zX5/Eo5Ur98PL?&|@Z7|bxc] +Z'p}|9??#A{ 7ymJ,ca>o>ri47R'{s 7'ix7Iy:$20.Jd=::yn#oG$Qt +$Vq+ˀE§t(XDY{n"lRy#o\∼g;TWѮNG6ȟAVja; Cdo"7BFr +!Ţ;xCg+b,QC-F!2К"Kj[aPQNq-yJ!Dޚ~W[ӻ @(wDʚ&vڌ8lCW;vy)HٙYYD^7gvIū)n]CԐtW/zbK] R~ُNu3Yvф,@,kvg)hMRy> XF?H=zpx͵\WNEoJPD?{-B/)'c;s59o!Ҧ;oMo7^ͩ} bf^NW~5\3oÊմj/x?(ˊS!D̟ۑ/5o1# ؍]7 !ApנV<8_/[ =rY;~y{p&x:oBOލf=b2E}^ޝWzC䖺 +endstream +endobj +281 0 obj +<> +stream +xZMW4rڅ0Y$$ރ鐃# ؀Cv%pSE6I=M ,=vOLjOM&A0=>}0}&(k|(pNJ|z6x3DT<%>ѷ{G޾I)r0tMZ XAѵRRh@HގwBj5 |r &/}TySx`qHxc^t=hFưakj)v#1ڏgU#2iL0Q}/3m(Pi?D/PHK)BO7fS:W6F6f{otZ{rGY2`x4P*oo;vq + TG|bzؕj3xC Yܢ/8W+㩮PdYaZDAa1/mOy-Bc@5ʘDE"8I4R w2oR#$y]E‘S|ibs=EJle5ٞ tBR%y)c훅&*%F#vRFyJV>QXtBYWmǾI]B:aYI$:jI7+oagavym9VS݄`C3cC@4k^gWgZeeaj` `v +EXWyaF:wËɚ`_xd;RRye`(lܖ:lL'>bq%gᯃ*BE^"2o wLUQ; JfxSR#z{MWU/zq(Dؓ6ukKY ,9K^=+$YP&*n[7ƦiKz !AU,_ZQbR%"+.:g; 5QGTEZr[sT- jY;0\3HZ/VT'F +3}:(ӞL4p7r'cbeC0-0GIu&LOD~>}"և+jJRw]Ll^c@Ғq[Y]]Cq02E)Jg*Y h>K `y~% `"51-H +LJ? aVQMl10Ѝ"^ikD|lZj LWb{b_l#v[GɞZdaaBzܾ0䀺Q#+ܦfć(~%AKE{(6ej)z]:{`S\^Uu:I(rg3` ClWgI= QϠ t~E T"1My"DD#_!g/vUƭ+0jRڨ%1R-G\L~XS=RSAuEwCmwŚeCWuOx+M`Alxʸ2?uK<QT]k^nO#Vaզe6;MH$l!д Mۋ +Vi{U4/Bt۲J^w/fZUJn~eB*Ĺ31db}B% 7ľ`0B(YyVϏ $aBM#aݼ1&~;'b.yoݬ1Y!K|h]|o-8cB|3}RR/vzM8˕hˠ!O;>gE'XE ٶ~u>-̖_]Jɾ` Ahl˯\WwdI<11K}iNZ*^rd,oG%4 5y8_}ӉdE5(GfpgP U +ER/!q (dҒy3#p!mX`6RHf4هx|CYЈ`ط gƶ 7N53? /2LWv|z_???[G']h|1()clns8L_GMY~GϞTF`,VOEnX&EMLӣSԹD,m%ֶGcˎPJ7$kƦdXZg~(y:Z{ljmt8zڬ@G\/} +endstream +endobj +284 0 obj +<> +stream +xU10 EwN/`;qH lHKS1pX 0ƂƹxeH +6 #Q +DHDY4DK>MYon6Jo;NAcyX +CQ_@՞b +Le;gcw4V +endstream +endobj +296 0 obj +<> +stream +xڝY9#E-"[!Y؀ld`<#HS画qwջ^Yzf!)//-_E5{obj]NZY)J5d)oBV~< +K]{ pTS/1%Wba(X8ؙ݆jT?Ӊ4w;r3<ra .}&e:* Ù@O栶 ~]UB'=[ybgx*v=|v|ඤ*ц5&cͤjAՁBimWB՚-A*nW7{2,'qN~~M< wh+j\XOtch62Z ,hЀmX߻mឬۜ]hp㪝[#}٨ƏèD(K'{= Z]m +|.{cc֚UYe%_Lϲڜ_aKr䖿ݚMnZ~_͊^mIИ*3Oxea:ț6s4uiئa;Ny*T{ḛ[|~U+0. I*ƪ[>ӀL8JnapC5M=ٴJ&%W"#*f'9x%9„Nm~6[&ilV6p}eo4*gXDyD˧)rW}c.ntIaIm-~=Q&$cRݎ4 ʶ֋B۩2ZJdE6aѱv36M =Ș֕[* +f .4|0rÀ-B@0mIе-Dk)Q67mA~KBm;t[cﭞIq˄ TWk@5=۷Zɡ-Q-*C̕1ͪd^U)n =Rgd-O_ik~ X +endstream +endobj +8 0 obj +<> +stream +x]ko\Ǒ_q?f?lOw=bha9@XP8 N6~!gzxgV)^zj%.ITE~tQE. rRIKKS%EcKrkO΋9n\byIVbeI9S~75>7q>g lxX"9s9<^x[23&+H';VRlT/.j5/--%.Z⒰> +-UKX5jR9S*>(yK+EV.1ex䄛WO[Y(R3؊[{QYZ70a)hXJ^lXżVS[7,BI67,7E6yXn"֭x .?zg"/5A + 7KPrDz)$T BԩR\1B)IOW.Km](x DR,T*dƷa*B[#$uAk:tu5MEInj,:BCŌ2RX?A%Y/. NQ'AN $Ӆߠ$~?QGR7)A=R*L;P'0Ni +P2H-"4Zt+rԠj]JL-/ 쵈it.)4KBjBJd|*͓+0j8UOQ瀱Jq,W !JF% +wʻxr8Gޅ|.1J jIKOgɍO]bpBr[(K~AbxGK -԰RB +MQ jX `u'fXPjw)]Qv+pQ3fhXp'A hA*In@'%FkmD`FIIJ,]'5JW6Bp}0W^ +e57ʘ$Z/{򻭿K.N֥M5&`]ƙOw] ߍr"0D0XP>#lʍųg_^mv__r˫?^.7޾[/~k_|y~/=ϼy髫7/ׯ6_\ >rŷ_|qnSrov/7/z}Ϳ~_7_^^^gv͋ͳWiǯ𵗛rk7k~K2e) d!I4H1qYB1{F҉=5OkVm:`<} +7 Ⓐssͥ-$ +h-0xiA|08&QK+jp Pbm'=9@@b X4"4kM/†4*d(,vڊ: b,krN@{q+L5=(Q2ك:^- [f)K]0i2Qjȵ59!`3̒Ś, +5E$zM+ppoYѓ#1th(!&D큞aFic+,"˥vM^;wkzB"fm*ѮA?8<5/:^ZCBzR_,Lrח! Fa]t6+4$]rV닽T&f[ +X@jN_)(}4G(ҞYpz +jMŁ{Fz !eMN!&P2+bBke[]ӌE8^ * +bM0#)WK$5euVY .LfŅfB%%f +XAKe_YG "5fieο2,-)A`Az_`TuZu"`er8k_yY*}d܋ P$Tȡ +*8*ILeĊmZ rͥwN'z[)iyhWX;\; V8]`쁭9sy30$€YOa 䡞)N +X?^Mk +%O"{2$;%0H!$vp6®64Hp,,|"G;n3:Z| ®"DªX;o < j2!Df_Tob $ 9lȲi[6d;0Ko*iJ$A[`}uWlICGh'=z@$CHGH.}Scle~Ht  %RM|NMRX͒ .Q\!S/ʶ|@yBmy +zȎ,e`1|Yr" +G6)ӥ̝GJP8:!ĠD}`%N,Bغo ~_NA 7ftCP­!г]BF}Ct6헛^>ssL{n'uҧ̬ > °q0(.DP a=˃#blք!CӁc.ZEX"cxu]CپYnI̞$s*EKUNolZ8<|ݩRǤ7c~uVd!&qY8*P9CEGvjg?3 {#"djXX(g#HYi3f9絴p5/$JwY J<3K Mj/r +idaѭz".pb8"Ή'J[.rthuNǡvUz'\N;20%rY\*bq`S:XfΗs?"9^G +3*بgmP̓:t~8C62ʹ=> {\#ys[8Hl6%kd㴖YbFpLKcb",v + WrIM*&'yVq2'BKYh"z2h.mdzJOriԄ֦!0rI(8RKht@HiZ#xADTY2j4@>vy[TrMbó@/l`[rl@Dp^CN+vrZ;3=MF?( }ObCܹ!jLlGB3/p  aGeK>$}QxYP k,+;7#VuhЕtNpUaH#P~6|ְn |ncNi;_1iʗ(A +tצM .Y%s=AqK0Q|7-Xګ,bzZď59΃a~d~.!:;iЉ`DeV<QmBtPpgJwIY/K61"!.uKe*\CM>;'ȦXm6qG+zS<ܥqBF8##EoJj << 7a.`qIi(Mv%329i}2<'Ѩ ҨZ~h=`O̻ͦ unSeZkZQb?]>yd&k;F|x.^v}gЖQt9E)WA84ǦW{tI =D1^{(0Vt7 cwG(^i%Ꞡ9l691}屟ymC~?i{jʽOs Gc^a'6zet*2glaC'}2,y2A4۫Oq{'H)ym= TcN%] ;VW4`7vP LC*[ Uwuڝ ՉPwwY=1ѧE1$,Da{ <טof4nz'}hX}!;[X(inJ= duyL%pVz>IhE4ɒ7J#OhAj<ܑ2s*esGu6(~4*&1>SUgiO< 請1Y'6+q3"YγytQ#iy=$a=@<w'PTS A +endstream +endobj +308 0 obj +<> +stream +xڽYF2#O2X'Ș*<ƙdYAtqd/3??J^LϿ}N?'psΐes_eN <,gu.f3n& p.K>/߃ϙ LKJ@?̰#AiT0'(PR{Otb \o3uc~q<}x7[A ,**e /Rxc<'0;r_cRg9He)RUYmXJ>łԮxmΡv߈Ɔs#YoPbke.AJdaQ+Ɨ*LQ;vD,Ov5B+rk;ї+]O0h]zFfB=$VPFlLA0@dY j? sZo~VEj~#%;Ru i!TF +ϑ)G{ esM9``)w)Q!B"z[y$>(Ș-8acKo|OAo\ϧC(_{ɭ${8Da궮+ $5|hs +Xk>^5~, >'Grh7mM0FC340h)Z(ziQՕ^i-1D|ͳ_:cg5hcmOڄç N۶%5Jy(|sqp .p lmȡ7w#wI ^m{܆{dl%c'3,?Zj)l/,^NlPmͅvoc-/zJP9DCtWC(`GqpJmp$0P םyJW:_9?9f+-G8 lE/>/QkRѬ=㷣U44AWMW"Qߖ#,t"*0C]Nz}{[m9}U0Z s~9Ww{ϵT?dΩ!s$m720 +!Va f@5"-DP ^u4zy7+rK\ò_&j m[vPL43 r3!%-ixH1Fl ݬ)^}uemNpSy*zх;Ź^/LaE6z!1Q0mG,g+FU1 PI6&,})gsWF}f~ڝnZ[caw|{Np1N߳ onKxm}K.J^Tڄėez ].cQh!XNm۸ZJBXgzhN?%2?췟 ;ʒ +endstream +endobj +324 0 obj +<> +stream +x[n[+@h `vh7;8]}_"#X2l&ُSNյ42SSE2]Lc5n:T)o~J'~xj}/;CO?O/3L A_/)̫lISJmd.0i/4Xd?rmmUBmYkY <|^N o?O|9~l_^ +NÓHAJR9@qFe^{(pu'cʮ<6\, (KoMn*hB 7QgBHT&$QKt2< $p97a2"Իp`M|y} i } qy +21EU>t/ z~nb/X&T}tckL'H-?d+^@?]91|^?D֡犜٠hW|:F +^ZʾMH.v ]@axa6Kl{WzN` پa«lG X>^0{AN`5! ^#eȏ <x}v `3jrNw)- 7 tF*dZ +[@!@V6/ @Cg !/jX:?ǵzSC]]E 7Z{< +* ֻL\N:o&|} ]\_L~kAuwl°F彉gEMʗz&r,@H3z;M knW * +*tEy *@*4{5|+1=(@׿Or6.I9L8;S7#凓sn-`銟:Ԭc}HDLcXʡys[@#}\ܷs?G5~^9K@AuZ-=vSUr%bx:9:k X'q:atgzW. <u8G +kԵl` r-w +<ܥޕ\|Fk{C1:޽H87D=C Py63a$'8rĽ%)Rv4Q+FNg)7v8TWk4ЖąDWsW=mxpگtzv{fODJPm-Kl^Vѣu5u%6˱Pa ()9xzL}HI_ٍ-%˄ARd^&k۵1Q +e$/t>SWҤ QuprnR+䕈߶0˥wrƒzsTBg'e,fr^j\gׇ+)r9jaNK"^lFe JP%~˲)miJ\xHh HA(˲p+ge<=f7%IL`cOW`tƈ QeO_|7#eò̦jWgv;W?FيS4dPTiyTX週dFd IR$ܘ.C2䧿5L +endstream +endobj +338 0 obj +<> +stream +xZˎ+ +HԳEvn0k{E񥗫 F*HӿOd;e8崙nyprl1q +`󧳳;}X{O@YZknm,g޹p8G.<£DQѱ&XGxVy@dzD]mWD@ݱd49}aHL&C3y]XUR,**5}@tlJ #EFk:*-NV;% }h/v^W7p9uFh5 +&6%0\، s8ދsl&߰ 0rpv֭2LӶo$Pal +K4ϝ*K8P+lM ;2^BFׂnoocquxmtt KҝC`/ cHD\g+fjhibsxXWoTUK{*-.i*(ح((͚tEpe%粪^L +̹|>Oҷdgem߱p}~OJ'@X|H;)\SNtc6,:/px;geBiHxĩ]WC94,hM7p*0>$Iԗ`BnFR5Dr-F!PJ),TD9 IHAD$R PHyң@>v8Zd8M'Ie cyQA#{Va-%%QΎRLtv맪ExnDZcA1(ʲmy%Xg% eMVWԂg؆^Gu[Zt2ے'דĸdpAu!+p(xO'c $۝S}{zKOpkUqk'6 4pAXf uM9A +bWTW|o!/\^{6~!9V<_:Oz k۱U ~{YeFfM(YlHzVݒ>rw-}ptS1H/WW-s'=e8[(q2iVoz^{*+bҖWSǫJ[gwtXon9^r+I8(IC-od"u2vƔ'G] /_7u_Mbpszn`R圁LH! YAm'd%Oh))L_:ᓆ laU-?)h!m +K7( ~,aP@fؔ.>ZU'Rw< ֬4}U>Eb[C60U=.sxʿsLE&#C]kWd3kHНѮ!H5T 'c[5BA]zUT:"J:sê[߄d|W$yWrŲsc`N"79*2h7{ŷ7\Bpm̹nG\i wbzx۪ՑWu`YNboh WJ@\< u|S+ 5cJh3q {uUǾw,Զ2py),Z_`YyV8K@g񷹼@p +q6vΜaŐF6ztS1:WMqi}*+Yk:/^͌k&Kn-fh)ri2(rK5Ł- kN*_12G>~oܗ +endstream +endobj +354 0 obj +<> +stream +x]M W1{hE$ ͈o=wK~HTcN {<=U*z#ד;YNN9US_OC/NgWL 7Z{ L;??O>ecrs|r/;w'[ۮ>aO?~ ]??}4<~w TM9$lG#Ƈg@Y+SƬT}bBl`M hݔ=ć_CB +s3|StM +.:zŽG]w1u>>ݕjpM~-g^ >R&|:zS uI ߕ<V/|W* +w +IB~]'uJ~r]gk>%+h\Py -Xd#?:̒t9[MQ3w ܏|;M)ʏD [T~ȥdOn( WV Y38G=F)|0q*kˡZhG'5+. +:eN֬6+QجXN6+Pج倒N hՋ f\_>Q:M8σZWt&.OKV)FVxlQ?ҭe>aY/׺?τW,'uAe;!J.WTVrPI/8rN'aR@#JՒ~I J%ǖKVЉլ+QXO+|dYl։ bA:ɬCCO~ŵ$[L }6bom<}x5}ՄW/z/ڟs/ +[z[rtC!/l] /42|5'2 +\һL"~kjeE%s| |wd"ǂzj~(m +1pk-G˳kR2=xaDy|}]cO[7"<$4 +QIBM(q uN@ÓJ~fRy4\$$)LJuʼ%ml悀:>gE/Ɲމ&rc,)[i@u6󨗽gxĦmw}ú`ZvOې!EHh"u_Rf4] ̦\S3f;-CH7>SR @u#!l%Q޾_wT!'y^'r/vhvaA^ߖ B^=>,R.ΰM\7 :uZ-v@bw«#sVt[]?x[trH#|G~va*cQz#q\fnB|p #ԺўZ wfH9lҙ-SL`G'S˾$j+֥rfFvC#i.14Mm,vZl`r*כ3@4D$ݻ/HT ̩ILAHuՐ+#^LUܝ`jt{c:Ŭ uy0\DI 6ii7Ir ]}kNX+J^5H@S"y_&b\~ -LPaُ&MY*Ιxhu8N ] rUz]mQ?8v,ۃGc"kZ uEqOS`7vRqۆxjޛi@$VTJe"CUMhaS/[uLձl{q0UEMkIh>Vc!l2 gumԃNaB?I;lĘһ1Fg )[匤VV e|ca٭0 l DpmɮJ«ɍm/yلP:ț˧Y7k_M֊l{qt*e#ERe.ڔ+|n7oٹe(m5 +ƸBicVL,:Ts]\f#smM#r\D7K)9iH&:KbgxjKb܏%ScF +w{S`ini]`~P PKa}7v],l]wVwU +k C:q 8X~(IKQOdG;ݞ1B.˶S}:<}(2JFq^c ӽ䁣wJ8t4Gh#GeI0vPrs,C6!cPvboi'Bn̷cްr f 2z_\NrB1_fȓ +XDee>/Filter/FlateDecode/Length +998>> +stream +xA0 pC P&Wܵ k(߮9Kd>QEQndEFQFTQEQQF$(2"(#*JQdEFQFTQEQQF$(2"(#*JQdEFQFsQ<~=p72"(#*((#QEQndEFQFTQEQQF$(2"(#*JQdEFQFTQE1(@djEQndEFQFT((ʈr72"(#*((#QEQ(2"(#*((#/ +hz@FQFTQEQQF$(2"(#*((w#(22HFQdEFQFT((w#(22HFQd0/2QndEFQFT((ʈr72"(#*((#QEQ(2"(#*((#QLdeDEEQeD2"(22܍(ʈr72"(#*ʈdEFQdeDE)(ʈr72"(#*ʈdE(@djEQndEFQFT((ʈr72"(#*((#QEQ(2"(#*(] od2_܍(ʈr72"(#*ʈdEFQdeDEEQndEFQFT((ʈREQndEFQF. +72گFFQdeDEEQeD2"(22܍(ʈr72"(#*ʈdEFQdeDE)(ʈr72"(#*ʈd0/2QndEFQFT((ʈr72"(#*((#QEQ(2"(#*((#Q&A +endstream +endobj +358 0 obj +<>/Filter/FlateDecode/Length 59066>> +stream +xuGIn=8Akp,װ[{oVX?z{sPB&дiOCCCCCCӞ= M{4444444ihhhhhhдiOCCCCCCӞ&˗/Nھ}PB:u*M4M444?~z n߾ݵk.]D} S }CGH-V‚hEb[*F#F UI^^:u$"%KFo,>̿EQk׎_d Ν;17sL'Lt3gԩS[6$4XO.]"tRڵyt QfMnl޼>rHw-ÇkBQQFuʕ={ljo޼{.ys$I~駯v޽gϞU7nѢE.*K_x1/^<퓜 5$OB3 'xzz*1rlsNJB + J95vQtWC{p2DD}VQ! TCÆ UE&yԉ_$BTRJo…]t+VPY^~}ϟ_Xn%K={T}]v9sSdmX=:Ad]gӦMԩt~~~jղGƍc`x#;a„O 4/|`jg9BxM8iLHYd!ҒhdQ={F̯͑#GjՆ R~ǏQ=rO<ߏ$D ȑ#+y8AHVc9@wD/lݺLjG0u+WXo8ڎ<ѣG(ڴi߸qRGe֫0eʔ}zWNBe"c G۶m8McǎsnܸĉOvޘ1c,X"UT1ܹsplpC-2p#GZ;vEرWA'գ.mHC\fϞBOBQ6eʔvtŋV 'u޽;A\J~zk\bN-[8qc**JGR#82 &P s˗zYTA!'Z^Zី Mdϐ!nmcpC ԚmEp:u*i +:t#F4I0nVZeP8e :uA٘#EʕK۷o4[%EBI&&Ol]#Rn\ +:tX]G IACik&$dhF<Ί=ݻw7h/AF4MJdϰ8q"E(P …J@A+TмysbYŀET cƌIfI":OOK>x we]qf^?Ǔcf~#OBC8a\ F]z5 ɕ̵<|ˋšĉ oq"E!Rϟ_l]v~HLBb\=z"]Lnp9=ep2e54iR:; +vz)S&%"D\:Brzy8)p*Mד&X/Q6OQ'Tpݺu$rƌ].UV)[ŋWZ5"'̒vZ$Q̙C8'>ڣ9!93oqGaA{ݹs2\H>Oi)ǬڣWd.(KKUҁn!y %!#&KL0efذa\`$1֋Xf ok(B@F.w+NeZfz… ٲe3HQ:;v 1ԲeK: QwoԨ.#1bZgҤI͚53Q/>)Xm? W\S4]v(E#*6p(o>ZGժU Ɍ+z b_ PN@e˖ըQ?y6 R#g߁A5kM*0ўT\ ںuk +ĝ  jp pA}ӐQz(ڵkt&5F/^TE{yN7e'Nر #_`WYdqy ~Nˇ䛨9r:th2푧Bi0 &1bDK9r˗O\l޼Y&<-Zl߾b&+.\Ԑ>#4EuBʔ)k׮vr'Ols(@vawWZrM H+[Y8x'%$؀ҥKGvk9MB _f,Z iqbDL|gѢE2G-KfߩS'NV+'2\۶m鯠$q]!nٲ\}r h=cpI:Or1Z,3|py4T'#~.|}}e rX܀`7o^M43ѽ{w΃u0A,$# 7vkrȨ%GD.YZ__L܂҈M.[ &CM2Phe ]ڨQ"xgnbw: ?"7H~ +7VS":t`CAZF).D`hֈE*vyXVp/MδiӒ$I"f/qڵkRJi!]z5QD.tǏߣGIqHc@"/@ 1W?5;?CÉѢQ 2C5u/ +N_ +qSj M m䛒]V3fLe+W~nAʕ#="v.$ + 92A<Mmzd1p`|1c_=TQٳ04|ЫW|`ګ&LQbhF??? +6rblZhTRoaVUٲe3z2ˮ-=N1cHQT)׎ lYɥK0qˁ;8ӧO% FѣGtN]6%p(Y&9Ynݺ.?\Ν;O<#['O* :i)R-Z2B8]G&pJ񹃁O&l1B0PQ˗$|9E=O>5r*;wn볆N;v~G%/Zc/s_RQiH[(Sý{}d̏|r.y+xϞ=5JVA//X`ȑS.#M8pwE724GLqb>c1uQx><3gVZ)y- *ÇV2O 4mtʕ"EcYZ4i֭[̺ߐ5ñ9\IR۹sg(6t=B(Եcǎnݺŋ3 eذa)ŵ0y d/?~\B]v2eʸz'Np rW]XbhDzeƍG[Lf͚Jr/<ٳak;q,!K e/yбc4hH#G2(Ż)LZ][62,/.*S)tb06m1R8Wԩ]v וN 1 L-x6mZ/@ǎa +^fL=z'|^zV8OL]V$vy΃fϞmm˚Bo[K0ǰaV$|Ow  t65o܅ ͂eF;OK( +z8p-ZPO /(<)3dO8Ȓ%Kȋp+q@={[@V{ /kӧOѣDwqjFVgjժe^x +܌6:t(] H1J*Y$y1U|{رc>̄TM$Ӌ.H*;/Q1`'OP"O;rH\[g"E +C5I+*-MGsHТECQ2X,B# j`O>Fp1bk:Z^۷T /%d@sΥ +0Ydu֙76 *!C<ܘà f%`a+WA +5k*(:"k̦Lb aÆoXmB{tu!d=#T1ԴiSwS3@Ajw\j,n80zj%[0`„ /6$Md晲g/^}z(e }jE*Hj.qıؕw%9g^~f~b5j/^HNU:t \[Ǹcwء@57JߴnGuQ2q#GHO )< Mj܉-%zhaN'MVހ+-F R~HI#`hUԩS9sĉS(?ݰaVt|KK"nz7E%W\vQh;~?or^ m˗) +N:& ߰aߚ5klrw޻w/N( Yܽ{s0]zuѢE\,_܎c~lۍ7탙_=jw?~|(yģGЪ\M֎''L[͞jժH!?6lP{ڪnݺnYf]~ .ء&ǎ+޶m}FK.HӫWO´e͛ח_34WR1c޽{%_z9LڳO*T+rZߟ#Qx:uJm |rٳgSeVC۷Wrʅ  hĈLr]vm+g7|Z3gΤIJoE„ ӤIcwE$H '_F+ǠA+ƶmDyvI2tesݪ-O0W̙34h ~\c6 }ljbϞ=sI$1$8mՙ0a“'Oz̘1vq ֧$/_#Fȑm*s Ո;־"=h}ׯ_h۶w}g_A\NRzw9s-eӦMnn@rv]p"#VX_` f'NL2tŝzyƍ6"--Z0%Ӧ"0O.!I+%cƌeʔ1ǏmDnh>}=z4TPmŊmue˖[=: Es$ImAB? + ABݼystݕ">ehor"E +[ #FEZP"EkM> Rn߾}o߾G=yJ*7o^ +";x\l{U@ :hذME=[=ekAgϞ{|PBB梪ݴdRJhtʟi_Z)kyxݾ-20҈ d%lzxVӧV{s"~ŋGW\9̩6_~m+ٺ.̬sIE*_XצM__P±q-J˟?ƌ%LgʺB +Fw*^ҥhfVA6|aÿyucjժU\f͚Ȍ>{-[6dV0aի瞷EH'\ؽm 6om $>i1*OΕ+`!/ZjJ.M{E9~Mĉ.]:7H'Hl9Sƍ۸qc+9|Y@ճgO[75D·Ok:vhlHU#a„s]x1*asO ;wtg}W^-9}ouЁnw'O֭{IT1cHႴ֭:t(Cp)ԿlkG ^|:yݻ +hhh|Fέ@C&Dm3a!Dh4444444ihhhhhhдiOCCCCCCӞ= M{444444d ,[.&MRr,ƿϟ?_~6mv4ׅGkn?~ :tʕ#M{ +1bo-ʔ)cܦ۷Ϟ={ѢEqG۶m ݰ69V… >>>̗/_=‡Uу;~ +* 2MyfѢE3wQ@; +Zr۷ٳtRAu_Ӟq̙3Ӱpܹsc a+V8vX֭pj޼y ޾>CoK*e%qͱcB}y˖-0eGH"J2cbhŊgΜy%aV$u˖-^„ k͛7wtP{Ç*H+p6m Rŋc ?ٳg +(lX2gR"Igն=z4rHj۷Δ)Zɓ'. N"`{K,iР{|񇿿?u9wΝ;G82N J ;uTˁlٲ]Cr)mƍgϞ(1 ɑV/w$A ֭t3C #F\}wD FtwСcǎ ,,)]t!qcЄW21c`DŽ*UH˗/ϙ3ĉ~8'A`\(Q"-F]P'axb$p + BcMN7O۶m<|iҤȥme{t+&B "2/܆>zE\4g„ .w` B0IJr…#GF\rС5" nZĊEnCTBx:d$ ÇG`I͚5CJpϟT{Ç71x7KUmuVp*oRTRe͚3F"p\rxH{N\Rvm,Iq"Te˖ŋ<>EÐ:tqT=hѢ(_$~J+B$$,Yb fʔI4P.t ~5j  +-VzuN" rBɱHJ\!EU94㉭&M-C#S">u|f3f>}$ќ6mM ZFn"Te|?-nʔ)r -[? (@ We@*~$k#5"z)jX9lO +E|0/D. 8@ÑZ_-Z0 -O>Kj֬i#sp>(U % +A°j 3iW) (H[BԩLc ŋ;t[ح*;y\7nƍ<\RbŊPo޼:uyH1b 3vgnҤ ohٲ}KWX%Ktq?̐DAݛjvbȑ#E2]fyXP=vX,Y.r ۱cG#2,۷NXl\[!?zhPرcΝa2f̘*U*ׯ?>y}_0h !OƪQx;S/\u[LyZ!)R/^ =駟> +g̘m6]=^n=r'O)R$@Yp 8M*$DnWlذa:2lX"'gȐ!Ð!C\!TY _h1JRd;oɤwuiDRn> 9(ۑ@ݺu]`pg\͛5ktCOػw/qu Ã$qWfGٳC0WBYy$@j_*rqQjRbS֭N77mdÇJ"Ո?7 dʔx'u̘1[D 7B+.ڷo!!B>, ̉~]Z xbTԩSӧOoS)S"2{ |=%z{{ĉ;~7 c6JٱxGLѣi%7o8 Zs皧pb_FrJ2eN:EUʝW֭M/S.ձNc@ž'^fypٳgQӧOwôUV8ňk#+^x5?ڵkG6bҥe={ȎusTz&Mjv-FeeHdE3h+VP+WĬY$!Mٱce.ǘ2,VXƌ631a"i׮][liwјKrO]4*vtPժUUrC`~Xb)`ǏS9f.?s ʕ+Whєb܁Yվ3j( ƍ۵k߼y_~47{Vb+qI" +/@{.]WPs/^$E&թS}L#4HpO}m : ) J ,Y2h\$DeQv-BFlŻw=zw^B%׻J{Ǐ߼y3237X\1fu@#ʊdÈ!9zn"K <oXy{w%bĈeʔӧOY'MD>iҤ!3sy:jZ8CB<.b7n̙3'zH XgR8[qUqPJY=#FU =2 wm۶5B5 +U;vt 64^S _pJ;xq#J`b%]pa;GV8Hz'[\@UF.\z0aҥKq(/^Pp[ xNbW@:i;zp۷?wP619Rxq|l u8>I/RxUVñAEs~={>}` ,Nqzʟ?~]߶m[bR4> Ax~{A99#@ Gw}ڵfG]ܰeAÇ7n( p/kAn8qnt2-'v+WƘ \YfNHP2+",C|ٵOp@sAƈ&DH\?uTJo'g5dI$I*F< +:]jffO`%H3f>͛$IbF}=EsˈMr ă&B… sjw5膅JvZ}I^uavn~:`DZÈ6z7 Å GC}Dx]ׯ_˘)OFeRIHՇ"KN.S0lw`"У1mf#eAڵ3#tءC'ΝrÝo[???Z@_hYr l^^ԅA5*eh@MpA"c | +֩Sn)@b1OBN Pg^@^UTqچhƤd +|.a[l+T`3)pz 0Abg9`_{h(dUtVW@4_0BJAҦM{ݻwƌ.v/q:u~ 2Cܡohd̞kMurȱf˵pAZ 䝙sܱ{d'70D*QT2e@btp[4i)2 ߼y xncCI&%ٲco߾*E+)Rľ͍ơCrʕ)S&mR^^`' n M{4444444ihhhhhhдiOCCCCCCӞ= M{444444z֭[F}q0X-z?|uy)Spr6Չ3f~,<+V,ZHǡfZR]Z={QpƌSZ5˗/]t\$JHNx7nѣgJҤI#?}tAԯ_ȑȸc|}}/_~9GiӦXb֭)2` ޽v\oڴ )cСk֬#F_~%K,A"vYdI8q̴ɟ7_. .\)߼yo޼;v,Ǐ_x׽{ܹs͛׎{ի#FHPw>|m6Uo߾իWܹ"C…(9shF`Fa1-[ ۲e rSJM0!E$O :r2رcY&S|-zS5诀A &vN,X2wC?ZjҤrp2d`(jԨ?\>_3g)Rݻh̟?ׯ (iL%AS˗/aFM:5`שS'SPn0,c,4B Y= +ڽ{wܱcun: 64BcѣG^ZjU۶mSt(Ǐ?gzy2)BH BlFʡɒ$I4Q{ĉNJ4hP.]TqɁVREƠčaʕ+2 +(U)]%ATR?y8>Fo-];eB*,y+Xb3gF!S Z>a( 5ҁ(w$<=3f)R$Ž1oݺEӝ:u*^xؿ"Ν;LZh |lٳg&Z*ʟ={L6lr1k= Aɐ!ß(=zWHI-|HǓBX,&F(۷oĉCk׮͟hURiBVҤIc`2 :Kʕ$cիWt֤x ʟ]v#)I2eB rLzAҤǏaMp7b޶F2?had tȑ# ppϞ=mŋ1?Q` +PC44ٌ3֟ebf*J"{ +@m'V R/h؅no߾%^1>| 17(2!gӧQ "ܳg5kذÇ7g.2qFCɗ/1}HZsm+Qԥp®-+9Ɉ1e2Zt]jŊf͚EڴC,YvE% +|roooBl>T1 4G T7n §˧JCĴF&`؄ b&;v+Ei&b+$IJ)Rk:'FQ(vL@ǬUCH]%h*r+V,,CU1Pp+dĉ2{.N"d%'>C,#-,\H޷oZ&?#rӧ$L2ve˖Rۓ=8Oc矇j6T +$)'0I&ۺu+¾M& *T C@~ , *dHnݺ8¡$YfV֭[cTJC*pg$鋤S%u'N֫Wlٲo^xqsέ\$iҤBYv$I\ndɒ_-,4AwY䤒C X-zAܹs=2i 34!)hΜ9ϑ#DyԢtׯ戤u>| ږ$??? * OȩסCh= V.\͜9S6Ua#FtTjiӦE0}c󓯣2 |y4IO[6m HSN&?SNUK,s[lPaӧ%1l׮*Je|A |VޝKgwk׮EŪ}$P|*K,T.:bŊo`Ç< +P;1Ё2e|_hqY[/)/ӤqY+WMl=+ÀlC‡Lqe)aÁ,Y2ʁ&M\8qaUeƲlL@ #k4=~ñNLyHCҏN#yS# 7q*o$J=zD^׬YiRիÆ K6˥tޝ!_$|Ʉ;i20c|"E +j{ohEWjE(lG*#S|gҥjWqYٱǍ DנV8qbr Ooߞ2ھ}/b#miɓ'E/0h/ಢ 2IV߷o߄ <d͛嚐|%V^-?ɓ'WڍFP!Ɇ^ܹsGvssO>aednj# +IOQ5 2I$n.C&\)&G"+Qi޽|m8mYZnM7x;±QFޤхf";@dAK +r +hܸѣoݺEh&ˏ%>ȁHVH!Cy8?6"_ڷRaAUĉ&gΜqJPѢEFΉ~d)c&{@gTݿcHܠAtҍ1(Ƕ.# Jسm{3cIzgϒ֪UгgOqϢ6w7xM%Klʔ)rĉ=v:"ut$vsݼyn(+)L/瑵@r1:c=zMB57;un::3f$d@|h|ԱcGXv-1aFjIGhGmٲ1ݾTj e(d$Ȣkt̙3q5ÇǢj֬Y~mVXx-rH:+%O$wm*Gȑ#3g駟䤫`f͚tҡ'N{ÇfuL2E1Gc$I]ӧOƍ3f̯}wAաN2eȑ#߾}!Cի{yy8C +ڲenK:σǏ/_lJZn}y@cܸqrݻw5,Ry.\(Q"U:itqm@ԫWOՙ)cƌɝ;ѣG\r惮Zj&L[EIǎy)s͛7.]VmMCEJ*DСC6e^v6X7on߾]Z5v<1 . 8=nݯ:ti:_~<9sׯ'>D= ц+hq1 mٲ3[8/v\a plٲyzz$> 829xY|~.]4h@P1b2t!ϸSPQF)Y71}t C~͛av)i7Nnx@CLXwرy浢S1)=;?*5kVׯ_70u; 5{KpX$hp ; n{sӷߙek<I&=x;}ʒc8/;\p +9= (y8C]\Ӭ۷oWXp%J%XP2>`H"!Bz'n[G"ċ'jp'N޽ٳtUIg$6ݵdD3 vTYC֭k@"eT|'O6NHP2LY[n}p$r$ BfB +%[aY%=M"M4|k~BժU^w6~ oeqYft1Hl!\ʔ)Z2S +^ƍ*dd M BoҥM.u*g1 w̸-E0kd+ +"V8=[]B=A:*WL3fwTqdxro $ +WN"yٍۄe%ҤA54oT"-J̟?)*hJODY&D q"6'g̃@@Hj!!G==z޽ }oH3MZhPUh!6?Srj*'&ƕ nAGrJEQ={LX'C$v뻢lٲ +O>}@9'HeVzu>|8z b߾}W\⤾t +&(Q"ĸStC: _ ~-}ajG9sfȑ#C{ݑP2K$leNoUH@'9rN~JIӀ%$b+V^M&#^^^J۴i5e̙31@8/`f+96YwhC(b +KЊ+HZ9)!<3IUHhoӦ p d)>#7Q` YЃ<V/^ M]*U*(WZ J\rǡ%3pTOs'R3y3Ei'ECN)NN:%CA RHS5 d: 5ju o6'#@l֬C6nhVK>ϑQN:y`]v}}ɊEd ,yɈ#LIXv-RC&VAC=ʁ;~x%,ok s̑ Ew˖-QUx7oޅ W.p#{ݵ 2p$xPCO,3[8 t͢E}De˖X5Bۡ= +܀c?~Сþ}ʗ/O1{СCaw[k]ٳg J#ZN8s\ԫW"5k֛7o7nlhC撵3A(Xe.슊+ZprѢE,loٲecƌQB{Aiϵ\B37D{jaTJte +'_nxP{`Z6m +*Z"dɒYW͛7G-H +~:A'^xʏt nΝ;.\h5}=p薀~}=~x۶mq5ϟ/[b-8OGr, rAM9r$f̘rRgxJо}@,nܡlbőxm E_,X1bDt^|y?{"؍cbERLy_~o߾տNȑoߞ%KU%.[ϫ/_/^}zƍJ*͙3'Gj>a8O6͛I&%Kc\>ʹ/?$tXG{(-رc=ݻw>*T((FٳcqAdKao*޽[lYl+dȐO-.]:U9KOnMh3:UJhŅ  ߻]Ν;GcI:xMvOݳgRVɓ'u֕~%ĉ<v:}EH:I\kǸ 4h1b 2$O8Fʽwnumy2e&Lb瓹VXsȑ#xAׯ_SUVݹsxR!{~e#@|K.uXU +=*GU'ޖ,Yb mɈf0n8ׅ%z|$I$QyK&4)S&(ɓɒ%S>8Xb0T&Mf͚,mIcǎD"]Ĉ#f̘jKA5N~˗d*UEg?~|qƍ4l.B'2 3غuk8q% ԭ(ۮSεk׸Q̓'f͚^^^x^IB[񠇼yz,wCkfHq^#Ċ+t}Ӿ}{F-_|{VR6|ǡ˭jժoooQ8Σ (u͛}||X6*&ZECÇw}GAfRUU֫WP'6ЯK6mڄ]v=:tj$#%(T\: 5jqO8zh6gΜGv8a өNHXb;mOXzR%U/'ϣٳ[4EJRp$SLQXS rI,J`ׯ_sM'+jP^ JiܸgbWN k׮6r r +闌ŊE͜9t\^z5R[. ,]eW$EYp{]#YgtuhтqA͚557ӕ09*QD``duա_Bxz +U$½*j^x1H"Ōp9sfW23Iuh&С4A{.s9bXIڶmkZ$C'ӧO% +bmytBv52 BBe+3ւ\8:9/^M5l0M|ի\KdE6m\D6lX3fp:?$&:Zdɐ!C0qZOZ + +Μ9#N8vڴiʆ-h +CdNԱCj#)YBׯ_?m4)ٞc wYSvh "{qFeJΞ=[vXD{NJjM(Q"%cku]fM"GcrJl=M{:'&ڃ +V,t(Tϔ vV… ;m5ahqؓzmٲ;wuV$b# &=&,Ҋy͛(q?f͚eW^E 8t~/ѣ*C Nȡ'J r +رccǎ?Ν;\Y-@n]o)S{ &L(Yk~9fI) @Iݺu6m +3gΜ3g)_'NX!eʔh,e˖2Ca^t װ%-gʕ׊ "׃`}rYT,AAr!_YrCj@PСEczbAtЪ?&ZU*Ϙ1zr~uhCByܽ{wԩxѫW/+*f${@# +rӁm ` [Rׯ/uq|e,gtڑ1cX[AH[wڅI$ DJW)BH"raǏ dRO?.]tԨQy&FQP5j\q=R ŰǏgחXԢE UCYjAh"u2dHʪPn+z&WrFeFKFQ[\ߺu3- .t<_1&dhdYub +۳rrd5BYtLTϞ=Iڴi9YSNR|mgPx1w95BX7AF5x > ,8y$`&\j +F'U~QL%:6 nߓ,_"B!4N%KmO:տ{-!#q~Čߟ 0sƬ{[!mslCJ +#?zux{{?~XUG``0?uШ}\[H̙3eE$H,R 3g.T|%Ml ;;wqǩSԜy"&OYL+WK.#Fxɸq̟ڌ%X+Vl<ݻ$gp-LQ'q.?|e~qC"zxj3ZpHLخN{A~XΫW^ +ԩТE&L3Q{ ]#Jq5?ڼy bٳ'$ڿ?E˧3R_~Ŋ[n;vl.… mӦMvϟ?4iR9N.)RD?D9.^7nth/)U?tUI,_Ν;1+VĊKbVիTY.;Rϝ;7eʔ?vb~MǏOk@30u2ޣG%-qjJ&u O&ƨh8L@֬YJ)-4sa+N ؽ{_ &00:u0DĈ;v~)>D֡R;zn͛9ǎߢF +marh i0V5d˖իWr&_!LsΝ)S&i(1bj׮mD"5>  .f̘X޽{i=X܊ci4Bj~f͚EE R@%7:̙30/Ya$NY\gI,X`† {,Yn݊ӆ N W}AdI&Æ SouXV(Qa7;J(ѽ{wU1J*Kt@V32%kk=z8Y VA4NhDQhn~P 9r$lL!syc6uh[pɊ½qgxr3tw D)Royڴi͟9yd?yA͚5!˗/sĠ .jk޼}#h&TxdP Hҥ-=I'dJR)R H_ +IOaŋĬPbm>|7ڵk.Vzf͚͞={ΝyťKDWXDYXz"&X:'Ŏ[,B}d~?vunݺ{ԠcQ˗WR3ua5 ثW/Ic8JuSQ-ƍKn'TwբS&Jh۶mGA)PBZ&M^^f=` !L [͛7CK +BuP ɟsA.`0ړ>1J!ZVǖfD4d~bZ d"DEnL2m\J%C*TȊ3{u%8lF>dʔdVxfj@M8QC#=ؓxpN;z .kFՑ eʔiժP^=IHaϜ9AHXh/K,$4An]fsr;uWo޼)\0ZΝ;$F9rȗ/΢c= ]ɒ%Q2-[?vI{6lPUVJ|#qׯȃ`S>6h@.]5n:u2ٴgÆ/Ƚ֭[GV1n8Gajʆ vG lذaÆM{6lذaÆM{6lذaÆM{6lذaÆM{6lذaÆM{6lذaÆM{6lذaÆѧOcΜ96mʗ/_~2gΜ*U*K۸qc4iFQfM>|8}tӦMwޝ;wn%G@w^@/vG.W%K*۷nݺ_Ig͚c94iR{Dӛ|ߐ.] :q+lWcz}A={e˖yŭ[Zlŋq+VL۹Gv"\-СCˋ{ƍԩ/_ɓ^zE9sΝ;S:T` Gvu}5j`ǎ;wY5|p%J=zJE;y | 9S[Ck?8ի[lI>Oر=yZn19rxO:E8ԾͥKjȍ޾}۪UQFYKxXE _=Cx=y0GE4 +[d CNuԨQ,)R * lGůͿ=jРAyK߿կ,Bɒ%Q$:*̠M6'NP[2{H끂^~=m4}>/N8K]Ȝ&MXqW=zɓ'n͋l1b4k̺M<9eʔ}w5.vXh駟fΜiBM6 .Mڭ[7kr^I&z,5`Ζ-Qꊐk Tg%˗/DŽ 5 +3 +i/K`4SJ;zjK0aW?=ӆ2+W=Κ5g ׯCVbDNpҥ +=f͚ծ]gϞ&Ӡ`tRY?~5k $, !S!b.\X[LZjuɧNji-dO1ɳhu$/u"J ,Y2d0a 80J(zuƍ-uFξ%;w49yRJ ŌsРAr8ȡm*?-%޽{ƨ?p-uָlGŃӌvJ5j\hvLב#G\pYNܹ,{(ݾ}8G|ĉׯ_ + +ZFa~thK,˵k6lLMUVÇ۷o8 RW2O+Y9r܁w؁qsС!2Lk=nݲnݻeԑ`M-uΜ9ŋ}Z-[vѢEnWFq?S:ECacb \X=049ҥyYdӎ:gwؑ ڰSNWLݻӧOѣ < σ,Z#f *5lذcǎ"#Y7)z\>r87oMR<{,c(\0ݴiӷK{XbGOLUz6|4<֕O*|&ӧOeD{$yD7}}m*URH!Q)٪ UH $m֭*7pSv;]oժժU^iP>#+ )ÑHRdcnݺ1cƸ7ܿt|˖-ݻwN7nk׎*#;bNr*kjׅЄ$"NҤIFʃ !$'T^ժU);D8&O\gȐmz{{s 41bDA}U]uɗ͛7c*R)СC,?u]B84hN8 +ҽ pB#4P^T&k֬)S4CǏA5͔-dو y#ˏ?6oB\x,MIRB a(~O cP,JoҥKG80$%¦Iμ-[t~z섞5jѢE͛?uꔙa;@ySN0)… f +˜䌫d2F4& ~9nǓu( ưtbBN Ub + ٳgHۧ*ݻw1*q~%&4͛_~ +sjAD!r{ƌrɑO*BںukٳgĜ;wQ M&i)G8BOc9r-$#J4m4%\|ӴT:lӦԗ1dtġMZf {zZlYN jN"/3v &4R{Ŋ ={%з: M7Y="NBbcYsQ-(,5I8lذsR)¦#0&MH dK:GE6q3L0e<>V*Dp9 ,^n7:SLO&pC@N 㨲&Y Yƨg 35N̙3J8./_>DA-Zx葰bZj ӤX +JY".{!'UVuhO.ҁ|Y(xV.RЀx*}vTC;>0Z^ĝWZEXD{bɠԙWݰahy_"FLM>kXŬY7o¤) h(ܒYtiҥ)f"7G50'cǎ浕~ ! +"RsF.)J K&N(q܈0h%+9 -B˦]s>Vl |S4)>F)0cƌH(y$m-ŋ+WcD}`F3&n|O. PyeaZieիW +$K,`D'r̛7OF0 $ ,c'M:Qun֬۷o +V̠vooo%P셶ӦM0|jth w5ڵqIAʔ)׮]d2+03(ChGIG|pOlْX# +]U-Z髞Vܓ'O^x1 T%͛4LQ#Ax-ZP%$Ƌrh|\,q˗WPAHBO^ΐ!AN:ԩCq:AFؖ-[ AEHh^k>|H@ՉzM4iذU2y{KZ)ӦM[~k6+J"mKܓZH҈F:DGу3ʈK,Y2.2y= J!kA\ +`LtLT\٘%9R!>ʜ9sKLӽEٳ\@rᥤ|HtY'%+mEATN:BfиqcT{}B$@C9-@6jL].]:Xv޽ƍ#gųpg"= +ڴiHp3'iFֻ>q<٘4&xq.SnӦ > 1  t,cTuM>?xloDS-Q%!CTZ }M5oޜ߱N#Ԯ]C'=蕟HD`"ܰ3ϺwђÇ"`"ҕG4G7̙ޑ9W>bZ +RX|>9qZX'31 "#UIc9"s:t۶m +O2ӧ652ߏ`V'ɓ_~/AmQ)约Q%JP21ˆTm`'nBl H4cʔ)xg@:-КlRJ 2ОCS;2G̙3X^ȓ'auj ƀ5* ,wh3u:1NYre+ +B.]ѣGh lAlE$>Ii:.\0ў 6l.ԨQcڵ +޽;7WyM{6lذaƷ&aÆ 6ٰaÆ 6ٰaÆ 6ٰaÆ 6ٰaÆ 6ٰaÆ 6ٰaÆ 6ٰaÆ 6ٰaÆ 6ٰaÆ 6ٰaÆ 6ٰaÆ lذaÆ lذaÆ!&7n6mګW*T0|poZ9]v ڷo߫ڻwT2iҤcFUV];w8p={~zUVp +8y򤿿͛K>~/G[xK.r"Dٳʕ+~h͛yiٲeLn*7ŋWfM.D}?~xڵo߾mԨۚ܁VZI AѣGsp%JpQL8qoߦ_ 5f̘޽{?}(Sx?#G& +(/I0pر-ZӇ_bׯ__|yΜ9>޽[C]X1__G+W'LL)o޼AH;vY#Fh׮]ǎFŋ=WX6jԨ\4lXQHm۶ 4(UT(E50{l|W^[6_ijgjժE.8}Ō32fXn]Qذa+hԨQKl2ZСC ‚JhsÆ K81&MDM,B3hҤ ݠAB_:oB/^j͛W̼xʔ)HGwN@t֍ +=ZÇDmڴ5j 0^]zB=w_dIQ$QP!35x} +,h4]X~'iҤǿu)_<0wYԩ?Bϟ?k-J<uٵkW߾}7_"ښ|k3/wjҥ 7+VHsϟ_B^U`)2G\:F5.bĈbBEDΚ5~`` rqƹ]mSO\1sLjSNm۶ UT$wgϞtĿp,S  +G< $OѣO>[l觟~BXGHP 䒐!'NaqtA .D&LT -Zf;Qː!of3&:W ,>|ٍc4$ 4>e+V,k"la[M:… X-BoߞqZ7h/]$w+TuWj@fh/mڴd$n—+VFĵ{Ua0aLͣD*EPre ׍75гnr5ck!"A!Ȧyj=;\pׯ'eRe—M9ʜ9sDx\棉SSiIDz4?{D% ɍ9R 'pºHňz# OLݻǷn}= :4_|H7w +ɸ[t(7%J8zoҥݫ 쁋#G@i7oެR|!u@G2B,^1E`۶m늞o6 H¤s*9ulItTbPC1'N7}HKM rEq=zz8ˉYf})b0{1׀ο4.Xf HH+1O<9cƌիW jRZjߟ>}:d4k +P)28D+#,D At]8LB +C r +1EOܹCmtȖ{re z2S;ב#GҌ"Px1M=D{ė$Irh$)S&.a:`.Ǐ'5 +&Y!={dܵkWQLj/͍h_53gP&|$Bhm|8O6TLAb F1B&T!iҤf  Y O4Clٲx@ީS|r,Yt&vAW\ѯ ʒЌrLb:|J|[p!aI`WN!p:U!x-#?狞O˓N ,)(QdΜIID$yݴiup!UbnGWrnݺ?[؍7h▟g'N N$ΝrLnʔ)9aw#<9d)IRS8(Y$ON:˖-SK{ eʔHk׮9>:U!tb|̌NJIe(IJƍ&3SߗVZ 2SWfΜIjѵ_6l@+YEp9BڥHŴ=![l0ѣ,T9|UTIއqÇw?Q;uMD]!Zo?OFKJD]@*;>I12Է 9#9NHhz8~4d"Hdw2մk}UիP7}fͺ>\I)G͘ŋ52kWh#%kxH۶mYirr%HU E_N}v Sa\tBlkV8M9cǎ 6 n38p nYcXz5UX*ϑ&:.ܞ)RK-G&Dߣ<nݺ%cnc5*{r֭l "PE5e""rp>$Crb =aS/!,4\%N8"DdhTdA(˗JAyx8M5Dy.{mٲS;nTWAC09\7hР1cY:[nC ]S"ApoIs{t+%ҿTRn?pѣ=zx@q+;wvoK'oxݻ26j}|?UWׯwS#^6rTp#.]* +RѣGUݬ;w0J.=aُT=8I>ԭ[T-n +G† 7Z-[;v rEM_p2g +"Ǘ:r`}0e˖[gjk{mfnlLS`AYOF;qEEgH|BmAs[Y=l%c6NB;jӧ[׀(-xMܓƐ!C^R3'$xHQ3dgk׮}H^4>|l]{@I~>dz!^gرcӤI4ƍn"hDtpNaիWAᄼGL[`` cѠA8@U+`T")-;K5NHkFY4-1(wUj]&![cӦMk9=,wFK5ZhAw!Fzn2S/_>Yضm>DnA8"\rEs{Lĉ)AɓGء D{ r|*ZhJu \c.Z>I…; Vq.]ѤIݻ:Z5d~Jh:]6ES#\_ܷzJϡ-X""Eܱ^Ȑ!$ٯԫWo$M4 +;|ݻwC]V-+;vh[֭{ Vx4T0COwhi {QX'L +ҧOO1/S8|ȑ۷oCƵ&L;udfb0Ή*"uN6LaF+ i@СCkxΝmرc+7#[C1bDpݞy} +LV"D=ў1\5}7l`EY2!IVd*ymQA9s dfθLγtb͛72d߬Y3du|zLid߆NUj*㎽'O$H X96StB/^߉9j j׮&Gr'Zt୒ŷˑ#sl %b"E2^TRLԌH0Z{i>_p %Q"OA?KcgĞvs-6qեKF)@dlKrضm`P=zqTW,^XD'|'N =ztخW^nis_C;$lO^='ܹsJ*4^?X90rʽ{M6^|Y&JK(a~W{:&CL<҂N:%M&LPpoR'.4}tF~\.Q3G8-ݮPNP]k׮+WPyԂ͛[UKKueINii<<wr\cҤIҥS2^$޾}۱c7n`o-hrS nݺW=>QDh;A/_ފG< o.o0,=y!C„ =Q.\K7o;FyנAkTvm,ǫ:z&,CY=*|҈):@u~~~$ajO RoM8~)hժz1M43I{QD!G|zM0 +eYɕ+yѺn@մ.ջsC{ə/ۨQCZzM R5Pƍ-=ݻwhXֺgϞϟ?_|g-~zāgNvVu:p`Q[l>}:ȑ#yZʔ);e:[nӦMVdB̙3ٞ':u,Y=z{ͺ9lٲE/B8q8S ZZj_N6͛ע"TP*D7X|[gטx5XZkӦM-"$zaizTO%M +b7hѢUPktElz6lhLӞ 6lذG lذaÆM{6lذaÆM{6lذaÆM{6lذaÆM{6lذaÆM{6lذaÆM{6lذaÆM{6lذaÆM{6lذaƗ#6lذa%Kz0l04ݿgϞ?)S~]v"&MZ5.:ѣW޽{ >|(7VڠA… F-[ٳƍT0wtuo\|YެDb0j3F$H)y+;֥KyQ"E(N&M:xʕ+y1;w̙7Wu=/ʕ+)?={UԩSR%o3طoߌ3ɓGPBAK7q;W4,Xׯ؎ >nڴ=B+T]tj5oj׮Mŋ~ˢ/^ 3g(PwW\Y|yذa;t5kVz>9aJ3ӧO߾}D9r˗5kּxbȑն$b'bĈn݂reEg}Q2i$QOޜr-[߿_yo:V?~~>РAƍu02eЌׯ9rPNpˇx=']VVH"/^0ݻtÇtرc$Iݻ7eʔqQRN12:J*7&Vu 2z]x_:t` & "aÆrgѢED!FDjժ#Hܼysٲe~.Wȳa*ѣG Dʑ9sf^k<˶hBm[2eaĉ =Σ 4?SvOcb$hi޼ynpח"Qp-EǏ…yJ. +Uرĉs!h޾}F˖-JpСyURTΒBɒ% a"ڪ`bŊϯ + +'ꑄɝcfPZڻw v# :PK" Ξ=k#H,ݻtW^mڴ)@&+tɘ)Sy%,ZG\ qj 2$GV3nܸLw>#yJVFݫW/TYs5Fpzҥ+=,o߾D QiJʎG,ޛ7o{'O&{Ejix BQ|7G$QH<+R׮]+Y͹Qʝ;wӧ>} {. "'- +5H dЏBQ-F jC + +N%)R$C CjDrgȑ$*Ue2 +oܸ!J_ OZoxuF$PR֘: zjTAuV0a(IVM48q"6UP NWre=D2k,TF_UVM"Ao!S_n8p[n̙nWG79sBoN\`8c*6D1'O<{ .&Bf%Ih xapm6(K¿#XCE:ա% <2?,ңGxiRN>h֬/ÑHȓP +_IA4_DZcdPdS__S"OȀ&@ +A!XB-q\ vɢaSbM݉ʕCwjiS YꕪmٲgϞ A!Q5B{đ"+:!C׬S#%uMVGҌ֤ _ 4S]$F] 0hlΝM]ܸqa&.\(YbB5k(K8p ;:  RX:Koe 4Z`J_ D$1׹sg&|ܹӧoܸ;L,Y|9Io+tb5^">`AziSX1c$#d0pM…*̘b2#סC{]2Ξ='Nr$hGhݺiӦj:~!*D*E\29t]vѰPZ ?ۆѭÇ'N()K{u%lڴVZ(qIЩbܸq;v %K\vMܕ??~LUTW 櫤4Xݺu ?U$'v !9W:tHNyJ9e@U1qΐ!|u֭Sn#|4hF}v8pذaMD"Yf-TM_B/^6mڨRuƏcdž!Pߟ=!cW\! ~ԛ7oVC׮] _^޽{7VRma>ب}˖-Džt"7Inʄ Ryy扣#GҥKg ۛTRndTLqA.wϟ?… xBQ!C{fൕBC('O}$j gg.2 IEc]x1VX\ HիW/'ț7I+aYJmܹsǘ90ԨQ#ɤؗ$yG-^>?ItLؑ)X('bE&1E3f4fGMɚ#d5([ܹG+թ/B֮]۽x%JT`AznvFb-_\*4i@OFZⱔECI& >|$I:ٴi-[ܻwoݺuٳg7X8 #мzJOe/j g9s2/Ax>weCCN +[ 󥃤RDmׯ㙛7ok)# =>>>^^^S(Jr$F3QuP, +ϡjJe0k޾})3O9E2 ܛCP=C5G}2g\$s7A #VGɞy2C~ߚ|> a̘Zi)R$Y͜9sRr{h)S&pI S$@ؙN{h<0E"b{ʷWA%J 9: %#t{;<:_=M! XHnaAd֭(&_͘1"$̩Z+ !N:)\y߰aÒ%KN8qСƟ͵dK2cJ֭\F&WV=cÇi@ke2 &Md>Qt [^*:ex&J @S;իWC j +2ej@hٛ>}:ʒ򭾼E $>! sPo0<@QPMڵڂUY S{V2!1iCΗ,YܛO7D]L'OtѸqi&ľ ԦH)SO9ȑ#ɊYf6BתU믿X"rZ +pftײlj)9j > dڶmN nܸ+rQ}(Q"G$bxy8'r +*AJq8={D,ܾygϞP/*(>kܸK**{2fXZ5$w1"݊+ `[dBiQ#xl۶mq^2~_\xJ$qㆾ0MUZI Ȓ%KϞ=I1I6 jp$KiŴ{'F}ڻ}6˗״;ޮ_^z-Z6d.1c4kL0bήT͵pBck=2ѶhѢpɂ 97`yV9Rxܸq5kTuZ߿p*#Km׮]T~.P rd>GjQEt|Me}1r߿'BY:uT3=J{W՛ 6Ě壒q պp[׏`7 (E۠I_/qh+{~Ѓ@lxbTiܹ& I2KzJPy%&"`rrBh +TG_xAU5B[aY9k&g5sʌSʂ8pQ0hwC Lw|B X"RNЎ@D'+&0K#]{/_>+N~X#HA?zW 9S!֭[GЫW/D7nXe4 m'مu#T *D)Қ3ӱSTgPbBm, ,c1el#j,eL/#c/ il2*| ߚ~~\ϙs|9>wl-N^}nQz!d|ayӂa"""puIZG%,/N3R +t„ Y7nqyלrr+Wn|ep@N6lH&EzÂt5nj|||n::rnOzK^R`M4!Y{SLI8tm_~4D=rSD&rq5yGQS **CgϞЯ79Ú18 ]sB%&&ʎ'|ҡC\ ؗ/_X-Z8s挸 k^bŊ12:,((hw H$SrTGL>}ԨQW^V… MY1$ +=vX#M!gϞS /_e.ټy3h+sa|Z7Ġ}Hds7 'KzjVQt٣= Zd G˜$\'Fh1L]Roٲ%^ܡwרQCu2+22ҹ:u꠷ -C +(c0r'R9~lXczz >;mv(c9TRs{{z{̘1m7B8pI.6mD4f̘ap?4I-o޼&MHÇPWiCw( M9ի7!zYyiӦQDʫFkG;>uTBBs=o{C5~8'}J#/ aA#)b#Wtʕ1]6'=zχ  tt D>L'^sYf2e8qP@Vͭm6Xrr=ߝ{㾥=BP(RAmBP() +BP( +ҞBP(J{ +BP() +BP( +ҞBP(J{ +BP() +BP( +!6BPxǏ߿oJfϞ%%%5o\/_aÆuٹ?>22244T^_RdɡC6j<lٲK>}|Ǎ&o3Y`soTS\reÆ ۶m[jj g^~}Ȓ%KTTT…Zrrŋnj9sfp,_ATX#GN<9W\ϗPlِouA & -Z |tjӦM##XoI0k*0,wMgB/^7oCXI&}Ǘ.]L217ԩ'|b^ܹ`}%K={vyKԳ>kÇ385kԭ[駟&iLJk:ƍSL=z4^uEoZb@yޤԩ3L{A)ٛ7oش^*U6oLnٲ婧2zW^Сm^^hO'z[v~uVʢDD9:Df vڋ/矿Kg͚RreM޽Ӎk'ܹ311Dss{ <N$ !TVRJQUĉFJ9wߗ_~Y@R /@֦6mʠmݺ5+WH"F^mz" uVZ$t{Ϟ=wށk#OӑEm}і 6n(3f̀FĻ 2~xKҁ'˗7UD.]ju>}jg*zCAZwy(P :Ξ=[n:~DD _&1- Ey5kִޫ Q˖-3k:O<ח3gܰaCѢE7|ӨQ_~Gʕ+K,B{QQQ!N dQ!WUzu܉>hZj_5){G3gn ~GhGF)q@V͘1U *#⑨KA>a(,MͲ81[lXUrOFi%KDMIsw _.fjs#}#PR"R%f{ +}EJի,1m2&vS ZɎY;zdgAo4dȐGJwwiԩ#G|Gf;c'޽{+VtK,5j +OfqPk H)'OnZ5wsMH?ŋ7HHdH&w0r #4Hz4u/1bgFN +gB0.MqZ&MB.#t>i@3lP͛7eX@ʐtCeMeܸq Tj%v)C8CگLS?o׭['+"2%n\pf<2ulXd "+F榩"V&bꉎۿ>}֨@9"FB)WiUhh֒QFP$ ؆ ٜ9s]ԅ?pXj{Q5~BX@ +(ZCDpۦ&P{VREvƒ${ + >冴;v,.ݳ@ˣE+&`ݺuǏܬ\2+HȨr꯿TMiƪURk<roLۻkSLqSţzd|FW~͛7=dguMjûlݺ@ǵ0V (`IҥK޽di&9-W֭lS<#Ԏt M"K, jٳ|7ʕ+'Yۣh0HNNqip˜ӧܠA+e˖EO:e! .6.MOH~˽b{~tj*=!668!$ Ǯ;w tE* ](8pmgZl0a&;͚5[bptŋ'NH~#I2 - 6ݛ9ArjWO`)Dne:?~;7F *TV-<+j׮m i~+M-“ qƑEDjȑ=z!{TZ DqY!Wf# S[aˢE>Cٙ%*O7D30)g"M~0o΀Fmj\:䂬( +y'$$<LԬY1N6 aAG(Ç y9s&܀Ξ=;l +ZQs̢rB$'SP`ݼy3RDv휘I l_kڴ):KFH%ek˼2 &$ZH=5Gc9 ,[GFFRlt̉ tzySvOV9Z9rdȐꄅ5j;w̛7/uRA-9h͚5FقFa!\CrWq:ǥ .**J/`(Y,2Ε\z:522zFM!t / +({+6N\{O +Vsܰ5e4;ƍllٌyoӞ!ADD&:t  W^uNd֌̙3{>8}Csx4vZῐG3wTz7QdI9q09F^C޼y}}}<2avv8y.bxm .7X+W:QXQti߀{О'.F:#Yf'bbb-rBϟiџ)S&M8]1cxsfX0l6}Wrr :q̙rNw}W\u:Qg1K3n8]HFGp+$wN%K v {2yws885Jf_0&Ν{q_>wСs9TDTTT޽i4/_laF`РA#F| ͿmڴٷoƍN +'N@]paĉBCC\'%4\X"\ޭ[R˗/ + + + yJ{ +B/ƒ +BPS( +BiOP( +=BP( +BPS( +BiOP( +=BP( +BPS( +BiOP( +=BP() +BP( +ҞBP(J{ +BP() +BP( +ҞBP(J{ +BP() +BP( +ҞBP( +B +endstream +endobj +366 0 obj +<> +stream +xڽYK7 W zjHDi6@{ Μ9ɑf{!z7חK™F>,gr>C"p&e]6J(Jo7*%vFȂDoIFt/O]@ 6DW`rL!Âcv +꾓𶄒ʭt7%ռ{_ܜsS(? +tVݷ !r0?hEN + ˿s/ޟ,&'gty|P +<@Q7mYԜ `e;Xfm +*L淜ÚFg&R1Kbg1%(vTd S+78ĪRGI$I2MIV(l2#r"K*TUҬI"XLKCn'¿M-ZKeR!=Ƿ}`q0d]s>RV'IŦjLM3[/d]Hġ\LG \URG3fPڥMċVXQYGL`Y(:=|TMGY(s=6vņ%z0RFx).NֳV :w6j<^V j\xF6MJE!O^ZԳKc vicO78sv>}4u0ͻb ʊEa[cIRc E! O"|zPIo@æPf`4 sS) X/ewRt/iMSyRͶ^JX+yWl Ul6jƁ_WmɒC6( )ti +#kj#0u4j؀F$NB)ڣÕ OwWVcߵ 01f+ݘ2etoGIGQɺtiYE$_[UnyJz6 Vj ]&^` 5<0< ՕyՆӵ\mKg_Uq铠*šĽܺG,:t5Ez_vx89un=sԞzԘS*[7WB,Z~ܘC \)K72 l2Gz%٥]Iؐjai<<[BNP<3߼0$C&7yu`7vmszYQo5&^7E?5*Nz ܥzob"P"Ü +endstream +endobj +379 0 obj +<> +stream +xڭZ;c +RH0\.b}VHQtDQ|~MfŐU~l߾ +AT`vQ]`,fu4Zߣ[Ɠ=b+#.vP{֕D!̛5{X0Y$&ZJe3+0@ueH\9-lxpY5 'A<>AQzRU8 ϓyt0gq\!',fC=MQmG T|Lzcǫg^V&=(Fpv2$ʷee\+c-bV랍LL@ +ls1 )$̫-vz }wt˷8z h!w(vن,cfTW('Ê.ƩxQ(s)+UYFK UYbS)198R̄RE^aNM1DDY~OG,n)xh,OHpbtV9%MC5Fs79ӌ?01lv4HAљFY;,2JiZ^E3T=bwC-8X9(k5=F @GH5ޤj69FygK=ظbRr[xՙEt'f5rw$EJqm0!( O>Jzr2XxE5bHWjj%bT(\Q{i(!,/څR±AG=8s>NB~붺nRh[UF;%)PDzy$ةa8D [d'#^Rh7*S(i JYlK֎+jKI>I53$}r^ٍ +  zH5^׿q5DY;Uԓ|< +Q8Pm΢i8V4pwcEUĘbv&p6qN j\4϶ҋF >>hpWY*$Jլ$DnDDZse&CVdR}\Ak}9NzȺs> 6=B9HWVx肭4aI:Uʙ'!4P/8Njy]~s$+*ҧӫ(n9ŝn]:*8-ЁldTI3HL㗡#p36:I5K*87yjVV';FX1i wa9( Z<Zo +Y%rpE>6}8%.QLrKtq!7V7Tpi6 XZHSziƢ\jN6z:\wBs06s>1Yzlb O*:!- DFz|q:ա.Nce <}EOHz/Lx8d~QkZ:3q1YU3dI_sY&^GMK;#3NӾɘw&Gܷl5N_CU&(96lR@6JWgƽ/E/$+L]T=B%=|hTvIYՓ{3w u9xkG'WݢG&ֶw鈰# dc)R/M*Vo`|.R[nKfw-4zme5)ɓG+8܏#x N%6ᒶّiWiDKf*,a0cy'|S w4#ٓ22*ʼ|s\G 6 w-gޖ΄y}'rgNjXk_I%|+K>)w$|J̕NVr%G"e]\ *;hc7Q%p*@K8BkFqWoAc8iN1u8csd_|&$%*"?0PHd_N6+ӯ[)]BY}ʖ X`٬9j +0PB(5ePe +v ^]SlyPn! HIZK(cKOY.Q xoՍ3q99qZx_þ7sf͞{Tȫ&?7esAi?6(rCBjɛ/(UՇxMf VE-T2˓Ejgdj& +*_qnrzH&CItte; +2> ļޑ4h^˵q1J*4*r$vK)]Zp0<3O73^sK4{◑ +`\+.QxV;ׯ.[Cl^THU',Mtp=U'c_?&: +endstream +endobj +385 0 obj +<> +stream +xڥZ;#7Wtxl@P`phY/٢06V,ֻms[[ɻ/nsx~<<;S~bmحM|ŹF[7K,Zb9ۛiGn7xۏ9ិ؞ o!xF(R}61_COWx5WcR{.Axz3|w5w m'YgEDM1aw$1,j_ug*$/ľyCS*|UŨXT8cQ79ܽ0WoxzڐMk(re%BNk;dc';EuDc{keWsm*w `FW *&v#8Ow_rw25c0ZC`@n|YgrH(l $ʶх]}g{sM.d^h +rpT(J^G P $bPjA k:J2;:'YJ6zp2c,C8#E9 =٦`={6[&гGuobE?UQ&&gx1IW_Oc䌑h\ gp\R6Gq}zؙIij# ,s8'&nRdwz`J|@]Ƽ߱ CLr Q-9e#۲Ů,#"kki61cQ!/B~YJ1{rKJ b)xN&X:RJDEzr*vSu>E<*SbkmPOTGCRXo[C&zHJƦ;:.O]7 2SJ&t%KTjYXVn#_5p|Jj&vRʊVҺ*hH㒺^rz>_4gH"4qtN&WHPj>˪BJf[2ЉR{"AqpSG3<]J*D$1sYGb$NIUmIv#-PiW/tQhPSu^B*ۈ^'TG+$;q{DX=ӼOc)fS Z]~-S!L4уcn +qH+H3t+N2nR΂ +"1;?L>=eOB@!@s&zpna$Rӹ¢x_N-7>6㾗Xͮc7JAPSN +5eS_[Oi4I4ːh_6YzԮ3kgzn ,0gTϙ޻rd'pFݫ}PC-WP +dj1&qBG$?҂R,.FsX XmwrH}]hIȬ 雞$)q9ߣY(r G hfw2%O @ ;<}\ƾwd18 +c0SJuvkxi^@|oMfb~{sPX~lmWlg|o\)Fz6$^~Xݴj|8r+`~@2Vy(`j`NpU<܉* `R>nLuLkO+2eQ "*o9uzb;2ݡzs[rG󣶡2"塀QJZhe}jt)lh{,<9a԰йTSޠw=[j)dm66Y~ %5!6Q)&svt+zF |9~f83/hm/\"^c\G$3> +stream +xڥX9o6+T&*` RxWO]7v6`+Qpw?XJֺ-_ޖ 5gH۱@Y岕u\)U<=q8_o# X_XJL '\%BOȆH ^2Kw1>:q e,.TYngg`J7Yj7BE:^>MW.d&iWD(BGwWuR Dˎ^DfiJ~ +{B^C̝D;rU'DDUُ&n ++"F9Ÿ#or Aaә&iP4vs@1ۮ# .ٓhO:7Ƀ6s5ǖ;q`dFI1]QW35y;5CU~B_r:g}='QT}*Y#(?dm\oJ%ڳU㣧 +[Ep?K,nvA!q=gX |il9Xu cLx޻Bp. )h9_М jC4ˡwwɉ}LN-q&U0OU00ufص  ŌP`2 u$Ƹ{*Y#@{\]w5Hk^E TH6b`ǘ)ni|3*S՗pB!sl W@wB4Iw[hh\oRizFl>hoاNlĸ)+S{V.\sly=[OD?bk LBumWXZD6-XeR.`mKwѬ;.d5rwa%cle ze+꩹FYm/VzJnHqFwkqNe(PQ(n{Od\~ݠP  m7W rơk5$_z){CG#@XCI?ӣiZ ]?p%s\>C/F2~ kh5?2ـIc^E9A?}*X&Վ[#[UhA W‡7^i[Q!; ZvmR]h4'cg2ʮp&5f4zZyp>4i6 p pk߿>Nj^W3UhZc5swqiMTIIX aH箳W[U`(vȚ>`ϓHަ |"nm +endstream +endobj +435 0 obj +<> +stream +xڵZ=45 KŅ|H+CQsvۉL2;^ޝN?7uO݂DLo?~Uݴkw{tZK +"%{{x+)mҩ79Hxޥr.^LY`y`-moFJ۟~yAR"9{%WlA?E[e{21$'$jcݛt2䙕b5'a@5=[&=K/}VhrQ5(l+Ƒ6L`B@%$ [4J\1,4dݬ!Ʋ͝; ֌io=G9" f+i) P^U=,>t⣜_vN(2\[VxVY})H`K/Bk^PQQ^E) #W$Q$ Kt$#=|g}"hEbs좆d{e6jd j]  "0br-]o>DzN/ C*'lrN7z82\Xaldk+LߞqklmPotl,jC (8"[s6u$)b"x^^[kDNf6!ӱlʅʀZ+VE@{@Pu2qNxZDQI2>Y'gVYB +)Iҙ$d ܧ$EsEk)CbJ9E[8O?R/1d!'zXL) !Y7m}G *"q/a#1^حLkH:7 LYql$uN-z+@9O+އ;ZrSTKfuYvEV"7]o +vu (|m:r@[%(a$F$_ע +‚BO+}R2ƗGr=w p :- ?1$V 05g+A8+Kv?嘅;$pgZ"T?jBSDӈB 3Ӻ֧^z}0)V_;x;`P; @FDryd|5/51bU@)^Uq[8E:_E@pʟJ::{p8Ҽ(`~cڪbl0A Ozlb\Sf*XyOhUFW L&G=u-4P-3눽$<8k?#0Oy0O8vE֡a_m .Ȣ JW@ 1[ť|cLzLGx~@ILM>y]C)q +H @ifXu[%85]Z)O*^yrjv:6CI j=Xzari^oxy̔8kg1j¹466ohU-?{_1<6Tydb]tg3$~C|~G̣gl@Y*}c\Wݷ2x7º8Lv^[kcwJ*N|<^]M-ooc+LPC1T|5wS~0p󋦀Cˊ]|yشJCXşJ.CgF<+Dy-}QjR9ئ5 kY Vj=IH5AHlߏRk6W wT}SkWT14A{L| V-22pܴ]|rha05f(i)V!zhMJ=eL@+/sC 뇣~qd\BJ~z@i:\^uce0#|s|􃹊UV8?-gA1l?Mc:xHc8tzyt + ߇Uv"0G{GecJ&x'>N ڋۙ4\/;:oh~:r{Lˮ/_{>L`G>fC<+J@X e3Hx!)gQ2 +S +fiŚ+4gZKaIPcʨ}qأS7068Z0M~5H6)~Ǔ)/6󴦌dwoZ5ܶ)HV~0_VfPf" [**s%"ܠHi> +stream +xڝ[;k +TIqz?E˦.E>DIGGږHJ!s${I\.UBMwa\~kƟ=?(}69W_W BWmYFa>x%ʫ˸,|V8rDNo,  nl4y;lr +:kZ8`7TŨ;rJQڭ6Zp0;wLRE }R.JL=. Gi"|:2 D n06N(X>[*6h6}ęGqMӨwKQߝ98̘") 6;#)eD,5TE7z){16ġσ5u@( qEFҍGc`!+Q1j%< +QYS8` 2$-բD s4'j\ˏkGks*5f _QiwXN1"6l}Y]qĉi{ګD14gCe +yu*Y>x1ުPB+itmq\ɸ섧g'G4B!`C) ~'Z8tȭ[\D!]Hl69h/׺{>WIx-#+{EԼ7In;F{őT}TqMNI<. w ZڅUS=@t`^=$R,FpܤY[eJA1Jq!$ X5Ak"RxңL8yWom:],6q'72Ƅ(lu:cmq"T%SPܐ(Cud$i)92e,~㘕{xjhL(&GmYbznuB?HJ +!8nkB@&y`WEkj^oUܬ`5Q1H̳ ?fi5AAx3ICCEP +9mâǰw4*[SΙ[F`2Nj#&+YYyFL^#['H}$zfK&!'҃6b]R> <j%ڴFoo1,tq1NǵL#-hzz +RŘ.b.u1Dq5>X[D6, +[L +rQT:"0dfR 0i*1 +&嬓~#,( + Y_Ww4WsIAf&ww-TgsVK,8jc\UC2M`.fGmB +JȀ}0..Pb#ިY(V2?Ͻb"Yjzq؁Bsp6eGyU#p68ŠpTYT5c/ j|I!~ύ(!>VeWn(vᙱ9`Ŕan2Wlķ\5P'1¤ nr[J):8$9}!@spN1uo̢Q1V&g4od=uyzuPH B9TvȱizY=D)VP4$A?I'`p~KNO+1vl*[Iw XE͎ZLR]{7D W:ԟd{ԂĘx*o=ii0@Cn6vmr%!D]>I} #I ng(.35WLLoI["R0fž1VU|6OڋBޒ*Ѭ$mK؟:i `1a[ eAk#Z=D;Wft ;1+Z@U+tS7OV}14lDu͡I[)_'@[LA3[| D{2yx~sgD{6fzzr?nv04Gp&iQTrWѹLy)gGgOYĆ́lB\,ʟeP9-p*g]I17"SO6تh˙<6Jw`pg.*xZ/h0H'v +UE&Y ~eLM#jgkn:ʓgn:ITX*ސU,m= ܅$AWSعVIE_r OCu8qlB,eNpov(zSX~JB.(*_jWp*tVRB^2Pq5K*3/r}z!CE0Q_xzo]Q?V<8G OۂP76bmVn˼Vi,7SsǖoCmsoQq-n`B^lR7[lT#EN!Mm/"rq @ +=ճDWSIP- @:ړ3m)Y(ړĕ0S$pI6] t=Rgv}L7ցjayS1%iDc\jqmcOZew}|sÖ( kt> +stream +xZn+9WR/^x׋͐")Q㾸HY%QGO=?*Trj;}u)-NoS([>\~Bw.^9\?NzcR +$8zm(-vd*[e?p-_Bj-">NkL[+/%x!/j=bKvL/'7oP7'}E̡CdGF4óXx$wx>5*npaE͖~f5ه&$DC;NWeF_-PrjH~+pB@Ȕe>lK%uuc{|ԌcKͲڜ_ƔleR'] +qPǀ3@74;=ӊ[>SU>Vc4QL#u$$֯O.nzE61C84=ydEP*j-{pƔc@l + r$Or3t +-<ڐU!0G͐lkHUQhU= ;7+)apӲDrͻ&$u^*>iӔC2ț$RYe'I[Uz%[&S[WԗHA*=H!B0q̀̾r!9vs 0G'_Gi'۸Q Xx:R%#ow`$n$niԃ +HqQch}jmlz2e-#0ң% ʹC o_rSIK[ji0fHY%;~[@n8C0L +]neG"a$b 5 u6Z4tp"iTsabͅ?Ez6o9 IJ)c K[h r'!ȿ W~&"ّSq? l#*38L' l1!y MINNwP;zG܎w"F{F+c +@3$_2}2Y"KDH5ag)?TQGJ:RI^ F\0@ :mRx'/}KNf6 Jc|Qkr8xCc݅)<+/ ~YΣ`z(W|cJp&|D EMZ +|\nk˜Cf#RgUPvg6 --0iatw#lsD|wS hڔ!B  칺ĔgHVӁ,tO"\Mi%QO|f)2YBPUG=rG[ҶA;̘ )Er"ԧ6n*[5ЮeG3l"{lvsT{PQvmeE,Ձbܣh ':=kox(HmRɃ'b9L}EO&iX1m3Svcx¹ ə)rZ֣lPnJ&wjO\*7wW&ٿU%;DNWrtϡle:Ϲn$١Ўޯ4آ7Wcx*{>T" +w7h?.^U)*5zJٳ~n))(WO^FqaQ|3-J/ h > +stream +xڵY8+Z#QoQ;dtؠ C^Að)"٧;e8TM_~~NΙ#')N_Z ?N7 w|ÇoH#k>y-oA ,._(ɲe*pZT+utqY6 vbts +xm[ ^b:x0dڎ:\#} Dǡ֡6~gOT@%-%O>GQyOn*EVz]*BgCW@,l1 s8QPmsEL2~Yp!@"_e J٩DC<h?h@b=g4.& oԬur=$D}AICnDm:@&@޸PA\exOAPLڝޠztHtУ~3i慿=3ǾڗR!Yw-T|_ ̵i-To^=M6nxxAEK\?QN}ht [tpv>jgAJȻWM',D/=cntH"H&)51^6N•u1e;v-RMS\Q3.0chMڢݕGlGjUмϨ*&>V"iP}$נ' 2R>8yr-e;:m%o`4HMR.iN$RdG9@f#Q;1"N +JBv6 *㣝ȘZcȑl.|毃?GYG. ]\GKkx ?H]3u;W5 w@]mcb` EcT^UlѲǴXQf$C ֿz%)KJ١KzY}cIGy@&5K)[ly5w_- klwU GސFg魐H+$1DEzۤ +םVMkAIyܼΡG}k9jgV ja2]c68j$xٗ?X'Kr,ǜԮw|}1'{e..'#*rݮ0&_w;>Дls@MZ⽾s6N+a6Y3v"v.e]}V؍uc'/MoSOfOpo"6bk7`ɀ`c=ԪkԪGr7olGuUbç)bv'b7}7XPk E'*Sz{z{$2vt?Sk^3UqAQiKċBBws˫EYIK~낇OּLxyES㪌Q0ƍ@Ia^ +endstream +endobj +310 0 obj +<> +stream +x]m[~ +;:Ew b$ ,莭Ό4Ћί确t)q +HCwñ:wb:W:k^}5t>.DNRS쬑.W<_4ob'6Wɝh$'k08сqxLql/38<<TXtӖ] T9sɁOx}ǝM_9s90`9ӂR`;`2Zy&amz4a `dG[&وɜa2NpT8t>vHƼ ׄ OS&fX z4ʦc@/:RXx!:ԡ;@%Ϧ"KId Q K#B ?AXbЅJ[rs- v  +%nLY@-E'=A= u !sPw؆$;hxbk10VxjQ:_ he>L -3< e=vXHGpA.Ec`,eAS5q ؀R{|| yZ%h&>R?߭Wg7C`y_[|`v AK>Šx7_֫_4f/޿7\-j=?kgg-OE{@0lU` |(t΃W)Vxզ,Tf^ (I`(rm;~\%#VP-Va'FS zKO[z}B>(El#lψ +R^GVF'wTnKr݁8~Ϣ*Y`^Hgp : ?ȠT@+^BzQ~ƒ4ƛ-C1QxTȯWGpʔ`Xin XU>QFEl!.DQR zTܰKz0S?4=P! 7P X(V'E' ^% |>enO"|Q d XM!CzъYc&a: ɋ\OZL+tߘuxʹDp2 L,akc"ұg"8FC0ikEb Fzs9\ OWxF9=f>R_O} me֜2<8p + +hvtj"9xˉ T Ln#HP<֢A]"CٟS>$*W3sg"ނct#'- < 0!FO/kFJcoGDV136 s<)`g<1AYƒ.䊝 &-,a]q }\bRo|>M7e +,XAmˣqD~09Kh]J U ?sQ,^z7/U8Xc)BVysyK@4 +`\T4љ +Էy1 <n_"X!L@b5gǃ/ZrQ,*p`Qsz.(^2' ZiJX'}$.YE!IT1HpY/##H*%/XM!_ D*RHsMX!8:,hj'Ji”*ܩ@6XxS6~^meHSZm{왡%Hv1- Zzd Mj 誀0kkN*oPH?=րJT9l}S:lO۳~ 6L2y mlƀ + +Y7zO/5_82$q琽l7%(nVے4buI'XրҢ=B ܚ(&"PU2X28*}\꽁:f. PxD8vLi l0|i/P@,R$ecjسg$=$m Xh"xɨϟT#-memiXS*5/QMF +MbI+XtG`-^e ,;SjPI,m KXU1}iag}?վl[o8:Wއx'9gG7(+*\.mDch[{@ârCKD%N+d)o:h X,H4Z 5`U +sKSWXuFDG@V|טw*޶Ԙe/ona+o(_kM4H * o9Z2/jNN t֗sp´Jy[\I{{WZgx!zw0EpÞ] ϝ>X ٶpZݩj8wj\֛jf] z9-jy]]-zvj}QoboYoD~:"W>$iS=iR_mLMpyUV.PXppx7 q_m6q%_^}/VJLJ b=#"R)Bllg[D,(p\BF-ުu?#~(![9d񄷏}Q +>[ֳ0WoVզrB< ^2_g6ú߼Y>̖bbxm^lvכzXq{_/jZo_Fd:7X<@P\O=2FUy!_ӫ{s~|> l\,_V=E me_6gChxh0/زOi(_eǛJ~KOF>YWĉ؇=^ܒ]>~5c?w,7'9T |3GI g3|܇Q8=BZ\B/b6H +)5`c:À>0Czy(c]=م0@Ɨ)ZXBg9jMɕBsXpq![94o8PV=ژY-P$.fn Ւo ٭Fx0TeK,ȒA߽d(dSt@^M1H[nNgW;]s`iTs֒a(gk: lhyȸ Uݒ1Y;)d%?0,>{6'7~ i|9XZb F} uŎǷvz׮鋜0o;Wr_T^8Y2-.3@E'nY_<7}>暙&VTp= /h2sݩ%%rz7Q Ri&)E=bC]wJӂ8[mɎ. }0SmO4>0X4k%T3ʠ:QΪXkVj\~STKaVFܲ^RA-m*J~EezAqCP沠njB}riJ(u:ÖcAUOVCQ_db8% > +stream +xV0 ӉHJE\.vAw)MD=r cmQq6`\4d_TV (;o"-'FKݽ[}B#%z'/Y350:_N5n,Wc|ъp{?84%npWKW{2Tíf>h)bߧA'둒 wG 6=k&e>t*b}Gg!Ftl]8ɋjIo(PEedG(}ZnPXFڐa=eNƤ:{}\ vUXBR{~&$`Km<DFJj}xhΪ6]iUdlLɫ˹ڻWñj8?hPJ ,m}YK k ;ާyrjՄwk\3tUIoV*M.|`=~Pѓ6w!Q6 +⹻}>' +endstream +endobj +554 0 obj +<> +stream +xO&7}T&d:ރ5Z}È`f^IUU5Tg73Lj/%I^tOc~}䚟R]7"=_俞h}oO/_/ӗ$z<sgcƏS;:J,?4K RSo_e|߾\bNZ_|J…s>Ƶ+.ͥ?#^{eӟ/VRp#OK򶵌xt[4 ZӬQ(*0{_u^ʫ/vފSO)u/^yY?Bp~}Qzn[(O'k_*m /QiRe۬)] I~>xr哖|v>ܿKz_WO 't_*_i_~zv׿J ?ȥn^_F#QC|E3e,d /pEz5owb̧FLOo| =0|l4ˀz/kt2kMsJ.ɰ-(ՂYGzoiޥ"]s9Ju\4d ?O}tFiVק©(qnEIJoO$S%SF%J4ERMMOg԰JQ9p(-<|*E cdjWLOE&>R'Rrhĉ$-18ZyY[HŠՙz;Q(]fN#mjF?4.4{R?(M:4m[kU$NthЙbeUc~sEjBhmmVmH=I96RXS='9>4bT^rl[hrlxj)<:c =Y,(ڡ5ΕmftD(6a%v,L"n|hTcM~(9ZmjEkcm O>MZOlʢaĈ"L;4<=țCc[mYIFvh2kMY-WJ(Dǖ+cI|jrK5;hVbm~CzK|$sl͢ $jKTck[s\e> +Ckiژ%6Z8&t+̕nʒ)I=V+R*HM|hѰ6gth2 +Y:u>&8\YE_?5ЦTxTR][ۭ}4,qSZW4M+Z%67ѤWVK2!V{ELmHdBq(nT-K?rHc;hRYY4¡Ԗ2bFlC"I#~&I6V눍W4h|j?-qgZRa ++||E\E#31j94GcqFXQlҢ4\VJC3{H)#njXߍ,ZZ$W2sCL&Cj"ch2BXQlq8f(΢Y8GlH#6^ڈf=4Xū)$cqTW)K[ơL.#_h iwM2sVK7jO !@TP2MdBD&{ rhSx,*CcЦRYX롱< M +X><4!,C]2I܇V|6A/O>&:'[ ,d|hmL& +owN7 BHDІ1J.jߡQGRYh|hUڨs,X'o"s6: ]:)rhxLdMX(4'\Rw`bX(/J)߁Rw`JJIj&mX'JTp6[x ,Zl )I-݉uRu]X'X'IMN,RB UZJǿB ]B)!5Y+CX %XWQC:m-~G,Rl `bX(>s9ab(kʱn"\KXJg@wEڬNc\SloacAeS>K&>C;7²)q-q95pN\grkLTNQ:a:ډO'Zw1c=4)ZN Q)qs(˂خs"[=Ebbˆ(Cf;nuT>jkB9">q#,)rD))v~TSM8RǍOuNq0yƺ*XhzjUL +`U*b˽S +[hK'c ,`p *G', ?lYKweB\fNX{9*G3', r4s X*O3CV`h%X}OVNCaFGdžyG_{t4sB,!h愥8yZb16f^;_rlg"7h1T_TpNueKoO(ر;"_L2/OI&n ~EeUv{Cn 2} "?wAFβ2N:'9uhd8C Fޯ4Mޯh)H#{ ͭn+y\yo'1?#p%ޮJ~M]{+7v [oVP_.qd+#|/ ?Y`-?^,K&neͧ~E|vwŖh-?x7[</|w~X@;5o g7>[9@߮afl{H2q{L"S$}EJ6g`}2y< Ͳ]Mm3Ҍ@ʰ!MPNYn c]*LޞRˣ,qҘƘL ?$C"BhOw;xV)Zf02JQ:~SY =^j+qT2`YIߥnwb; LE %楨4/ +Djb9 "h)i Nm6@"%FuZPPʨ&Wv +!KMYOC:cZ:lW`>}Z-aQȰ"хJR *9$б;J7ԁA CDj [ɣTpt$A @,-N̥ɷ5ٌM1Ta .oO]p"+A9y}iF̶F$ b dl oZR[]:b+^ l9ȉ +DEZf"C +tISˮd)T (:ey݃k~m:}N^ tXiؐS\0PR^T?=n_-3pF[weP &ҚR:}a5&y.qG ].P58Y1xH=JayNƕV1v.mW,3G͎R^kR:IX43oU VhINHVΛH6=NY5d~ 8)[UM꾔|*}IJ^z!QFKp)ooI-MVA ^D< vzXt"O❓o E*--md,nl@. +ph{t; yJ7Yp88gi|i2 &2vlxn 풱M`W^OOJ!t0ݣ^ V{Ìxd{*@}vѻ'L9m`&oAlC!օմ}o+umI'w}ɨ\os@ש}Ծczw|ƍ73n zo89)U#[kټ&v[K|}WFxnxU?^x]kHr[uB V4Iw Sc pBkCϱl'v"CĊ(3qۉlUF,i޶bI-Xuy-Z"9]ۉ'NщسnS+ڰ\V,.e8$5G+vl1C}[X[_NXJb+ʙjb+ʙ[ᠴX'VfzfVGS]DbE}uۋ];Bn%sb[¹XZRc߽XFo3>iho33`'ۅ½f݋Gьmaƻ+bn3V~%^6caύ}PXe]f(,3||3ȷ+bCm6mG9x"-Z8IC; fBKbnaq2SjQ~Om0%!MXyz{"G ,S)8&9~¦-WktSc89W^q潮NU<>v^ A[/xe!3USOlu6r趚mK2]EnBfmtqEB +DD )jn %۶} +|7(+Dyh8Y@s30RnX(x֢} +qܢ} +M:SpPG3t$ +4>(U+QObOr`BCg)3^?sO{ٛ{*ea{}7T37}N?O9>eiO0}.ا~Bo)'Z!uONQSRp~]R4YȄA`(Z~PfCzJj4V/@=>({/?i~F3X-Wo.͖Ϋ؇,ه/6׸v*cj'3jEqIM257*ƙީV,p)0 "qdZ'L1@AA6fFZhFDZBC,fnN>_L+3V8CmVВVf]L+HVi~Z/>Cm?&WlZ6o )l-a㻿1˿)]-G S2-B9ʿ:baOg4^LVf%yj+gY͵dY>-"!SGr jO1,NfGqb8{&Q]"EPE."r_ȗĹY]c i^Fp <ҕdW4Y7ϱ[ԑB9v<=֟v)#JȸgV NOcNK^Ra$W +Y#Jm4Ϗm\8l!ɬؒ0.X'?uDv!#䏞f8ɳd/ȓ篐/Y{)C9x~y +gc`\)=Z"Nh73#߽g4v7Z go85vF6湲)v]kq{.e=[+0-M7Q1,llF"X̍O>We({=ry'͞~嬼۳EGΰw!HĻIeX!+[Qy7{'iXobZ͚ԇt>xkܱ +˖IGV&!rAV!EVU.`>[YZwkS^#&oQ&;e8B<ʠ]m{(U5EA81 Lԛ#Wk-j xOH֚{H Zڷݾ"@T]L&ު5a?!\lZ{f"sɹ2lwiI9v0X "L&{j%[hفj| j[;sRdmP $o-}fCZ{whC \ṄBRB-~ .^hhGG lӽ[|laIj4v%ex:`덐ĵO,*Rv&ݾu2*ZjaE~5z5ܐõ0B +׾<8xkuj&6J5!}W7:Zy["dp-{TA۷}1S(#!lw1[A \nv& \ֹy#] +bC`1R6iy ,`̾WCVm~m*tCF>c{:볦3ɔne6:zu +6Cf$nSceFykC@1F OumeH:f!#Qd.kcA΅*!V<D0-N_-ui 3װt]$Ƞݱ8@t2p0C&u,U}eZe>P:wΪƈuUёU,Mҏ% ;52+[3)ۘȞ Ա>C=*zK0tZRSbf+ z \@5f}qEb3WhAOV]k~Bူ#\5U,dha\cV!:Ú)+{#8Ҡ˴+4)5fȁlSڍIXEf>L}].gUڶ4ɂ0W&vmD6"" o:Xu 9EY"$ RNLTbh2Q/&S ԥL5 j5Qpu&{( *eQ<E!c41볕Q:ќ$!BT,BzXgC:X^kBDjcp`q%sG e=6ˍU{X[GWf 7Q-'VgHˎvN,Τ^₂~"Ts^I~HuD4sU&Vg #~HqvqHF|V/3io S Y4%GpX'c%xce|r2Ts pxyEnɧ 9 0>L^a$d{b o:6)d ]馐,!F`\驌N + ijV:BK0"+4( +M8ՅaU3($m{#汯R@[yH=h)`I +Yz"YZ/2 "SŰ1q"Be[+k{4ۄ!P)Q0ђ/ȥQmE*#߀::Oe8+! + )X RSEf^kfcM.rT)J60tXœZz *|<ȣHy$8y'+W r\0f>Pdj.#&(+daP+T:xN`LIKkAF~7<DQ +s[fu*(6O@K!Xbc9<@0`aX;q!ײ:m *ot. +YayeQYgBKDSa+ L?RUD"J?YN&۪.QUfeۚ`d3X,q[0eT.x/,dӒZC"p'AijDk͘8_Aʍ_<5͗@C6_mـ99J9B:n̺氤3$ 0) cp |9Y"^Ne96^."i̹Ҿ-r!KLr8HOl^V rĹxH/G5 x9ҽ _lɂv\|9XҸrekDW`ȗ#&E3m6Ls0)|hcrD[4ĕfs`,\Z$̥[-<#wc,]Y`C`."[NMKK+\9MD.F9H1. 1GJDć A]9B$/ݐF\Fwy0ɐ0o+7G¼E9Z1o+nj9JD1/պv!X41eNj0oV1ohԥ\ӠD¼,9XHټ"QaN s]20ǜ^9f{"̱`L0gœlsFV s̽ۈ9&tb9jqmc28\-7ʆ1@W_?1K1szΙۣ9}g?9ߜ3yyDK1;b?9RμB׀pD`e&{|P>_O5D?QO~[m?&1[6o'!tޖOՌߘOߔO.ޖO>%DAxϷv٩yuJ߯s~QS9}~=uJ5ϣyԔ>kNGMyԔ>w()}5QSKNGM)}~.t<\qJÕ*DMl@?izМ@?D%Q :~ A?4eЃ !*Dg_g2HΠ2臨 zA?4Q!B?DQ) :~JICTD臨$!*D'q臦,zE?DQa ~h +AtF臨4#t~hJOHaiCT4ziCT=NAtG?Dу8!*~EQyCT=ƣ臨<~:@zҁt2J2t ݮH_P`ve zNAt"H?DE҃H!*~ѐCS$=ΤB釨Pz J?4Q :~XXh]Xzб𓎥ѱt9pǕ +CT0=LL?DQ :~J" 9~JAt2~hL釨d:lP&ÕAt6M?D14w;t$ufa4 7^ֱT^>YZͦcsQͦc ͖b"Δ[1fNtzR%?oӱw̶1tztc'Xtel:pdr t:6vt067C t{٢n60ͦc,)òM䀸87-'|:2U]ol8=#;ϥtۨ3RuXMM]R;}Х]%#Z.8}0yz4#BGhzGhzyh&hNW">v@Mשʼnח-?-4]MLb2?"#2=?'ӵWNt6}l:[r M7mA32=hFߴ 4o҃fTz JI!A[H]r"=jJGMDUL5JG㕎~*}7} #߇!*DǽQiCT;zއw>DQ :}ww;\pwp݇\!cxT!*}tшCS澋>DEqAs⾉oe_s<97w:~~ VjՂ^/m;9˽c r?û5L>YOd_/=0~m +]5Z:-ET>2vūbˆX܀c +6=mؔ4x\<7#4)Za9[iu7 4CSe&N٢} ֵw_ A5gҮ#Lr(a %yl+|h3~!s=(6~f~Xj(` S"6F=tvtvynrV+Y;wǪ>-\Y.iࠌtEp#i<;Gxp.4YH31st`?OӁ~y[D8o4[ſkټ&[K|h}WFxnxU4?^x]4kh@ͻȳEM7`!ͪ47`qz;SfԏL3`> Xhs jl(p آ9@ Olr4`q^e)܀4׺sv(ÀŪz,pˀi"CF0`qNV#885GE@(y{md0g; ׳Tہ+"%?b,i4zw`E&Xdd;<'*>=-X~d`׉Q݂ʼnuNс,v`W 8l`PuF +ۀZ)])Kk0`1ۀ]ˉfp`ߑ%wSv%5=w2n˖s͵,<|_lM= ++N&0Ѵl٠Sh+݀'-(6`c3(f988]FstR˦pFVkl[8^-˶`v5 ie ,6K =XK%M=u.uLXCKGMXKMI{&7a_QуYaK˂n+s;TcDۨh2Nv+J|E-힝`{6^qvfZ+<-gY~m2h1~%^)8Ml=WFݣyX SR+I;鷢Yf[$JVdVig4[`V+ڭVQQN+^'heDg:3R%lù/q^dnrQ3a돊. ka[/j>.<XZi~ o`>^ + 7NfKUvu×vk ?`xqw`ZV[vk3\LKk7{p\IFmkh\wUnZ's ~+dĪX&9"7NneB%K6v+ruۭ+v+I3ح ;t!i҅[bF5k xms$'/u%iUoۭXO'VDV8Bvn`:wv+d9m]9&mEVbYۊòJoUJv[qt~zzs[E8trඖQ_fۭȠg۪l-dִmVl*rn9rךrio ׊Zٷf| $;bYf<7UZC9VۊMZr[ m+h]aYŷۊWd,۪]+(uUʅSmE4>VyimE_55b6[^5u ՊΊN+Ֆ:Wഎ{m–sՊijm+u3Uai͈aZG'V^3hrZai`imA{[iEoE,Z>+ʹDufWϊyGY ;s=Y)bf6+ȳn͊H\"pt۬^!. +|VtuӶϺ:igŕ%@+{*+1o5Z_lg]1;|:$S/u0߮vÈ4 ,FWڟԴEhDB G[OW~.}j 3Ho T~ZW t"s}u+u +endstream +endobj +559 0 obj +<> +stream +x=$;ri5 ZkI2{zd,d,5+Ah./'._%_~yDe4\^t}Z{y{}1{tzm5_ֿb< +\+o2_jƿ< qߞoq.ZZ `./Zw>@K ZY}\~^j.NR`T}A\껄4Ǘ}LPh{TТ4Q9߶&x{oҴB;plմX4 sP9wu2ҋϴ +/_!ZgQnו|׾\+7ɯ\TQi7;DwԈݜDX%9&1VN~:Rd8xȺ42E\@D ۝WO\*4Ric_n}?n{u,>@Zqm2,Z5.7'X0"0"|J+0XDr'pD: v.7 +&"*b|%Sl<",#_ d*?bxۊ[`+lłXFr0>IAt'獆`df6#+ىW5 jmIUMPL՘۳ѭ**om1Nszla;,+x=ؕR,ocZAqZ2Bv$&^u{6S5ӧja$2݄UDgZcS^y$a4 +8 Wn J8Tru]y “pܷVrr'[[3[:3?X_6ǀu)SGZj-,LFlQHE;eHi$kz<$ cC8Ÿ">Kt}DK+KBT3w}Os.+Ks߫Zդ@nѽ6?[<7bvsr0S()7WC^hՐ}[WpA;$ZdHn_why=}{p8D\ю3yZ"}FbJ7HHB7/475KZ%bv݃ñ^fiʢFjzjS{^́P~ԎJQ;* ++osT@AIʊ@YgXY4)c9_ʬS'bT`zD^(PlP.5M>4tG۱#3[I47sJUɀRʚNJK+'Й5=OU:GG$}[$ZOlXCH+B 7n=!:Wt ~H, ~ ke aD!0fu}W(c *F;  +xQ"9wqZ '4{%N5InM!quWHK{ !1-N(ӨD$&9 ~ծ +ӷkLriC D!:+ s2v={TdDj ytg8Mk< +ZᓞB9 M4IbvӚA 5NmWLVY;*fs;!N꙼B K<ΚrjM-Ӱ8.6~tPq>%'#δӞ +NgS>XR'§o\oz?w,6VU@7LЄMJ)8 +~9ur#r: +v]r#׫# +l`M4a4uȩ??,+蒌_,r 5pa%لcl"q{%FJ#$EpȎs+Ǹ<Ôow,1=8k;~lˬ,&3k=Ĺ؜j",5R:\;FED#xxJӜJ6㒉4%vJTJCۍ1**#tv 9hNa/݈pjM9N>S{TjUNx;σ2Qrj]ϓ!օRx > zHS\R&f6Sc6SdϥZ9VnYYwuU"d +LauYG0c՟ϚiL!\=%oȒ;E+>P<͙mlpLFTv>ս!0{Ԃ2.&*pq񔌳;a&N·&~ui/LZ s~M?mXqir{gd1CҴhIy&VX d7oL3kD0I;֥n&G64ؚ^qZTА7P8r9[PNd\XR[lpBENbס4X,B 'M712 6,~} ~ƷW1Ǒ#2G̃vfSL__o]uVsdOk%jNYKF00)8εkjgnYً?oăR$jHWkЌWj[xKj\˞]ƒ9.DpCSk#$ b3.=yܩ/{H:l6!5 x35C{iMi8}\ W$6qϾ)͔hy.[ HX>RCbiҮ |{kJ3erIEtMrJAy +s|(> Uu CP^vY䴞/+ON88啸:?l)i@$Қϗt@E*Dlr%#}6FeZC<(!݈Cz!-黖 )+ ykeHK +CzR WL,Y)U!=߹(r&t(T!~Az<=Pҽj~\NA0RTB6A᥏r}ݩV6]m͓h)%PJKGt*;,~>q +Mq A;rΠx݉__U\St!)*-%\oųFv | U mg.qt0۱ Iq !{G2 NJl+h^ڇ?>V"enS|Z PEbe'Q2ȍ]3Gxa;+S6y1l6@f6@ܢ!Q7u S|FzzdPkߌ0ѓj\p t@ +*;/2QQ9璻{i_S/>ctPwg6-q~MNHug| +!B/أ($R⟁nT$rQ20N e'Z < LyAaήz¾p,Ky5ܑ&c3?b0F^ aHW4OGχvIaDҁ?х$@tiN tTQGKdI@ *yQTOYjđG6QȂc%9(l PeWp#K +7н[EѠe{)c {m_s%kRWQHۻLDG>uF:$8D +mZ@bF7|^e[7gXpmOYPk 9dWh(Yt + +endstream +endobj +562 0 obj +<> +stream +x\;$ +:ŗ1ۀ/:`3쌃LVK{vEQ_v`2rv1ߦe~a{ +58! NcёKߟ׺PsNo*ҋ }ǟbL#}.Őu$'Iڐ<{vȁёyW'b e<Mi/D)QTOdBzhEE^G1]/NP +8ʓ d<2z(njckUp!$"9*RZWּ>$0yP6)ddG2)iŕct\惟V4B!6.񘟡VB2P;FR +y%zl D?epg=%".O[C9>Ps z9Ji -onic^ɱ=z!X5xkj2md)p l_OEc7@PRa[/ƙUmm ʪeЪ)=rWMoXxm_w ʩAn̨J50% +GnGT=UG56Z45, 8)JOȰ֍ +xVU3SESYŰlf_GyM?[js`v4E$0Tϋ!(z;5#Wfk o}u漥zUqw>5)>c$p7JN+Q:[ZәZYĚD!g5IIԲk GV= '܅WL]wg1 +4k;RFsxs.{ʢ@$!ɱ9/ I!t! /9BўM[74Y3V;!|(*kƛ=* >y\T70yJ8T:FaU} Wܷ!dAkn_" 0:PxA Hxƻٞ)늯r?@z7B'wD W<H Z3~TO %UQ< !F[}M1=eX?; gWA>Of*g``[CL=i%"G: =Գy J"4 Oo˓ /U2 j 9wzGx-}Ryn({$GH8Ŵ'm. i烾vC3qu?uh, +endstream +endobj +565 0 obj +<> +stream +x];,9Bpzؖ " @(}fkZޙv.ss.^ /O/]}%&\p/ɥ.;pϏ_7[.,r%%|yaK]~=E]/@Rӷ1X}a?|= BDP\Q +$>dyHq]P.!(,s9M(q" 90.z"3Ys5RqY#yEˀ0t 7eW +j[D l9 .(GQ?n1L0YE:?P\y$O,Әo/ +0c]Q* (Z #Br>k (s4 _4,^rfd'h»qĎLƃ^Zkr<(9j.׵$vIkI(kAf{Z&UB&C3:IɎ?fv8[Uo_Ru)ur=W4D%9FL zwJ2e ~xtd3g1:xZڗ, +y,ތ.05wo>#Y}bƢ~ 1NŧM%k)D(Q؟вLEQr۬fx/ECbS)BAEI1goX6/55aI'M9oY4 pR/0G0rGw5 +U4ﮈ\Up`ⶤ%Uw>$c_4}~1[a-)-|TD *"h>k[b[ X/=X,fP[J<5;y7 HԜj P=MP +MCm((u^b'P!55 \Fz $+{WS,J?3$Z¡rv Ж+%S!*%->[ IBz!yL|ɝAEC .KX4H#{)[5eD]1yWWO",Ajmw nm;V+jʡb*>?uf|*[q|^sL5aCw=z&G vK'=C9ݐ[I#rf?ō A9be%&|䏣T?Pt?OS)F K6]Ggu+$52a+q.bNH\̝ؤ<['' 0ySMOJ^ T$ +"1i)jbj9J4A`,@Y]-P|#AlKf8'=i^(LT u,?h >%Bĺ#{EAѾ!PT>#hU!(Txe_Wyo BQ5Z`xgНDē NOS=3δ&IE$aS=e#ldhؤP< W(g9d|paCR3,I{͹}fH W9D_ Ubֽ_!v$-rŪUq.2V!9<~Z򸪎bsFΓ)-Af4EL\Tk}pYl!F^}%)a—kv7l_ |~a.k"|38w!E( ]! %]2Hm]k&>m #A]cgkP +0dw Uॅ,$<K~EKi%qǾF{N<*NyČpshjZQI88 +#S)Иw QP+yv }C1%O%$LbkY?3bԋd Q Y=sW?QE& (NA6֔ .(Z;{+$#Qd`UEV&EUmTon\ngYnXdPSjW’Kǁ,G0>!HcLp0`ᒢW65TzZFPq«ju{MV|W XB}Xe\>ejq}13ILL=rEQ9KPWRRC0ROڵOI& NElZqiGoÃTFo?4ԩe4Y璋'ˢAnn^ hM%eRRturOS~F1؄nM G8Μ1k(ܠ^ Cp-SXn:2̐ JߟSQ2AԋΞ隁Hej)!W~bAQtvju4 CF +endstream +endobj +568 0 obj +<> +stream +x];$ +:E  68888JnQP/΋^kJDQ$ŏ^~Ep x >.s*]ozI%yB00*Azyyf}/?5]J!˗ϋWVڡ/BD\&嚎]eoZCALp6C';pR>'{HqpO$hAN`'_羦S[t1Q}AZe6y?2jyGb]^0lG̚*h/(._r[v<ڤ7 ~ SiYvP%1/#O2 a- TQ$ w*k! qZ<%\zgbYUG R;sc)y/e=LE@ 4t_aR[FchܤB'l;>$@LqY~pp!Ơ_bJ/)L{)KȰdn մche94t)=Rp#-J¥rdHG,xVd ty>m7LZh ^9m9e<3%c< +S{]Gy;GFBiH\wKQ X{UM줓Joɯwݯ|t#Lruk\ mRfk Nw79$1ʽrMÒ\Uh;Lu{CAN*WL$-W\I εr[~oEk١tZCR&̘Y@$+_|f`F {'GP>[B[w[n:N}GeBXWT0VNkj0V50~l[<Cwз6VpO +Rr&CFQ$]Î9Q`<$yID&oj΍is NϴLG& d7xi_yR>dZ,R-z2 L5,S[#i<̖D̖I62Y쩖ItLetLeZs0[":[M"UQFD"5+tz1ʛ,Hz˦[ZH<-}dN!4Ϣ-39:DBL<ϰyKyl9* x'l9kB7;(t -&9$c!(4ZP^:̀0ň0&:}YD Gۍ ݬ'r E'7? .h SFѡNÜt Fo +[| ZSd(R uŨ+D]'WYtoK:_cLBwCmulKΜB9e$ ETQwČbF -16ƌڪ1%fң'$=a\`ÌrA/ȃ^|\si:>.}7Wș 6lc:ċ {uZBS@>su){4s ]_)wYұ`탠y![ %>˥t"g4ӎexB׋+gH%RtTtN-`jLFG>8!K:Hz9 +{η;F;/ņ_cC5Ʈ0cC&bƆDkC lh;{*6$bCetƆhņ6 $[u:qK|\+n橖 +!̽0|Q؏GESg[Z; O;|ܙizvܹs:i:NAZo9 Xp ,OI7 !_8'v +~,|mɝpgS:7Mmwp[ʣ0QX+v);ZӓX +ae}꺁2;A%y|V:Mp;f-1W& ~$GV'9z.uI!#Al- sXjPZDL^PnKU#zm@h!%@p]KG@l Y dZj &'/;PV6c6i}MUiIl.maAe&9O*LkR: +ܱ$@X3\kԊ`H$|)͵&KJ>D[%7]"Oŵ -t\q߿YEw ? +! +MgBԭlw/=C'^68D@qEH][МYE+1HʴaA{?^,kEk%k|S\&n];_i{d«-ջnGj7w- cQǒ^^R0 +]֭VLz*N~b7pT3Fcb3ۿ,NA0?^Aũ@= +U%{jzIŎXXs9M9350s{ӫT* t~1H3vZg!4PiR'}s > +stream +x=$;nC;D,`nf;sgLjQϙ*Q/IQm[[It?~Toi%{:~ߦi~do_ߧ ѿo _o_44gaNI[|=ԇpoOl~Oo +8oI .%>淿 (hݬ*IYoզ!T +ao_ *=Crmqq86b>@VaPx_֤qq:ks= 8*3A؄/VB}V#|0oG3[67o//BW>LVeSyJU8Aph-uG X"  7[{/I@6 b% " :yuk]1d +I/ὼxg<0)?Lzp ʃ^hb%M$gf ]IǨpI{dDX_npaA?E+*e3U4ί]BNXBqz~G2Zwiۺ `.غ c}+VB. ;螘I3΃: +Udd~?/j<(AR ~XmPLԘڳZc뫅5@> "B=7'1_iO==hl*eAO} ml/N$M #u=kX9i> ҙVbkQZzЫ^` 8]AW~'Rk/  J8ZGe]u“dp ekSR2oSqYɴk>{TjV^ۮs Wrv,dg%Ho$FiuEuiI-\zs3o$ԝЌjE,QgE?=ͿEuw*\:ҩ&,j|VӞlneܽ{xuN#Iɡs)]w +$wԧW |KȝEkяWZWZiN9ZjcAw`ڻ}Qs8\3e=(_A!qLhԀy3ldgskgw;c +)MӔEܺCVLk.pr+siWS9^=*YVD+,a)RvQ* ʣ%=iΠi⯖&hs(:19Ddy@BCqen#) Cw(;":E!v~h`_imU2ZtF +5481(p$T@3K͞t Py_W +e]9 +ΧQ2,0"]kd-dO]>]5;ƩDwB͎wA\q>שo@k֖_W$lmuWت/۪` <nѥc#By翮A<MC!b;u^8bAW-\mi\eP?WypWgCeVUs3*?Lt FPBMa׷8#8#sVƷUԏ88M:oCoy\κ;$w֣ڝ5;;|r/ l[{,O^rfNaS(W#yQⴄJ/;\Rq\J +ˎ]F;,d PUS KJ;}uz-Eט+/\u8TQ*NM: CUj("H+Ğ#pBeGzⰊ4x\3Wdyœ}癔z:HۆԢ }rr7Lol.AʙI9$WJ{.T:inaJEjB-n11mk^!%Y"&A" xd)3I]SX#1\"Lm@J,ۏ}Bh<%R4!w!lLא3LNR q>?drDM'nВ"h%qܗCP":}0@>HB(jfn{Z94.X0߷k]}ȹ8[Ηәtk&.tzi9r[$@᠗FHM4NaVUOoQnY%"=k+A>9n*sֆI2a}0q~CDTb.d\W h qLqTpIKh u/cp + [r{LqU3Jnq(E.90wUKkdz0۬YӺ´Y˾ydޅlc1VGt3#GG>>F9Vw@Fakʢ*-\Wp[3eFTd^'qНCunyyq4WKRDh?F Dn@4kT7_h+ 2|k%u{ԚX>>荡ȭV@´BTkK5ǐ1RY9ǁ^Je;TSWGz$Z!$kwUۉC&NIO (;Yw.eGxwTpGD>Ryzo5W+$&dx"_ & tyk̇rUتWHT]DW$ ^2 +Nm^ &xd2b͌@iNU*?u7]˅Kyp5K8ۉc٭iLX[L4r4| 50OXݐlp=@-Wri8%)j!W{-0)\,+, =PԒH{ $ԯ<úpuQZy?rmBkcܭQ2BllD# 0).kV3(0n%s[$ܧ# rY(EYgc@+"[Vg$B.ЦR/cq:_*-KI`b$NpCǻc, ȗ&/y%a g8PQ +S`= z|z(xCPS +a V~?1X_WvDNL..vsPIޠb"s}ɝeKR&M@{}ܚa\#j/*Z]YƟ笛ռ+8pUWEWs1JhT d+=OgEt*:ݪ_pPEM $Җ E*{f0bf́[S8_xԅs%¸Lyd5QGG`2E܉ɑ9'-yDBh]VmF#}ΊcPQQE%|GGBU3c# ]/+}L)._ԜL)S]z)}vm~liKd {5lUvϰ)oTJ~?֖mVE ug F1  'L +LKWY"I1KdYMSMSM@*7$M5/fi6HGaFbNa-+{yGV TߔF WNe+L=Hۄ nY:hr+ W&q@g~M}W@j*8aNeK!brBoŧfB,EKF x^CՐ1>ØȔF򰗝_§'z1ha!jT-ѡ@E| tV$=P"EԺ}Ra%{4)opMem@ϟt7Ǩ[ż85 >Dgֲ"&r8vcUUJsqݖu vٍ`P񁉢@57|qnAՀ +5ҩc\[ +/a//</d| @S. +2f߉JY]+ؠ[sm{[vDlWH|CΐDA 7$X;Kb G:+A.5aU=%Vh|k"Zngi w *p6ij5hhAϦ`#8Cj& sO׮ (GzHyړ̫! ( + 6UϖQ=53ƙk(b(>j Žju=ZN8d"!Cwng㤌χqn4l7cFjr?}W}6[Ag9H+s %zkce_[K6&B}Sh森ݘ=W.%E3r75g4G:0I y"Z2+7fjVUfScbOTۭy@<|^' fbİɟ&?/HGy P6%I)U^qdvmImj†3yUYOiۈ3xL&cDɺf`j es{QH*\ >PRrt( *CKX}8FG?X/]gVzTJk}&{.^0m~yE{^rS.^ڭ:3FJ@GOʎ٤g;iDLh| +:O9|hK!Z:UҪ&O6y$c&G#+2_B*B9(#J2Vt[ƌ.5NL*iPV2P䦔fݟ{ϐj*3]UZġНrDx*#8yjT4~F[-S$su*MȪU宦t4h,\}ךBw:WWqZ}RqniS Wt2RJ)4%ǰ(.!qg%8cp]%n]چDQaz1nD(;zx&F4>ÊI=alQ&ư@WEQiD;Ua-Yй.S9jbsӝZd?;2f1;.miahvM2VI۩*#At8N/sjv +߀CpoG9l7EMJݽv1H*Hv:; .#.ۭѺ9t.8Zf%Ov2hoڼFE7n˰9PdɱL XΞm*敩Zrp;65c}jvLҶ)1S糤i9l|0%!*Qd#;B;k4vkkQ^,qiS0*@?Sγ_F.|(PP-spx_(iOP5াRaŢAcNREe)"Q5'<\(UaX1,Z$xWVòB|L}~\Uh Pq+ èo+7vk&Qˇl䳔};#T*~;_cT\ˎĶKߴB ^5.XA#QϘ4wïqGx%s]]m͘ ++Y2"ZV)*}y$[SiT؛R@tuclW'^abPet/t>_ḚM"sCWf m;IQ.Jfz(v$/3Rg9y`ڵLytnW֐=#tipܰ+t/y +-MYC2b^&6R+ `gRw `c#JP~tdp بd [DGΫ{-|.<]YnGArզG-O8 ,m-Pd؂X؂nUۣB?ї}Z12VZp{ŏZt#,x6SQnQ{YQwD-1QnKԂrI>$ER/|H@>4աT'չR3er׎'RޯAnI2y}v> tEQ̰ m 8ȁ}'?p *>+[ҘO +endstream +endobj +574 0 obj +<> +stream +x=ˎ$qwE&`}0` N2f0==G$2+,v*;$`7?ͻB|oZŷ?'\x߾TѽY7heyolY/oc|#wox*ZbxZ0o|׿jH_0b~~Ow$D(I}{iW~?{[ڙoonU?PPł\B 02o֐2#QIWn#$?0F$?0NJ+][.lʇۏpFDj jP!ϟABG*(AYdʃ7Ez-h|lFG )b` +.aEWV*R 7{4F4 F$2v8^'% f"A1A!Q9͛9.tb?]qoI mWӨSh2#&RAı(疱Z&L265_s +̱:Th5VB222owiҮdͻ0=m3ǎ̤c>qeL>ŧuwIlf(p"SD,{T +Q8*>\mTP3ۻ| (SMBX0A,WΔe_# 1$9̊Bxm1/Tg~,=ěD)Qy=`zGg|D<׹.Q];.~Nm} uwaHN)TzNӃ AAKz#^'2v` dD[GɔuY`l|Px@c_FH}!:Os3?2J$ߍ' uϼ0 Ad7z\{,@e'˛,{3O3`-X7ֽl8wglJhtP2ӌօNu*YpMPNhZJ;SQem[I[zlOo}He mEBbPۛX1=ЏuP(kZ^ 0Xa' A*bagr0*P& Yo:xύcPB},{Zarzu`UдTU =AX(rpr7Ğʩ~f'l"g}A0@=i^L/Dʉ`!=ݻyA3vcj8B۬PWM䢩0)C14٥`*"\8'ܯQnreQ) +W.<-j Pd4e-UY"fNKo~4\>}xai{`9~`mS$?i?Vj,#ˊ9B+_['̅Ȓf:[rYCV{ 1ⅳn. <#cxs-r<:H2JE%r޿~#hSX~ϿI=H!(O?f ''c C?C1֤X&'7fy77a&e!}? +:uy5`٤`Ne$E0pKz +y^gFYc ?F\BbXMeFL5ctkk5>dF$?7c}ĩ;F7 6hW 8_JķuP}q$ ]5v&yxo+4_sBZ3jlKZH:˛<$<΃nX=d&uAizzJB|UӛI4yvDHy9-{|m]FxXEz"sgsT3}`XN19f狏 B|"<`a~iK["E(B0qDDc'~)URr(ROIa#TҬ(LJݗ'$1WaGb*]e]^AQHT*ׁa E9qM*$ Z^5)2n@7Nxby3{D% X,RU~d h?#Iͭo7W/{ǐYz4i#?(84M'+ƃځ(@SOV0Y9ρ`90%[j̟EfR. P%w`ӱưX?hju:ւߓ*rli[]#v sX=H:(*gƣ5ńY Ll5w#IJǙ`wԌ˞rny +r&h%՚jbV]8 l/92Z~9®Vy7g\0 83YN ]=~&&ҸQd<7Y|_e9Ē{aՄgnQϹ`k8g@FlͼSWU[b֑2Y;HGz :jܘ̭=ġs>P4O1j>?UɌI%AqH#u*4*Y:x`\633 VúPj^@_?1[;7 60>>SNF)Ju.Xqv6Rfy 6%#gn1JycB/NB&%q\;bDx>\LֆkW1@E@=,atɼH˃gQguB[Cܞ_?fCqu' +z|3-ScY;a%BڀJB` 7T9C|rO;4.C_SFb7M̜F4noW ͅg{;hޛ)Y)"F1-Uw3Eh}Ω M-t*)iu/Lljm4+2twtsJu7ؓ j.<8rň_ȔXv_$RHFi>7z܍Oa,3Z'1f܏6ۅc*/m?{N,u( lCG+&Oԅݠ8{[ +N6 ;|M6;"L(jM]{IP{;'1.^; +&U: /SLC浣,v({%" k9KuAOUOO/"hE|P@Svɵmw8Tr^@q2R,%g4t +FZYqjhzhpn=Z{>N:7NMk f9wLlY1^brzOm2_hw +)c@%;ys]MZyŋ,ЌHa- W%E$tߒ7RcU-u:t:vtrScUZXɒP<> v`?brN7S)]VL2|GE'I]Yi4VjrȢ0JTǫo @ F8^Ej~=W/:L*ױ_ibdCOG(Rљ%`?C0AqٹY~_GziCY:ؗ,mw:؛ N΃XcwpL6էu8UrEY&84qzmVuaxcxv9>j$RYP=gXΆu7,۰t͆$`GN~vmծTV30 +yI܀0^[Ѓpǫa:ogDZ.N%"׳8S-E |ce2BH(w!~m/] w|BP̡Wg…q.UX  m2K>?> n0#sj㑥+)-M㱁xz<^_ǫ*xr<^WE*xrYnJ;`4+oreKs(2 ]x^)X)ܦIm$lVHVJgZ!!gvVp*N&m,>+ 4~y&)y/W@"6ưL   +,]!'ּkE- N)qNxrл9K6l#8gf8`MI:4wM&@Je},o?&b첋0xx{Z!f2 d2QB}dIO{ts'M,k'9D}&Pri| WUbm%+UUj@ݰOK'ʂ EE?fJ)CEb0יw($|2}M.aT +|PAo?ShJ:ú34>Rߪ>sc13L)ʼS퐷Wʂz@$3@6cj,Mrc73F-T BgX`\'ʛxI%c !1gܧ0.UԏVCB;S!21Lnx7w:3.*ĉ\Q^;Lb 5~Kein=dED*͛2XF:rksb?ߤ|;Z!٫ 'nې;zei,,^ {&bMZBA}C +,:hwYDNL8.+.Hwb-w"ksM x2ur_` ayhC1c=LGKo ':"6gVMgXjqEnvnJj`_V>CXo\*6`Hoē/Iݰ`bn5L$1"8&>)KH +jjR L@ +j;s^%..ZBedzqCY2cwnmvPw&ޟHqDFؿ"`;hYG E2.wqy,}LJV0ȤvL@~Q&M"b ]]Yb7_=s x XXyб+X%ғq&].R>NS#}z8,96 +4n5TK:*+i-~;6k{A0ĩv'HCo Ǔ$ݵս WBuCVF h\ܞ,kJj,)0uxt1d >k> wxʴT\K^cK߻k%EuOKCƯj?S L.F]L.p}ga»%2m+7Lw._u )0FniԆISN2ͭ?ǹ*at4'V,Hctۥ;o1X(13ckI @ݺłشG)*XgsMpe,/?OkG^>qV>/~,~;X̽Leq37_3En$Zr`_g{Bh pMh{J6;8ٻCFؽɋdzmj^ Z{yeB%1NHnWh[\'Lҋ Plz +#TRfKKHF̝CEQtB#lN{A vԢ-DU #߉*f̗]e*/15/ +nB@S[8kX00ГRxm6>Uz ^! G?O׊RM;@BCD=m[fhHbӧӫ-[ğm3oޙRFB'kow{ -%ָ_'PsbV1_g)je*C$!sM*k,-IcSE/_ϼ +endstream +endobj +577 0 obj +<> +stream +x\͎ )="R!@ 9-0${ؼ!$WY;XmMR$?Q˯X./1d_.˿|&ٵ_/ 39\(D!^ +pߗˏӵ|oM1\>}YY.gk=Z>o_? <9ߜMȨxe}O2`Rh~[y4:0##WElm=vd/=_u9Ҍ~T$6r$"^]=y!@__\K903N_B2} `BK7 Po{񡪰^a+!+nCAד# T)E|U0" +:=1A6"2MBJre4]+k[`BҌ;{Ⱥk/M'껎3;V>n1])<>>`Lr Ή$qRzZ&څ#BաJ AhűSl!%v,سf1w`$p%z[[~pppͲ-p6 +p')nR C{RfaWה9xc+T [[\ue yX5ŝB-MZ|TECxb\8d5iZc q[S z H ƘRaOJ%J́yP"o-_VkVH+<ș 1PBD H/(|fQwb$PCxXC)}B&yz`&Ir}&LۼzӔ(W6DEY&AЇ ׺Z$;"=&###^JѪz &R㌝.[4tscܚ 29/c =O:p2rV] 9S+1R7y~%X~BJM<^ +ݵ,Z4y^^@ݎ+n,C4U9VUeьKOKN0YmUZG;am o,:Ր5RQ+Z-m !從/~1VM&HQiLR/ɛXzx\Lِ[X``O#ƥ4|0Pʂ-;4婞Fu]yad\ҚO4,Ostiou.X4R+v-T@|Ґ-V&ZK#K ?p'[dcw| Ͼp1+f?=>$-)":ꉟR5w3}Gqv+n~b0"Ky4r.[L~-ߞ.̓~^eb׎!/N4w0f??nFJȞbT YqVJ{`Umպumz;NF6,=~ :!#u25Kr5Ŏt49"h{kUϛ$Kvjfu)OY:DXڑM\-ZC@$vMƹt )!<Xv@؃{0&{e&Uճ?|[l +endstream +endobj +580 0 obj +<> +stream +x=캑Co04Y|,:2p2lEJ|-zŹQ7zWxE]$..Eq+":p%A//J _xR:g!hMJxI|sO7}Zmӿ R g_h%؋q^x%q?/6-Ҧŋiϴ1\^ %]2 ːlaK[1DŽs/ƈ'hu:|um ܭI +upZBXKi@ +:|v-G0 IUlZ{ kx&m lM e'TC},t]7z&%AQ'':$PAͶ]"Xf!" [7]V~_ oXgW+rɢԴ)Uv +8w԰WU⭩Y~ڏZbƜP +v?!G=cR1 +tD[gW+~2o^e>u+(Į?kؚzQdV6݃1NGq󢤇JM懤&ڶV#T'9zT4QŗiÜS&512wByTRRvdxRFDX.HU7)'߿筈 -D>whg?MH-KgM@Ԗ*/5X#p,u +@9KB2ո꼀#XࡇLgv`[ͪ,w7ݍט7?探n' n6 +4A2m񮨪۫n8J;n(c%x;vpbo︊}_fOWL_A~0!7F@6+C~d _҆N|BiW>5POm'&>)f]$2(aPFh't +v$t~k Åm91ΡJk~1 k;8q71Ω7!{])*sIjÁq q lBf bzpgR1U *s2]-T.! ?vcϯI?q”1 Csj08Z[Z U?MpIXIB7@̿Mȧ|(xTYRkrhU>f?/^}xdwzo@&֙jS[t/+Qg"iDHٝ"~dLG>!ҒV) i"r9_D=#wxL6;[h`wL#g,7of?8G"ɞn~CEs{IwW,)$,$^<=GG@1~fԖȿc=BJ1>MY/| EVFvpszs*oK?dcky'Rvp=mDpL6 g@iM^0`(a)-gϛ s-$$A=6p2L~/\"H [2B+ؓkf$lǥօHW36X݀P\X:n0 kuYj#LpNReA)7ǡ#JSΰcK'TGNCvvgAkjwg_SjWa9 +72#jAo9H|򣺽jI8xIckX|ts8}PO:pfj L3c +-T. r RVBQםEOPF6maY2T:drfxd92ɒkn덼/q,l6Ca7;D0TqҽJ-/!TW fR;oK!S~XϦ^;ev[9 **|- L5a8MBe"-/"mȸ%m$a\01O̔%qN8k@IBaأl pG?0,!D-GK9C&Aͬꀨcr['|zǙNi/bMau] k;?WzH n$J' +@OEWay'L) n fl9O!|r2Kr\Ob*gg5D92U-AI5b)YT$Μ}I$ь6IoPg =y9y R4r@N5ӇB̩maEݰM[DQ_On{jx@7#TQ[G64qs[wF(U4P* +ON@K֡*D!IR5=@yCvBzHcc׭0{/Am{ޢgKE##r76d3BdrϡdA[ +Mo +}X!gBK!%::tբɘڢZS95r%lQ atP7"q9/1}/:X3u[Vn(CuE.Ւw°Z~RѠ֙Bfz #zN΄\MTAfRiIirK"\2 M9Qy})Рֺn![°C=|2!sN=qI#HɑMD 8lSD~"MG/ k&qƵL$o&ע=Z4#'&|.Mݜ7Zi0#c0XZD+8bQkcq=%.nK+ oC,b[bjF+^O8f?j)PW4%5F}ml(@0Hj\g΁zVokLǔ͸j ΎxYZLz[S2[*P~ L[JP^ie9kŞϏGJlE01_R70"A^d%u+i9jrͽB*M~JH/29mgv>QR!ti| L׈=s2tP-v+)̀{oq {:Խ濤sLӍ7rتJHsϺF@sEqzBJ-o+7 ҕw_% 8긵J1ٴ6Oz~J6br$8^PBW.5=-UްTZcFrۗs j1M""va^p.Y8 \`<%mv@9gVz_LzMK=*YQMC_xZ7dҕVTt@\}K])?7IkɠԳ\uz $;\Au +#|@P!2kV"K[=K[34ՂnNafSRs[F{ڴU#t#"ùT\Qq8닏G! N ']d qlq}Q\`PsRl9+qYk0B}y׵ja辞n 7Hvl?ps !pɒ3=(o{bT£ģ[&Ţ}2ܞ]+gv@4HFldjh%u`)?~]:XG>zL(#f־\ٺ$7{├L'#'ŘCo?v0mrQ בL cABϚ-%T[fP+UY-tulXJ= $胕ܮ!-u8Slt^jљs2|\4 +u$!ԣ=pkgV&֖=B=߂;G3)MDX9::]7($rX//DĤ1d)HJhg7a0WZk:?9\hm}YNdRb=݄7!>֤j,\{]6 n'r9|3Q|.s%i:qmPQ ;`~~Vzh,p!3$r ԇʅu=6q[ŴۉcsO^9qz:W`nouYxvAzCML%9| NȲ"]": #ZrD@[,a2R-8,#ʔ +O\F@UN/hiri<s<\-}\@UJ]^ތ猎f`a)`k|Q* M@aLg3Fy]ECt0[g3t&I][[yT . xU%R\PySȑfZ̢X΃Ԡkdߐc_e`PaV!ݠOUD6.́u{5+TRa}:MZΙ3;9$<OA$i5RP$EfX *r~ȧo؂› h6_TS"fA5wAv=RӡC3F*6(S ɘXN<9|A*]7H(+Ie+pʘDvQolnW wzhKn¸:B?OX*k]9\@|uD}NsvtĿz$5jK\Eji^YJgwM)bJm5gr^ ASy*-!=CTjm8>: +o|I!n ̓/9n />(_Mona",nv6AëGcbbbb;vRGf;$Xa*J#M=2J5`r̃In +endstream +endobj +583 0 obj +<> +stream +x=M-+n^fM`>Q/"%2.f1b/bQ:ޭjNa 66EHO8xq6^ߋ?K??We}'@WE/:{QR^˟7k_=ٗ~ <)R!@~΃^<21*S1y~+4,eEB'Sp؜3Io> $g_)Al*A!JkA,ִX@ tDzLy };_%r,'Wj?Vེ"}εXc>-UF͝>MӇj9à14w_LYZtŴd ,,f>ĖY4CH7XӓrSw~C!N^-Z )+:LzjBL^-Z?Vi%3gtҚ5 ӪGH7ً-L&L;3M?DZz b`W9L=Y<~S$$i7 RD>$5l~ 3S4 D͏c:1MTL<)L}XɶNAjeYִJCʢIUYXʖN &FV4udÓ "KuD[\m#ROWdz'`.tes8I/<8$MjW'ݒ\j46M" b܄XZ[~֐Jx=XUÔp`&RӴ%[J%N(Q%CͲB[ĊVo%\#shc55:l*ߢGHg#=So'k)?^A6"Xĕ.R^Bah:Wd'@Bȃk}poQG JM&>]k(^Dk5B@H,bv:=FkS+Ax$kpգU +(|TpX|{stʲ&d'hnJKL7ckfY%CDs>o+Ŀɲ/b)>|83.^e=h= 3uA0fťÆ!Wɭ0kԤZ/#d@I/*W?K"C@] }Y0Ç})jֱ<㋶ʋ/!.jbs#eU-&~Ӹ5v6:mR</a* ;pb []P$dWmْM/ϵMMZV3*{JQe7*fD&-}SP,zB il%`w} aQEI +YRj?ş UYpϗ~c|GeDjf642[:d۴:oJ8Tg+j$ud +i@fc`vjZŁfh*\WcOhz9efDfHZh:o:Vѥgn +f}i37,ٸXm%u?O9C (MD Ǔ1ml˦Ut5.;\IEw6,SYvw8ӡMR"96j⢕=  +@{F9f @nR5:q=ghI7fm>{5ak,#_ӚĻa|!̓1[ѣs_. ͈ +͈ +͈{6#Qk3)5gW"ޛDgo +h5%vLAFkiʴ>4,!l5Ob;>k%xC7~,^*{ UmGO~ 3.Ԅ8t{A?sO.8&^wP;_N 5)d$iJ l' tVzYe~aQ~sIRCl9 Awnj1cD"5K *V +3Ve^\Up '{5GYyAzPaJGNO ܷC~ZpQE,wځ?>*BURk8l@ٛ)JCaQeϔJ03 }k6Ȟ+i]rJmb:uysL79oLΛc2if9dUδ5uvҦ\MS8]hg65HHkWJԜYˮxKA#KN|<\ 9m T-dQAHȨ| J9C7$~Mv789lI*85T,<Spm>*@ E+J(h +@[vܺcQmr1{^uҩ@FzuMN %C#薌FҨjj#)]G\)m-)Y]jx\!쾮k :d4;nװF ++ Q[ߕ +n[v;>7a3XcAyGv_V‡nJr+W#8CT:\wƃ+_K( [!WM겏|\BrNTL UIE@'w8> t:IΏ7dI|Rl f]|[z`Ƈ㰙R`:]<%G&>GƤ2hՊrql{+NJ\#{&OȚI,jB W +r GՀXD\c  BnӨPC jF?-LV#~(j~8Z)tP;$"ĔwuZ9uWeZK>!=ƶ>b0;w^:9cs#ǂ#*=~SکGΑLrW >q833R5^Y sF4?LN>H)?jM&w4Ƶr>'#B9q#8p,L3g^w5uF8Xu/h@-Gj 9^#hdp܂{Ǐ$\ ,\Cα"_d->Ȋ=ڨ7զ;ʷOX 1#͕b%eڻk8%nJvtUZwabuƚ~yd%pS Z^]oh!F5/` ,XI{>ؙvKq{ dQ텮legiZ$UW(PPO|]ܠ<_@ n\R v ̺f\ 15x.ƀG}_ g"CN;|c!Sߞ@lFr^?ɹ2JU.kҩ?.?'U8~גp?S> sw`jP9q)MՒ*SB'mѤ˜Mz-?O֐O"hC6[@v麦/DgOm@^r~^3Oo潡F:wI%"'E NmΉ .xN2D-?ʦs/IRHfr#ƴ܏pe\~+OG(4/2vUTΣ2@TmhC( +U%3,Ji(g/{.&<_K0_~/ }FgDE]ii!'>0 !t6xw~T& 70+C0nͷ  gf9\k;ܘlLG9^2VNnR~6D}6 cY-4S9hɭ!ON!A5m%onLh 7#rJ4m + ,@N +*׷֘5͇@<6eJ rB]A'?@˯?V(iСiKȪ&^gs7^0ܿ+wqϳ*Yqܖݾ+3 ~0GP Ee +r6ٻt^ahPm*",c+.6409J mlfA|ZtԂ)>nnR:b&5]6jX466`ᶪය+Ǹ8Us:y4jc@-4_m.eM6$=-qsn*bn}OpC$HUa$Q2o’CzӯLʖlʖzxFQϦ-ɥU߀CIV|nߞ[] pMO>T/3Wǹc8 u3wQe-F\]+,pMWC\O]l6pNe9BвrU/ruWvU_AY8iv]Bg6.MDؘxxE9:fnd"/Հ/$f勚u٠5ǶuBѵ%6%y+LݾA<Ɖ`3ˁ1 >%*eP;(Y@Bu&-գ>#NÇ4>s)[0 +uLiǷIs]WA_~bmf$Ky꼴!Y5)!YC+jgosAB]#bk47;Ț[]lB!&Z|:=Ey09C8E=sgjO |a팭;?H v~5|#UzZhh2 T-lcLnm3Y'blq[Ϳ:k/j^ cf:խnʆmKq]e.HQKkJ + +endstream +endobj +586 0 obj +<> +stream +x]9% +^h#K$u l}80`J%Ux^,f[]EQ$Q"/^E]T!^{ӷb%]cxZKҦ "W9_s^/rGec|vE^YlP_v Yn^Q^W [fٳƺpPa M$Po9ӷ,L?e|[gL=>|q 6xX.`bMBO +[SVU_$>9Xa/TޏG8m<9I㠨4j獣#(eyMbYF.[ VXi8.C[_ѯO4+4EI`Hƙi$̖.1rjo(ab rWU /?:Xf7]o&nE8 '`mVOQ2)A\5~a[ue߯N\RkjݒUk S Tl5[v~|0wۺLܺwT㫷f[d[??H\HM(Rą`!}-+NTq!ǸN24`WOU\}GU\Y7s( BB}:1kK@O$+$Τs*ɼBLYoE;Rc$ y?>'a>%/]ZWbl{Zwl\~yU8[/ NeY?"asØw9"׃r\z.ExE_I AԷI7c 6 ^E-߈`[u6[* |E39ѻS)\/dZm-[?\ +q㙏)0# +54 (kdTH,=È'wQpaM|\~Va=J> ,A(ovqx;ڬ8MTX]Lx^VLCi<%&TKC#|vY)pny+YIh2,ۤϕéclEФI1o0vg1 N9-S`zړHsH=c٧5ܦꎚkkI> _GH/-+Sv@Uo^n\;\^E:cAE',"e&AO!M-_@tO4ȝў]D mxftEUQS(c0F=/QtG0:wًqzPt?2'M*\=CHƞ4j,P hֿttSh'V@<Ƶ@DQhRa BT}3ߵZ"ꑈ'G4݋bMO^M'h$GK]H35bgS? 䁗eC{g#ܙi`n68JE4a$l9X15ˣm+gbU=?}zCJ'g4&SsdwgРRL5̜=? |'W):VK~AMH5}F&ECF drhY$ 6thM´DuHZ^\0it;9Ki֢e?X+z'&zN|ݯ'$uAn׿!u uA~R_~-s4>,׿On||XT7rSdK^FL +endstream +endobj +589 0 obj +<> +stream +x=M츍-ZA xE]!%eeI.WV ޔU(ߤ˿.?sp./woo/QEŠQȿy3Fo_h_Kk!"YsK~Ε?i ?sk~>67x[r~ +G];a,0gɿ\Exs?l|%{W`r^y&ъo{bU>^.o. %`,aFBsod e Q^ e/8^&x5i=S6݀B `oVIP.B@oAY܋s^2_F͑\| ěٸ||ǔȌoOTqw|cM {6۰ +*[ƣ" -ƹAQiE8> Gpp`l6eMLVv']|_Nr݄e3SO1_|!O_}\$~'q7e0wtӭ@zR-q5"b"\aI袕tc"^-_-dHwdžE)0| e ѵ#ULlnOw `Mg=9o@70 ݦH375?0S(>>8`RdjPjV P),9EhgFgF=3<3ClM; =272΀۞Fdv4[p Ukv%ٷ.VYMc cUqY +H碊%pKx#\TkFS$o˯jW7 6s4fevP2O"(T_Jfz#Ň=J2%g od(K 7@ͤǐHfH{M;f-BaB"Hk0ĨBvE_}#dYlVʔ+%]+Dݙsj1Ps8-G"751ϐ;nCWEO΋|bȘҺ)UnMZL4a ++v ݓS>^z1hy57|$\Ƥ3H`bp]Y?*{+CϲA)O @&EN8F% {gPDU R*IyֱR1K*8vq^:-[&G@"gTX4]c)mHE4CIm K(~) +#@*NO\'cԗPAe~IK\Xujsg +~Ђ;fW.E b APGQj SiAzhtkFI6GN_єcfd?.9F YHj̽_9?=h<WIfK.c:a{]J]u\C +IjqR!F`鬐̝8 uN`yF$5۠c͏3۠ ϧ+C`"8rƩ弫, ck"MhJ$g/DMǏ543b:L~8roy9҈/c_X~RHeԨRTpsڤϟŋhggh- +z4'@AE -3aXf$!\8 +-PGsd:u]LL>G=YXR1=М |n75[n}jUQFq) +Z**xݲgV=Eٖ&n-LlL;cI~Kh- {;>?Ŏ]Fd sV4nN p5?LU5BM=yv:i=MNQj5TI h=b&8usT[UM{QPӅp4ր| C7,N ^aV_}Zw%JKPБX5&<߬Bf!>^ v͆b(]6%9v %`Q6;b2YOQqv~Qg'+BZxIhaMXA= kvk'4aQ !!kAbdܟ9o>uX|H~#&yj Z4Îp_ś ,7٫>w O +0܅g2+“%t]7G2Ǹ]vh%سڱ<{8Ս{ 4%}H`AoK`qg  :Vl`Ivi|tgc9$sv_ s vM +qA|L\Ckܖk<K/5^) ILh؋`>OXC-,69uNYg@#3uRgh3DDBdN . G 5ԑuߟXg˦.5rgD]4'_'"g01düϰ܎$JYӶ1$"@f'XkrqfoȞoemZT^qmV! V9`ȾWCZLϐC"eI0)"tb|-k%J捾W +| A88 8z+涪h&:$ -ȩ˩u |%}S=q){ ' +3h WḒWֵ8R el`n%e5( +-AOdTtc)Y2o'42~wh9TJ6N'miQ\\: +r0 ]OI4d$Qd:r̠ˑh:~RHz= BR$[,PP7cQ}-pP`FzƊ 2cgX(CV}`0 ~b`m&[6k1mkiӈoZy + +4"Ye/a%ICdp}g݅(ԳjragJoM@ 3{A9D-DD93{f9>1*V!+D}\-aS44Q]zbCE mS?4(;BaTn)>p(DinJ^a iQ#lVE0Ωז|L $er#G+)@죬U$:>,lR>Cõ@}[ Jq]j&%kX NL2OnidDŽ\:zm 9OY<El$xN$Y9 $[ #jM`,#h< -S#[Ir$ꓗX񳋆(;Jer4g=s6:lE$AX5F>8 50cZt^#H ,kAf©H4qkOppj"5Lgj`,M!g,MV+RФ l'$l&3MP|ZH4Ӵ�biAJP= XZ9/!µdB_qi%ODG O/ s緙e]{MIyv*kېQu 5vV݃0/{l+]kǧ:q9P_ bF^oR;wI{zNO)!g=LO}'"kE:&_BObwrl9vX3trۑol^;o $s}}֜aXݤ{ll75jŽ@x%ʛBLꗃcvJ{S3prJ荈)GxuMX1`Ѯ#Mp@# 'ޱ,-yp$~T8wc=@`n prUwq,gQAнfJްܱ;N ёf$mꝹCFV_hF[W'Iʩ3TNF^[ѫehO0(D0 +TSz=! ^fOȲ+3$x]!Y< ƿq7H_e^H|Nß(*\v+pv籩B19qJ9_ d>h +Gnu%~acA|eU8vY+E6&Yb{D1kr ZV!ՊǀPOR;s zd_5ǀPGZǯud_NR[(a䱼OQ4}8g\+KG!J;F!;Yf<ۙ׃jP?Ѝö k@9#{"!cMSWT QH xZMbA^$ߣj˖zrY}ng0QJ,3%6c-{m'> +stream +x=Ɏ%9nwEH@#<1fYYCÇ?OKxU/2"Ġ$&o/"?xql>|_K} @BCx~R;RZҵR}*R7Kߓt~m5@m>ҿxM o-=m+|{*Mv>}X?˿"ExsVN Wy G Rh /寫M˽8ň\%L/H %aҖ֘Ѿol۫6trz5'vPya+8~uw44B셒Vhj,>_(ߠ08 (>4eA5Bd| leq:c[:$?E@ӓf25{iJڙd _',2WЃ̿݉B<_Ir/H#|32kZ! =Hw}@FE-F X T߉Ddp&Mҝ(_d".@*hMʴNXu_4~'kg.,2 ̂.мз20,c#I:bQQykՈQp=Ƣf.5D]KMpR:FgnK]-c--Oϔu_zGYGcP8 {[h;A`Z) @ 92*'mQEŝh0MfZ#7aIzNTFWH4~+^Uksq6`ʸ7S5p?j&V?:%ߚ/?[umiqV_ X&')f:Qts|EV%εZX䲱|MHqJZK!6qP"P'~Y,sY▱W( 3$TGH7J1aK,3n6{A:fM; ?7_VmnE*$yG*E&\(_z +e>v~tGoe!5@`:}5-Aq`S&54Z:Ipwg؏DV.mHڲHjN^ƺ ZjmU$xhi^Os{鰬R8$bl5U&Bpv*p;U Kk*x`Ռ2e_f0}<4)+,Î5Yc $XWw#4aInBs&k p4*eX.>#aBa[QŦqE8 {PEjJ?3LD-?>0ޫ\L'4vkJJl +)/v⣭p0MR$R"ԉ8VHwH뽺H-ԈH  kʕ=DҮr@`j̉ + yƨNE +9 WHiwMt'#4P8Nh!@vFp&1ˡ)!}/'eu&3㛉]:P6I$BU":9v7^*3/ ^H7(͑v{M>^{5 Dڴ 7#xEnIsfV|HanA~Liʗj/s«C4X:C$%y¬\ [jLΟnh-HVJXYb7|bVbˇE?Dvv:ع; /aL=aӿԦζAcKfgi,އߐ):)8}8wR h 5f4aZ! pe$!_ /-${[@\ P%)EnWE"[XkYx7.,7 9Y;xR VZ0,u('s 9-}SF#BƮ493^b6gT7Skj  e~yx4,m*p uyn]Bp/qX>ay,г º>e@YDQoO yǮ~K*A_|DSB* M B)P9V/XcXF[ڂc]C?iQG c4,,`-E ~]+ZTwzݥo' 9Q8igI +IǓI QRZA:}MS[ H[NR9Z@C7h zyU+.u)g Si|}kip}~4N,@cm=gѣ4a3/LB(]9r=j4gߘ(*yքh)G$N?Y1@RA`r¬e[ ʼn>]._ Rr$,QO҃Tǣ7 2%h)}*Ϣ|~E ;7𪚖`KxBЏM< u٪Q"邑.;>@sx2gnOhL WT0WdSӨlQejR,6힙D?!04`> tg㞝[axԟuF$q1jk'h!=3ƓQOn9=(hi {ZNUq,,"%ؗ}(> W_t y f\-[S6x (k爚 hVXRPiu JӚk}DAe0k$LlڃژFi/X+\zWlSGW׺"]JYU3<_v.]=.33T E&0c:nDQmht)P,luŠ+{%!qŒjLC-]G8ÿ* cq_!X髞W0Pqm!F: +cޭ*ìu>[J:q̪t)`^l::ys"KZ!'L<+dV;>gRʙf@WR&n +*Tn;f8׼T@:3ig{R+}mܰBΔ!g:!5i?#qn0HMany{}Zh?L#,,,X&$ߏ \Ue9sD ex0ˠ*%`V jV(~0ٌUx|&Μi;4^{iI +-o\)DhjeX⺁T=T:QDd|~ˋ}vce55lWo9Yyk.IQ5 ץ=[Qb.ty:tGw8Mʗq3ﺙ:7ػ,kgCsߦ0ys(9;9Fi\3a͜~{Dh5gD]&޿p%?;w8Z\--tFҥ +zJ&%}ڷYv(I$}) OCӪSȊ)hڵd)"*2/Ĝ #_Zh0_BH\\ZUFHaV$Z+|\uӼcgfR6jµEuk~`rLu@dl뒺KU~]ruXԩT%9T*$imyŌy"tXuR:6(6;b-*$+r/1I/҉ښvVZ~kgn[ŭ]_~5At=!o IWx"Ƭca>:ִ\̊H@Ri09:Ga>?$pyoHx'#Bu-^ЕMA_WL%NoѼKA:WŰf RRN9(%^ݞ$cZam_(Nט7I}H @g3acqnVU (=z򒿟-v*[roGJ.p/^B bej5E +EAwtyƙFUђR2oUN R~oHoD I撦|%uVFY9R ˒p$i؇Q8$qrJOa>&!:z(P q̼Ӵ㐩eO?7,i1q>Haf HJk#\tk<^FM- {KR/uyT*-ljXETk>Kdˑœģhw ޹_ VhgS.ϳ~VLJ "_9;1eQ5(3㖟J]sej?@=_,8^TxPi闳@UAS@so%ib*߷x!ća3nIEUqm7?k0E\D<Gu"raY&ؘ6QҰ}%i$F, IZ@ +X9dQ~,9@5 ެ=oִ3R HuSlB^6m6(,AYe +o6()T~?gxZbu +kܑ{ [,AU.8Ġ~/8_1^6Eֵa?E%!z% X{vCEa٥cK=_3d#ﰋ_r|DTpD 03iԒV$/$X&ed])}ˉw ':Ft'lFǼ3;Y҅3l*_RM$ y+a+]\h]\ͱ!4IooJ +֦tCžP{@.c?Z[/Lv*S)MJ8QIJ>k|[Ʒ\62{=Dn -G,YǬP6u0u Y,5˻c˻mwy8ﵼ;zc>,]bgedԜLlxYKuוM1'BPOz#oyg BT'҄S.ƳTop%瀫WI9lywVbOedÎvp=:\|aʘ`0OG>8˧2]38_Ã=Ǝγ|)t,w&mp℔XͰ/ecrWDba<|FC-yo +e,PrL)KR*erԫT|xRi//Av 1)TR{S;(S/w) RǓoJf0^z`F\q,9a=> Uvs <'w T6_8>Ա0$Wymmi#[;g1\-,OscF> +stream +xڵZɎ+I3V@#lu3|Ç?LpQDe2%]b);96L4.M,k?Z/&  K: L+L~Lޜ9e?$.ˏ)bǿy=^5%`#\=%(6D@OwQ}uDyD7V;uR0~ϟȎzQC]$qF"8Hཇwjrg vTNf}{} MB':I~E[ +Տ">H25 z@2ӉS򚱍<"~ maF q{g6z O:eMB.ueHm5 ?%[.돰 +!tBQIt3!4\:;>Q5B+T64^Z۫Jkm7Bm +x5=ͮAWmysբBW¸y_M )>J() _BXbWJU!y^m{U6|km{B~O)'4PQ,P]* + #nҟHp>j!3i5^B7-E͎~+VvEi7ܣ,&"iЬ?)"Q:K5ykM1V>Qh5:ٲiSu#5%Oblxl0{kz@N.Jy4t +k  y &awgÏ6 |ecM]#8mS +%Dd _ +6NzJVGF{d]Ҹ@K@$|(.fΔ9d_S}a !-NN[WGR?R^^7^oFp"p֠ Qs2nC-A9h{;-f󥗒e',vk)n?ØGbCO)zP[`!6`eTabv*cٲ,+Y41W6%ou}m)5X߻K9 -_Դ@1z@UbIKaP++.+U}Q95`ID?:':s6q ӷAՎ}m$" =lrEH`)XjZG{D΢_辽`|ܰ$=ii sL\Hq1$p!,;RYm =: F'Q KpA6#!蓓 \tߓXHrx=d L괧jEuOr@7l&<6%ΥjNZ)Bm?ZkFe>S()m0-vp,߂ى[䪲>z\L.,%Rkf9-K#.Vd ϡ2hAZV _NUqF&`pb'"Ԝtz55~,(َ E%'C4VD-b&<ζo1\˭kJURƱifKNbO}\\c);vamIEC:'cl3ԉROi7*,`t|߭R|+5!*^QbBv+mUȗo:;V4?ҤQZ!Z[6i)_݀v]mrM4o)RʪJqwcؙh6_/%L*Ef n*.ӺƬR;nᱧ{uS|Y\uT::,i B=-0%@^.ן;&:"z΢rs˝۞ȍ:a5"8q=:zԓ HK]zY=>PgK%#,!Nn&T3Q>_p^s" /U4?_r-mUwq#+C(#/,s1Q?P/dGvWy6_523gVNNJcgt + +endstream +endobj +598 0 obj +<> +stream +xڽ\Ɏ+ +FE$@wdcA/"˒vluoQtHq|C6){˯ßM>଱tx0?uPRv "kѳ|g+_ru^Z!S.߻p|WK6- -4J[/ }Y}?b|6/4 |ׯ`M>o).kFC` D=8ylU}V;1.Mtxdn'|.Oҩ2X9\@R:0N %CT_uDZyyp2dq Lh:B6=2~[cSf㦵S*XR`X +oo]]IόO{x%W;9 wa&]6qwg@ +V +NqQt HE6+Z6.-\zB}J𾼲!N*m }ҁq d`xN[O*b=2 er&Rge%8t΂Y>Fkyzo>5$`Fa.vjej/96ۀ& g.5oRR@;vqjU O),6}NݞК{E,;IJҷqa 5{agPfō@p~^mwrY̖LӺ<5Vh Sw Dk[p¿UEb)H3U\&{kTpVY]A%o[wn~KCy˷QQk(ӪJD7".2;(+2(|qP>K\Tt'1Q?qZkeӄ8.OaUSrb#(xAߪ,g*?(ʯ73uq zzb}5_䡻A*$I=*5K/%)gw;:ȎC؀]Ik%ΰa[2nbI="%JqUKlh[{sVxIq;Ǵ1/{V3zæi,':z?r)^g#c뽞&g-e$rj^Ǯ +endstream +endobj +601 0 obj +<> +stream +x=ˎ$9nwEe}Zcn^} +1RȌHeTEII]v1MKKItf%_~q1&)1ʚt~Z{߾ "]k&4=y_:C_/r +6o_r{&oͷ.3 ?>b<-TmhnsvqKoۿ_V)Vv ]*47e< .NuAR|eY\2 'ui5;6b@Pvz=@kTSQ9[4=PpkG:޾8M R߁r0tю?֘%vYd_t)ojRęL^ġ +Ρ)4A5r(8in:(gҍMJC<4g p#` +)Or᣼ʸg{_+~0RAJ}y!V2\yuݚE껑A2ǨhAȈ`U?`<$1wB-… ΥɸD  ?<*3 ZA-O2ƅkk)A3hU@߯ъ +VV*XY+| PCz LtOLO,NGU2j<(aVCmjӶ;[=o5|ZYsT 8镼=5'1/4uObW:k%,oc2s3 c{DneoB{1>F" ˴>+a- 5* @oЋ~:@V.]Q dq>d^75pkek4B _oM˯do[L%XM\$#=LPD5{<2f*f5\z+?e.u"f7.-U'q-b:TxVVeA^Y*qe]"nwAO]i).6Mcrv+ed`J0qsW { Sxe 9m|p/'zFA-Y?IP e*ڟAwn^"<BhxY"k +SڌDot)575s[gE9j5gwvzRǣeRrյ7縷5N'y!ЏQɒ2UJ}6sT@FAmjl1ڐtB2x2pW<66Ge)RT`+r p(V \>;GMѳ/1KL<>&1i n$:86G7_VOϠD*qP`^rAbx9q`77@9 >`r)\W2ěHit ːcAE,jN\PFԋ n|_aӵԋq} 0},u +}s@>@؀K{Ri(astwc鸭H3$,#s:q Թ[T> /^.\b*K`&e Jyj*pQT(تķ1t5N#snz瓟n<.'[60Iyݚ +Oۣ-aSY-zP2~WI^*W/2])`07_,_Ǒ:FE;LNi]M@+m`6RR7DGgơbj >R`d4v>iʛ0Oi6OO S6hTQ (Nf (sP|iܣK+bMJS4Sp=SZ2tߧy(W'\Ůևl?'[0%\tU捱^KS{E7Ֆ^[FtJ$X,K$ }8Z'b`PPMma}CѸIa(톞x cq0CDX! C)_6LĤfN[c0-P +l . |}7gZM{ׄ"kɡҵ?m7N8񎞀 EP(-Nq\T`~=ѯ`TS +Vz/RPJ +t }8xTU B=N !wt$?T$#Zc,,nGEW,p.-X0yw.-tg% 7!="]IH+}h`i+eՊĺ♌bD|'YӶkW8Ynq{Ҭv_."+K!oD?ywb!nZyw$_ܖ kB9ň[p]m>=E +n¢ +6 xs 0MI@Fô#w' {d'۶ @/,VKђHV;~=9 {;N2RiInYd06e7Aϧ6/*(4HKDOmvɬ"QƛW%doD53xqm53'ɶH;kI_"i$մ6(@3TT:BI*9v[uc +NŸ%-Pb7q#m7SC~ƒ?\ +C4IhKX0ҟ>}Շ$Ų +BƠ=8QQ.~RqSɘO-9U1e611\rw AT:06FerzW vlgA쳩yqbio@=4戨`m=~2q}'6oN6@zپثA5!-[D0NUFSqp8xQD߉;S snp;E8I%E˿Naz;_[4%Xt;9G`CMF;5 +|ٍxȡH(AM(OXOX99'Zj ;p=Hȇ!@!;ptrOQ\@Y Pe2z]^F.v/pu9vҸ3l,T6#'x;؂+LJpڊ{N8yH3gs{ޜ6 ̋,$XGI}fҦ:ӥŧju9l/$tDN:|]&ԠsLW@tRYw‰=SAEg~= Xq4w >i3"&e5.!~Wlx%\selFHx`-J|+$wb,< ZHjfcYxy3h>gfS +3dIhSu@J ޸~hRq:K +8,w'Y!2g  3&]m2Rm|u/K#nEXk{enkaaMu>RkpPq1cHg13HH; +Hh2HhgDf:[-!CVzaMRۃ}94V`>׹܉B@7 rV!ߊ΢) RX2l(h ]0TO>^e8:8[¼las ˆK;r0fY3OyP8}ˆAT| +s!/.`h =~ ,A/\/6$gXm{&⧜ LE +|S[8*#FA2{-v7G6t +OOXСstXxoUkzڐ+z2_m;筹;D><)Dq33*XK= qptpdZt$Xtz:Z(qhC|\`g b{(ff|@m+z| 3ϲ-筂_79.3} IlÛ-QѶ[b׿tb kXȞoMIfuڦ7!qHEg̃rK2֔]N'N੝-w14>t`餅;tz6sM':|nnօEgU7/7 Kq+l`u גyN{+g/iIx#GɄ͐LL+CpnxՔzTL;4E8ʡ銅ulE,@j|Sĝdwm0Eu9hI>x=,ݎɉrc0xm`#i~drRK^R}Wvo|ٚW#0W ?8O왕?d=@!Mlhhf9MntwWxl+}`*h|!x/c2{x䱡HCƏQb¤-L& I9mzd/aHWc{c{p"ɽ{fCa4f6 P{4ƞ#T2MA3;&;n^;Bd*9l !!_"n鱆cznHOy#BXl92!<'DSzf3)GWRHt~u9 'tU{D9_ubY-ԧóZpr*S'e욚8v=ꠞlthYdİW { &\v\ӛ%\p)!W-!W%q@[cW_$Qv%=޹! GL] n@:8kyvry-3n.{=1’}2?W赕 +p%|"m_&M`_Zw7 X%mzdx}f6}KŚ(QnʊrU.{Nb.F[c+DZ ,-_۞n>΁1㓐HaͲIA<7r6fV4/CmY8a&9±RgA}yt*Yv'8\t.5.rАToz47ЦLB?1"v~S]IvIr:' J1V>7>Bm#i8 ;!N`=;ڙϞWRbx^{Ct Jb7S5@O$j?@@M?X:TSmN_mji*j+?Ud,O6*;Spʦ97J J]g~Ў5 ƅ%Wz^Kƾ͐/at|<"TJ}0&eߒmh<ڮu$J륉؆s'U&=& A;f;{rdk H$Fbn+asfK|fHBL/Gi`e7huO..r\m;T=:՗/rySK'GM$^ w'|qdLA¾bfM>EPFɲQMBRLhPOIdq*M[9[Ec V9tnxSӺB:͑=+\=_(z좈?Z;k̚³9$s~* 'uPح);$;aAo6b=DHڣ ]1-n`˺A0|D +KWs@J&HuoFĮ&v0HĮ'&vPZ GL2;NuHjN>(vL +endstream +endobj +604 0 obj +<> +stream +xڵWn0 +ˊHI@C@{ +&?#k:U pHɡ.!ewyKMU'G! !bt!(^9}<1;\U8~uA `[ PC@fPU&P-{8y>#L5[^B^xLU 6=/@pſ`w qtv$|0x)aqxݰAyq<&a2h(#g)oҼ޽ +endstream +endobj +607 0 obj +<> +stream +x=ˎ:n|E@+.z Y pvAݧb!e%Jj%W;(KI]~ї /.'\MKRɃ}֫Ekeu?i~d__ᛀOzc(Nk˻+DKN7sv=mn-032/~6L?.2td'z \^V`NOz}_ߗ6wT +aQ. D'_H06Ftll{b>@Va:@q|_A#B l#jZX 볇@9mi)orR7Oz1MxN(ΨIeIBwKΖ~',oK8JLjgVфTH|Vͬ[;j 36("@ Ydb^f!e;?8?iPCK𴓼(18[-o2Y})"B e*,X˳`y,ςta tt ;VmHQ3750 ȎIp1 `ggS3Oj6>~ܢBtV<ˈZQߊ-p0t(q c[F3l۳!Oōh$t]7MYΐ0^{5_/ɡu )㔳vEs_nX*.+Ձ*'%>jx#^MfI~=ȶvB{/cCfݺeb:i@yv򛬇˾gL *oY-xn.[óz72bx@+pOmc P8MK}+jl/К0ϝD@.!lK! z?&_GtABv ZӰ]+> smRu +?z|9UDBS-[4(o:$ҝ(fС]r`Ԅ91aX/U Tzsk,oX 1m:KMx5'\f;c_Ct7XnFnS.vKȡ- "F/lSY > H*Â20 Cf8q C0￉nYg +5MCa.$g[7vt qd~|BF|R#4cPb9 +.)98G$iz6/ LӐGFH(QC"LgjjH;5D1ohF̄FBfl43gHxlKF#'m4| kGtR3 !j!tvچO!G12mCB קmHI>7mcqi@E34 |Ra`F o>5oC|[Oiaj_K`gvGTu~^>  K1Ũv' B󚤙9i&uoH[qPb |P;% +FZШ- %4D|rzK .2KrMsifD[4TГ]* 9\^fOJzYa^npɉ/ ~}K/K,sͽJFGiR``8$LVh э "ut#!uD!p씞4<;K#i3vdtw'`ڌ1Ni(^6# Ee$H4|o>mHp7J7]K(Q^7[Aj>z? +hPd */s@pabE^Ba%'¢yk1@ܣ][cie7n9B]NNX{^?NlxXL 6P.x?3ӝ)oջ#6inl7\3B-P$PL4k6PiE6 jT >M[9L݂^۝y_f.F)t4.TIya{V079|AL% Q9WƊЊxL0dWFQ(~VъDi9sқ<F('sQ(=)}!~աzݨt{="YiuI˙^ΒB-@w~ZlH>R0,GtQp(Xe8(Y0󠀺#UBٰȏ eba'(Q8Ȧ;*t=fQ="UvB5iT 2JMmp=a$><qM%M_-Fbmmc$zd:bX>^iWL&6@vDUzWV {sg!0r҂W^/eyϟ*d0IGhB8.eFV6(glCj"Υ=_b} Uasl9בVΦ0-w S;\P<6%|hFٓilݠ@KIEC,yS`y%8nKe*St0$~dT Bp.l=#i4CָFqKQH#KQH'hP?5۱ K\҂ @hkm}M +{&gHLפs ƲH8TIOQ}}woe +A/ +'?"ix0sN\n·}eE&s9>G 5bЋLsՐrsOדpF\*Zei1 +W缂ɗā.$ġ;7*v.-v.V&y.dC]43vj[4b'hpJgRί/vьI.Vb78b ~}^Y5fn1Cˏ;??v!!vBP:w#@ Cf$R*]'*9W$.ٜLX +?EF)k 5W^}!ܾU8]3zݎ+L^w6|׫I*ojwJghHR7ݼ䜻^=$妡LBUB=dp=中] &WorH5^EJ0 +ckRRyMwK$ moQ.Dc}gd%W]Y+qXa<>*l;9d5Yeې2'tG|.Sĵ $ԯeXbpa ofu-ò2  B-Tp˰-0 7zt4ziClŋfy.CTއ2Q_ u)@aL,ړ9U'-Ȳ+s7M ijd"ty@Ν:tgj*4nosR^J6=[IB6(jGguNgv9a0c7m:Xj"%vqFw @ "Ӱ Uˆ%&w`cPP:lRWSʃQ]u%o6D>X^gѡiN3ڼز9g +̠lƻ|~@i)RGvHJ~R~r*,B\#"uDb ,.7e_`8j`f9%d%lK$ Ń͗.K]$(CsIܜ-[|+īi@ӳ@ĪJf A9嵪 nuSv&ti]μehsN 'Κ)VvlGg9J4:"wLA`>7nYaw+:8O|bQ[τW@<|Tw|7hX;W=m WՔ@PURMP! :ԇQ%-K)-YTuL_ +g +endstream +endobj +610 0 obj +<> +stream +x]͎$9n)ZH:,`O 𡪫ۇ0)Ɍ̈Ta z2*"DQ'")osTLs? bW1ʚtim=K~jop]kw;KjMd[R7Lz.~yeRo~/6HZb}/VoMb+mA74 +XT Q7fQ;']J!AR|k\YrԣĎca߾YG7*;n5* Ĩǭ^5dOjaQ0oiA.b@ثs@9q*3e:6K#W޿y=)>2?nh;Cc Byq*.t,ʣ_rtM4۱\tM58vizL `J0}ep^SKo¬kø0#d]\/n6{cC\HahSYy>Ob\{e>.qS bntt? }LO:ŗ]nE~CO)XSlLܕ\xmZx+cg紃ɹ4ZTw +C S#` X"<+ڱv^Ⱥ%uF߀r+5wКz~=4,:IvW!yx: +%_kGȫlWh\ +O0zC|%keh +ذRɒ~}F[e:[6d <4ƪf)SQ@aʲmE+RT`/rOp^ \sy|N;GNJhο4Č) !6x^&X!T|@ۄZjC+@lW>#Up*Rx>i`oN3@9<`EJ\\{6ʩu49V3.sb2Cmu) ZojVDr=ǐ.r5iSNç*x>cT{,sV`՜T^]|I"͛RL} Wb%w]'Zz-੣O'oljt3_Y~ ?{?\K2% $͒/I/ժd8^U䔔RRvn%2[ 0LwY9Y^o]G|zE$ُ 9]LDopxk}'&\$.%w}IEXY샌-Cum,Ը2T ߶C[䔁.D!6-%# cCu hO@Գk ICk"blL7xIh"Gm[czKs\'@}mk[Aùa$ +0"=OAiޡ3αQlHʾbG?ٛg !h'r(<HIځϫ׫侺]Ύ Ok{&fT]i ~eĤy'Y~אBF8zr&#}xV|}} 8xq#qfH(1x7!B'gi`P5ۛC^L'Ph~ +v|Q irSM}x +8tM5L@e nieL$vd1Hdip҇>[?dr\?x eb65{Oguh2?_=Hx#z&k8XGIJ# +'2đWEa $& #C +XGD+|+D {Otl™ԳX$͕Of;'L/Sw)/i\` G7Ś7rbe)0c +ю_@q*mPhӄPHz߬b^-AO27Ѫ>a$ZMWNiP~sxea?51:1w#u6˶(,r {ඤ,!-q8j8q_ 8|Pp/_VzE_QJ +'ܮϳ{ehGm΢lEȑ0,*ۆw𣽳l$Zb i_+lsFwl7Vpp壼$3Yt{[p x'vCpW go { xb7| H3x!Z܊O/g$˙nKW|4(+U#Yv
    {G='eTM͛Ov]֧O6>@ٓQ6`)2ee0Hh?agǤtULVjJMJ(&hI}j{a(2-{znLH[&e֬BD,'4pэX62< =d`$ȫQakWH\xJ[CKDoZrYV 8O,c͓to}$}_a ӣU@(e%#[64m]ލ1Olҷ2;Es*ڝ T:yЬ=N`ݴ֬ +bLu:2z vU>PI |$V8ƶB2LZ _m|Ȟ=·tOZttP܄ל1P=R }u3_ǡnR +@| ĉEټYga79uM7xf,Ğ*IV7E̙1]d{;j@3&,,K57o=!i }i F|%"GǵBf+y.[6M+tTlAAρvggk^LJѼs8q,DN{1c?y2cJ`0G''7y\}yoŇ:'8COf?#P}z/Wh + S_IqpF?jrrtgy>٨%Ǽ.&k^["Qq7OFFI\ ÖY٭–9]nwEp:uD3ʴfMɽdq!=AXbPդI _& uK'GWr1ɟ-u_! < ԭKQ.37~fUIOTf' +HKI9J}AsΫuS<XtyZpch} ʅ.r'۳_oBBΟ"5^{*4f}n-9<Ҟ u?u I:'ܰ+vRcP/h g-`z>~eSpwqe=/?l=6]M=5j`Rqd^tk #-L|pW'm_dn_T\9?@tO>qR!Ǡfn =si. RM'{h/b^zu*O4_F^tS=q|OO{rɦfWyk-,0=t>dx6_au +endstream +endobj +613 0 obj +<> +stream +x,WlGHQ"@ .Iq=)!I;3:yG3(\4c..E^?-y~W`fPEw+oheݑ_.S޻˗KT*|v$^/?~xn |՚p~$?Cj:u1ͻ on"y|!7`uxgq!NagW7 =JAn0No:yv,Ld0 +!<\ ++ s'*B&7c3Lf2. $e$zhUf"(oqEmĄ'Wf)cAp*X}+Mh@qemb>]Ԥ40Я{D=EݘvHZk| HM &Q?G$);e|#$ D/`Ujyavs)V0NOT=NTDjiTGQ nS訖QS o+s[ ;*cHiAOѐfv(6?3ÞoˁP~;mQFV^*u̼a? ]&B`EFEzDdI cR#!ɢ" .Wr+W+;7 a=N4s4 lU(e"JM٦pKcƳlud0lysG;/u/KUmx%I!ËM~IT~){NjҐ,+CPr\x(xGOSx*iPjX"7jώțu~| [,fH3ת6bRQtE'&E5s?s<]ǥPjI.h7Y>_'`m0ӛ%jlPv'6kAjOe2R{,>rծ;^*h#iC-TW̍Ķpg=5JލgɈ*s)8XuVpsS+lW9g [r +[ZaX+j4*gMn:z(7r,F44^!ۘ| 0+afbU6gغ#WZxxi=UoΪ>;V"Sz[*ϪPdYI`$:M[,pуU(q9tF̌-R"2=[*"\p_Td΍ՠok(IO+㭖e߯3Փq|;>U,"W<:v]1<x?;/^Ljl >K]TdY mԛڜX{ȸǦ~@?݋d$iO$&[7Nq b1lIZ!9 _o?x_9z/NޕRPg°e g +ϗZZA1@>$B59DJb> -WtĞ 0YA_##i*lD!MUV^:$vkh|IGtoVuI虇z +}=!_FA~)Ob3WCi."vd"._6%K2dI0vvN).Co>ִrg=;3|[f-K=_|a"K #z2gXb)OOx/.d.7XJgƁO)HZ'JՒL37%OT]&cGt;zOKr<`Ԝ/uMP>[i2܏yzu$θ*zC{xSJ20 ©21~vG(dEg 5|zgڂ +df5`kXz#Dd_<"O}|?USщa\ªrP ُ31l5 VI¢YYBc70ߙ*.++S"ruK@/X831w>bCfv`:x3NAqJj|WӀʎc:ӏSN+a^yxQrҐ>qfFwJ8[1!pr"nu=nFM=䙷 ]4p/}r ˜ ĺK Go7/JK 㣽T\+798v1.c}v[A63JvIo8:HL>!}@4e20Χ)a70OmLUɬݤȞ+$*G8}4Ok{*8r17{IU3bk +endstream +endobj +616 0 obj +<> +stream +x=ˎ:n|E-E+"E^HdV]E?b!eӥ]R;s)⛔ \,IM.6_^ A? rMֺ?oCg-yϰ|zޗaЛq)Rxcyw܃uL^_ +yP^h ^>+12%4{\5ô+ ˋ/L_\˟w_{eEś ./ ذ+J./eFRr/8vr LS'!*{=4Ӟ)ܛi8`__PP/zhGq@, d6S7@_*ϐ~,!(}¶\8Co;AbY7RbŞAN+D&ЯJ ]U ]U ]a-[I# '獎f RgGi`MM@045ߔ4&pySfj\*~TN--aNߩSF^ĂH]h|+da/} +f23 sC=# gufN42~XlLjg1^{'9Qc KOâer7ֽ*.:4SŅlW5\ okjͪiF_=ߚSQY"s t[ &@GqP)*0Wj:RÎ$y͌@k(@#,?>w >-#-wH–&Ϋr..~ºSl0ĎhK7͙Kh,tkn߇S-^:7r gɳ[)Е™+%^Mq7%fn6g_Mpӭw:-r(x$ +ق-cOI@`U@MHtXvGqj͞7O~`tq|crri-R-ԧcJ3NXH31BfYE}+l[c+ooliɪ}npv\ѹj;K㌡PҐz"a LUIsG<ɪ" K6qŔO2kDSubOLUOJeCq'?E:{8V a@] A9#(}*Թ' p|n-a3Kd];k<51PCi09$,qVDS:;{iI,MB&7, qGyG޶ +=lTCd3'qՄ=NpuV1N YGi:n ;eH69 CӛH6P~%&l~f$vddiS#WqHfeVN3;iXH`b[xNiXgL}N )J?{Б4yPtycvZ 5S{66Z 3vZuAÀ1rI !XwLlkֈ ܰ4}`U:nX&^ע{~z<^aW5ƃH +amZ[iT\4zj\V@(j5jUjg!rdKǎov f\BZ֍o]a]f˧] 023i/DGfQxX#u/}v*iujwB[. + T$-wP9d5`s ;+ֽ_5꯿1Hp/v+i2N;eӈ1urKl3ܫ a0s{2tku<%#߼Ԛ=it` z %-]ewW!DU4')Tʻ%Xyt LNI{#\)n h51Re=y1?+7b,,?Z7&!ֳѲYKS0҅r)[mэ^ñ^RGx5Jk4/^&gpQȝ= Jk۞?Hپ$*CA#: ԡЇ^f@|D L9O(w٥\aB %&M}C0yEmz3OCl[qqGĿ#=DaBRs{ -#aub~:?Prk>;qLjPla?vZyi +8Рo#㫀Kn#c[wVrN -\憋o5PD|!=邴uS_X/8?J|#6f_\r 3"5Bjq"ף^_0C.ro~--!9`[ =-+,f;I +ٵA4#ц,QWdP< jsm:ً=P ;hN{60m'3{;QYlXo s9;Hj;ϙen(asu0Zڎ1%nqqfeb3G[Ԑ[!!+a*YvgS8O[}J%јC@PisAL+Kо~P|eGwt𶋚rMN͡\E TK#qf? UGߩښQH*$%H S8xvQ$ѽ;0ƥ~Tχ"߄NꙆ>dI&. z T xzC7aF%^[ܟdkΓo~n$O$-=)- {LFLl ^Q}D}Z+JTQ0yw]O:܀Nu$w03@NN6s[tCt{Dwn3].9ѽwDtw.<8I(g񮖯y[9Tlٻ9UKRI=LS9B4>%f(9u"^EfКm>m=C8'٘Wmtfs-4ɌӔy(lCm4q{*I 6t>Ӓl[6e˳yhBbm?bKg~~OUQ9L$Pd=8[۶C,}- QSu +ؾ%gFvId;ʖjczY+RuLl +!7 4-c#H[1/hJtpdžb;VNl(z Y|zٜ;g\YD rۼr p6ϗ< -SnvU &r;wJ&['I9pfɓ5!m띶,Ĥ+l6X.wrL$<_IW\ +endstream +endobj +619 0 obj +<> +stream +x=ˎ$wE%z:,`ۮރTzDEeD1IUd(Kۿo?s p >no{ö́[RɃ}q3wQh5Z{6km_z7~b+jzJ~t.r`E <^lX BVs︯g8_ݴJZY= coO(@wCT 2Л}Ue¦S)VoOѾ%a8KqL`;{W(;mO +zmTukw{&:[s= 8*lcj"H#1G񷣈?6%#FCBܗ. gJߏʠFt(t쩄FX4x?1) Qx:O7gM`^aoʚ3gu͊,\|eIW6oS&=wz}fO⯔GF&gD n$kddX@Փ gXcIDL;^Fc\|eޮq+O2 jYXd"?QspH =VU_ +( +( +`^  c Mg8o4`zaf3#uY; f~?xP̭6]jӶvX=o5|PZU--aN_cF÷^ļȈ׽hD +kegg@&{F@7lಷg: m7,ӺLgkcټV(L 8iQCo KdD; c|k=%)3UO*9Kjx3\VkZF#S+qɲ[>@ zN,1diЈ讳t o{XлA84 WcwR7]/6w62Į,8$mhSќ Oc?2 +Jl"Jz&7Fp .{!ܿ:棠Slv3hr[)#+3WM'^D^Z+cEtA4Z s \?C&A;} :\xyckSƌ$ot[jr4~Y7:#hM\\]|u :UHaoeL[Ǘy-O\^DPFtkGdLm_a fH%U FSC>F@DOS*Y3)c0 +)dcN'{*p,Hz8XIps[9h"7ҖI N3H`PVDiMA +:]} rYAZ(z/pU(Kps/Wq{%%%[r4%~!(G"-#Orq|NI`%y .K |fyB,OGnh1#6H/Ǭ3"[_r[ٱoܕd5X3-Y!=䉅m1Igy"zb̲EPP [N,U;]|[ vׯd-Tr~/&4 2iͅ2N~h.B-Z-K$FEwɿ&֚wB:UEQpP"71SI/thpϦ P{<^Ys32)v*iFTbeU25uUUЛ{΃ZɺVWv@,̛L2bO2)*oLF!z 'TBezE^*uw,#0q`"pfZ_$2`?MA<'GM*c^L o*o8a k9ɇǵW-]KHIA8۫Uy6*tȁoAe=S $ HMsqʄӚZ 6+ nKZ:|Z0^4"nCԚ\׬kuԁvC"vlwr'NpЇ(iehv: t6#WÜ li_Ӑ]Fh#=ԵVl?` l3!b.X,34$9 ]O!Vq((:r#FeGF?,\"AՍIV\*H%J >p´O@q߱^_5cpК6 di `Dk@H aTPd*HInd*X_5١"sIPJL1 +y i?u)keUI''`f*2$HVgUd _ȸZLhD,oMwbK%Pk}y9|M[4d͹lF?]ץAb4ga'Kab˽XdI}aN9h3\BHQqC'() ,!#X_X`/ܲbZs03IݯI쎜o쭻FS'AEg_Y.nS#vm~4c8˹2CO>àB[D\';1Yۏ ķr] `$3IF噿?- K>0@Smd#ٰ(hF~} F-b9p +a͟?Y9YR;ߡ2p1u"^< &Ȑ(k,=Y2уhU;6k,xgXF-fs#'E$ww$r?)DŽ @ D2%̳"p *eXB.rffv6tߜV*oM5Z. Qܕ3@b9~oUAꬠK9wzILzFMqʗ0_[/bYl͹9p f`Z/+X3Bףc-)1g-̈˧[%:A=Uj9s^=1rcwfsBl03Pr_W"MІOȢ&0I~FƁt N]KgAWe N0j'tSY'%'o. =z+Hˏ~"|E~??*ao +endstream +endobj +542 0 obj +<> +stream +x[KoW̑{gU5`vaЁV[d:H}lq{J |Gu.s[rϴ x%Ƃ,)/ +L]-G/}1rOKLuB%%,X8bD䢀H W.g[$%@`OpW)B$PC4 ''N,)u"%Hd0,J +- <JNX- drL$13 D Up9>0Df0=,El‡NPG#8pPCF,:iN 2}M.bL3lˁЏP>ӏT$2f4\QvZ.@Bw^a_9`7Gq9UHS3 `pnpJ1 zVς7}m@HNN0H 8ܖʬM0Cc.5`e)qfb} !SMaU"h4ǃ`RN6f,`PWp^+(Ī + H. V +BpT_!Pj&BE#ppyQ "pJILs$,%3 BJ5RX:hvaf+W*œPdwQX |Ps mRQ'*IH +^XᝋDFhF +bE޼_XYWRH\ Rjp&R_߼Dryې9mdAA4V@B_\?>^×E{|B XPP]Cix1˛;#Akfh9wHYt=52Pdz}jW\|Xl?5bS-^/>:6zmTկ>V?~^no_:o{ˋ_//zˡ$ԛ8&ԃ 'Kj,38lw^j$v] ryK~4Ɩ͸=K{8ABFn x +xxv2y +NR7z 3<xŲvU e˴GDmnH?@"KFS݌Ã% ,GyࣽrZ̪r"00L>ɾt׿ԧ M is!cav"07ycmj½ y$;理y4Y?u=#nUY(#`̏ޕ"B1WffEQ⎱1& Pܖi됳+XF'>D>)3k<x i~3TtBNCҎߛɑ+vܰݜR:J +՞3&= qǘѫ@hWj-ҳN{hwӴ+:=;uMiۻ"c,1 ifO1 mݝ;tڬi_C7zD{[ 8vh3 X[C崖Y, h0|9e9}C 1֨9mnfѮb v溚wd˴+KYG{EhĬ +0S`l^æ>e[6?U |WSwֺwX6ڝ{bYڳƦͿw@֛?mj_2 c}P1jiSP>pZ{vkZvu,?X `Qs{\ cw_rY§K^N_!/oM_i1vM7_cYw+Y,z矟`==\Nឿ_ӊ{q;[XץaQVed{={YAVz(S[qC:Բ^G_1կG*W]<ǻ:lY{O5VHQswg=O38?LdYή_^>[1~YN'ɚ/S.OKVV{tŸW8X^eV?^~HYx_Cm?՟ACJfnRE)(@(e=!?T0CB8Ȁ⯓f9bXC}lobgף_?Őc‰7֜S8!g'/~)?ҸJe{#46>ތzP[޾ΟOGS/u;>Gwrg $>щ|C~' +37*dԷOt.)x yYa} &o- ĸ>y +4;wd6\!r!p +endstream +endobj +855 0 obj +<> +stream +xڽ[ߏGr~_яCSU0l8KlFD^6Z-%jl6g(a1]_Ufnp)rRrr ?P8*;f}8x l"9P@&'㚝'ЉW:x@e..kt!Z"D ^WG]G3hg\4Z?W4@ )h`0AET&:,dh  T4p;:eIHK ˋwS +Ҡ@ <@ <9cPjgf5>↥*[2>Z䈀 DF}0(NF^ҘI:@$&DRJPipR < lS+zP@c)A2 \A&M*XY;!y9h@A$;ttUb 7\2lEѯxCY˪:͈BbbRDTIz=V|T~ +%^ׁUWH.Qsn55`OMST`?4J}`Hxv11}.S~MpP CQXg 'M[QzJD@i+[EtVb!.(uJ +࡫( bJ*R Rײ&:)}2;ÚǬ:(f9jyE&A{72kV_8u4+PpGQǀ~QԃlKFܣtƅ(qU}A`h(c&<zKEuM4-U\ǵ +`uES'Q/8nA=+yA߷xbp/ +>C^!#??=R#W@ +ר^s_ָ8/%.#.k4?s\B\>Wk^f^0ݕ| )P.Z"V!-yh֟Dl{Ŭ m | +B>?F٢{pgUhٽ*Y1=Zz*#ԏGhF_$Iv͇⼶7]t6^?*>ܟPy.s@.8kvuQT87?($L+<4ۻ7(zO/owe{+?_6qkm?N |yxu~ W A0lpeq?zOc){a͗qO _M-mYSulvUvyӑIaɮRװ_Wz4&Z~aY?n SG6KoSWNr>\?Nָ,MblWhj6e9Mש)g?<`ػﶟ?z~]fɨQ5\?QuIZJ3?̈a[Lh `^!2L˲ᓆGZRlfW,6IO]bLa؋94bZ:t"&lAvo_C:i1R LWW3mh|~iۓMdsL-/{ylGǣWX/.ˤ-ml>z}} Rm哆'y/5 M34ӦnlBvsG>Cܓ3|9?<ze  i^jƂ!Eo"cj2~Y +a۾&< +p~mO#۳Ob^9Cӧ经.Z@fZ}モ64!/دgv]3KeL70z%LIE.pz)LιYskF_f*-pӓife'_9n9c}u~2rŋ]O?a_jY~_>}ݡg2hX{QY̱(99t,rpzm_6?n>m_~DS}3,,3p}sּ>=i-eֶ4B_vMXVO{B+@797n?<훹v~b#-زi{V36_6Ι) u3o=~0xw>_>MH)=Wҫݽy~wW| o]V:BzgG2U}zŷ~U8*STcE>KT/^*݅J%T*Ros]TꙠ\sE\tE95Y\꿭oJ\}Iꉴghz*ꑶǷڮn\=p:W\=sգ'W+\=4q-_j6_j6NmM3Wݍj +!ڕv :+c*lWLZ_zPѳ68s,7&΃%h{!M]6KĖl\1I(l2̙KZ7W8xJK1yȰ LЄA +0\+?D&A +E!Nz. +5栢 i2(zWi0ʰ Ќ*HZ+M\74$C2<$D2D$B202Et+'>22zl[⊓ +Vj}63w (#5k&Bv:_PfR"[%wV6cvLK&ŒiA<\+ +u 3dekzVZV!V* jD}vOEfEE^`Qɾv/}Y\ɐ ِ ِ zeD9 <_@fYYtӑԠA\Qe;H|{@Xgz DKg]*UDWg+pll ;[g%>PvK0\Mi% MbFgZ}.!Zҵ>Dqc&c>>b}XPbJf+,V(t_~+V*XeLbVBIPN ʊ̞$Q™Y?`X/<6YY++beEub "֔)5+*X/"|IQYY:=ml9ĭ 90{I1=ʁX9ֈmkĶ5b&Yք.ǔb0,b0,b0,b0,Òpk¡gd?*^*w]GGV +b,b[fu(( +endstream +endobj +972 0 obj +<> +stream +x]Pn0 +|4M%Bl6BbXD!-=ϴ57:Vv`Fy%B6$/@i*e9 Gh +!&zz{yoyt43(nu'n M_pRLJ}z^תKH8)4.$ ^ ˲XӔ 'xޘEVwG*ۓ(.rEU?mK +endstream +endobj +974 0 obj +<> +stream +xڍV tTU~EXME^\"DttPUE: ʾ^JjWU{$H QnƥmGnm=ŗ93zLs$U{?Ƞx<^6=m޼7kk9i\6boK簷+2k[(E'<qy<]{MzýeZyIBVUQW"iU6+%{ Ҽ{W^ШVUTsn{G=k<:/oMcuiޒ%JI]SaoDɹ}m\U*jeIle;rsTUʜmD

    5} o7_1vv [~荩\WLW>BCe[+d] #O ^_n>Z8: I@}uYZ +uJ]mF>3{P4vl{˸uc4[v@z3_`K}&X ꦽ@$ޢaa?*Aϑ`fTAC}%?}\8 KU2Y}g #&r;:_2³Қ&qX7r] M[7l{׈3 l$?mv9h;lΌqn찀,.kĦ_ĬnP$w4(6׆Dd'g2ݢV4LF8h&ʙT& dƨ .W܏2+a2GMO?uB 1>nw8aRmrp ZU"(pݡ7?u4ds0N!p3X' ӢzDX (Wp;Cݞ &zEj'E-$7@# F~,lNňLz@W?Cf.: %O4'7wzZ-6N,^& M-"RYZ*%Q"OpG~_Qkܤd_C৓r z]BQ舐s:m4WJ;;~g7И'1$`h*r7 Ԡp 6e0ɕ2:rY:U"H9ĤaVܻ= 讟Ajad"1yvGݳitdȪ'rzᕓ5'psg +E\5;`I8] +2j#;&Bavڹ~HhG6Sc NIw +q)q@$CFCWj!w/aD~#8&lTӻ!m' 釺yǯKjvᨿq9\5Wife7x桙 5M<|_#OOqa7>,ocw~^:Ë.×/av\!$ҾƺKN?rYZQHElD#ӮXܽlt%;* +tD]|OAEWv$Bf/$)DO92ȥuYD$7ԆOљl"/'pɜU)\5;v +/q=BXɇ@R]:uS\ 0O(nT&%ڊH݁}VxQq!ܣVL}xozbW1w'I.+-xtf~7~o?g16,8/is8^Hk.-n֋)w eR;1|zvBmQ?] +ї }(?,iѢV4޳P| 7'Gz-x 34N񎾆IxǻЁH7.X:W>Fl'Ad2=uNh[?޶W/%+m6$YJz *=%V;ワLN~/}g˅ 1L + +{::MaS-R铩%ݻ{FU4Vȹh৆@SsPI/JjUVk8xE `h*\ӓ1#6jmڦj-A7q t@+ZU-3"-78;ڬX勬fb]+6YYMߡ7)hw_8|>K`W C}= xn/ J9jIfka׿+|do ckȠ?:ug4UyWհi~tnZ[h) t I1;rǙq@f +cDڰ˦4v D m(6/tЗTRv*~>R52aS_#[?9*ox {XZX&ubFdo=!zЙIJ1uwS_ÖCY'/ +]8ھ7ώbC/M?1ࠪnΆJ]s xȗ +$u٦C*3p3 +F PFt ZZxxAt/O(~|hdP8 ;덥 AKO(5;'Dz˱o߇-RPlƪɒ`g_d8 +Lj;@vp cJd䆭r}qwHWPoRPFA^"YdR=!>c/$P_/JNw'ޭdT@C7x Y65|tJ70yi :sm .C()*=u_OYD(YIENnod[ȹ27aV2v-<} JhAƐ)Ltdw,xHڇ>!iGA{h0eF}"jAdׅ#)x p^`|]/, +,\7 +endstream +endobj +975 0 obj +<> +stream +x]Pj0+渥5҅ ݖǘ6Po&L{7IYk<$Έ=tJK@hWd~+nIR=!|SOKAbB.E\y8Ժ3@w3^iaٽ;NvײfRRQ.[= #q\GҴVUA-ѕv⇻,á ,߇>’UL 1bDib|&o +endstream +endobj +977 0 obj +<> +stream +xUT L[~gOh7͍]ME Z(*m֒l :ʹ}{r11YzYgel 1'>yabeueqJ{_M'wX#. I!ØpQL:S y T +M@m*O* !o {QӉ0:, Gޚ GfD+q:y +eV؍⬎θE:ȓ&&Hz4xF)%ϓ:@ϡ=XG9$6mtSzQ:1 +׋'u9Ԙ%FG"QCy3ZdQwd8b3D@VHM]uƧ \HoI +Qg_hy(f%-zk~ޑ|(;g?şQT((DAk d{j1]p(Rz8;!~Mb1s ׮Kx%Ѳm[+]ǁ'I ;C^LY5mmo*2T$G$ +"Uwtws3TojxٽW5c:gY=驃vaDZ[CXWFoQ59ă}Wx)(|vP*YLS-!>DG_W OQ>-kp|46O Qܸ^x֖5NcN`$:G3XC4 gBNa>J8vx-dDF~.nA#33bLNRUGeC(JhELoiȡ\ak9{;!yb#oI J WP>)޻ivwwh +&;'†= N ~ 9 +6/5mxI02šu%;Bl4> +stream +xcd`aa`ddv M34 JM/I,If!Cy?VȰ*VD@`|&[Vcg``_PYQ`d`` $-*ˋ3R|ˁ +y +I9i +i +! +A +Az &¤tT9C&3##Kk3bö{gɒyJW.1[ͭmBۄ)~g$Fo3^X#\tY܂nI]gts”)ݽ}@mM6|%o^1oRi+[yqpN^u{^O=g,\6wℾ> +stream +xE{PSw%D|@{EobtE8Jq-n +.(B A .D^b!Ɂ@%AH +T/Uuvtߥ?;o;s̜͗)wl_ɻ xba~Żj+֫)YSmA$>5M#.X.\NJU+9[;2/2oGa"U, 攊hN(e;1*%sSr\FNJPoz]QqJ'4Ej"VNd; NJI`u"5y/z_({ʁzzb#r)ZfEє5A|FEsaC6lk^Nl\SQ5R(ӗ֒՘Q=x@]mI l6)GYa>yq axpdQA`}Q0U_h|z&y.e%3XNiS=6oϴJR1i$mp.WU8m;L@Cs(%ښ.˜)Xs1XO}LR_wyt C쉝;#uǶ߼zC~v?%KY2/txoIk5yC6 (^w&gӷCp[/qRaa:lƸ? b/Rm{kt7?5xu%}:>Y*-9InGqP(  ޸-U *2\ rȍW1+wX.A@~'cCT'`:\{(2opcbMAr!?KJ$YWV=2 -2!4b!N[73)&1 +{qd%M:k5Y +yݕc 1c?*(dq8}z͊07O}{bx +`@۬ %5l9^M/"%kJHZC;gk>x /@!PH:duס=9; '>BQGx{5F*ؔ̊xRhB8KRKz(Vxqz6J+aos*Aa$][WŗEx\l> w?XazjU e˱dͰ+,xٓ/Xn8X/pY&!N+=߽0S- Mv&:w17e]G"1DKPtae T\CZVrb3x5^]p%IWbƓ8fn=a[FqDBrcz%A_[oN \mƈA{B2%wͫhB1 I[$>& %D[fc/>:-Bgp#VWU4Itb;\ng7Yoh[_?)g +endstream +endobj +982 0 obj +<> +stream +x]P=k0 +4QJ>^8\H[:.q!/A='))YŴ|9#Z0*-.fuaIi G%Ipg]T6 {}:{m!?jVqfz4@)Hw xا蔞ԗmDΨ=(~0:'$4M u]_P TÝXDGax56bxQmE +endstream +endobj +984 0 obj +<> +stream +xڍW pgn!Gt80&r[@ 0$@B ! \1ccc ߖ-)ɺ[dC>dlqHf 0lBXa33o=VvkKI{}{O"%p86oڳ{׫Ϯۺuʩ/IYNha(9p3Mp/-D2@ct{;E: *[9͑?Qkyu6@(MRe$;q RnPBvepJ&Q(bi艟xD#F howŬL;EűRiUEq7ZmOp 6+2n5f0ZOУWՈ+Q`JMD!%Q gB6f+&կ sw/`746<6uu +nU4N@Nl6X`"-Ve#jFzNP_re@>û̓V1HG !@t4훈O64 ll߳p1'ǽ9{d/ɦA?h1,0fev'3ص=u=x +Cu X-Zsbd1 S| KPkev\{K5SHU *i)hVj7:VKMPI""fsl[!Ln-U2c;tAJuAL2z{z0 !ѻԔr;o94ٵ@'H]kSe5-1Mx.KcѮr +">z:=֪v_c''m::ap\K&G`p~sib jtUL2N::_/{@[|c 4-ﭦvZ20/,Lܠ?v'<! ߉NJV-,Q{) \fJ[bapz$KnG8s*{N@':8et(zbWmV2M4ACy,y)dCi;}ilE_Q`,W)s>ك-4 +&8gOrǙyox%ysG [|2h˜ zjHYD۾*- 420WB7oݤva7!݄C8X@ueL7,~CWZ:ߏ96{!ܺE&RBZ^jwvPI.7K *O9Z8oǐū"3eRrvn鎴z]q/.w2*5nYtٽoOt5iP[rF8W׹(ۃޣ``'c`<KL˫QdxW …i{bގh:%of VAVNHw@(L"\tIi3jKFac^FRնP~l>gh3.c@mߜc)| \{4 E}_#rcQD|wchȯ["~8sWqTI|}ȧ 'X,ʦelY^GmguzNJ]Bs>M?Յƚٯ⢑ɇOc׹Ljsm2~p cgvWSnhPKr؟Kd9_לCG>shuWOvCE)**`RjS(C0S1kegބ/*Q!8 O쾬0Ed$\ K6=ȁ +q8@q + D,D6zXo?d.į7bs[B\ +dz8S,g;G<߸x4Qq! 5}R]ErCbwaU DUۑX I "oA}l% x଻'v u m +D qαiyn* 2 #YUf !z!?rqhn}Qok+v D{KWzkzLyuQ}Npރfau; s|<ݺkvolө)/>NaM7 Gj*t +endstream +endobj +986 0 obj +<> +stream +x-_L[U=N:Y1lC,$Lt[KK [JK[?*({@sè =|Aͨ1 >؂{r~OCS +Etq3/kl=E^:/ז=]GzhHɗQ(S9}?)R +FndV[аu`N՝j: r:AoԙPOd厽l0뫫fs8Z54Jo2pQ5}/44htF=K]:(:jȢUS'ZJGєZ=˖Ox+nIMJ,X!tz]Se[bq2Tw !-UiX: $+W/h&O`eIj-QT lR{IҚfe>m>p"銼w*/{ D3xD+#b_:ԡ,š|qr7ҽqS?'~p!,9zh.nݬSuOz=VIگbq^bn pgb?Z][N&fBj4l2܀Y$ *'R@ +0 +OiU(VH.K"*oK1#Ѵ0'L!rАvea<䝝Z-^HnRI"-p:N~ `Bmbx5ϧ/9gCd4~Q х\1sZc.Gi +Jq2c xcA #ܽuq۝\p"MzlT &|/:+H~,1|ěv'Q{uC#G-7*J [ i%S.](k@qjh/^?: +endstream +endobj +988 0 obj +<> +stream +xE_lSufױƩp{Q0M\ +J '-FŤq] k;oo7:ڲ'\E6Kr$&c1&&C &V_FjΕ{哜Mߓa@zfמ.P^lʣnj3D[huמ4'ԔY.5e>W~N BK 4{R/unmͷE) >/}riýQey`KSP/i K}7CwQ;!՛W ("1:B*H%AL:O1-O-ejrQw{Awi +85h;{7v\ƚSpvbLIrڹߢVxyVݠEZ}ST&{㑒*ê4ͷFM%}C[@ާjxҐb'ƹS7PwY%,"z Ҵ]C㟇( x?&/JMd/N͞>e[/-[턭oo=`m,VR#M(ѣ.B96zGdqY|m /?)+Xt,.|m^Ps QN`goD]NIHIx&N@<(kM@ܴ|ig=]#uWy BCy?w!Ba+w=ZOT%=^EEs_: f/an+lPo}᎕~fV4e”VaF'񼉾7eV+o?bTq֜q^ +endstream +endobj +990 0 obj +<> +stream +x5klKq濭K49_܂ eҸ,X,V뱶[oggjLV3k׵(ufa6@EDBdty^ +i4(݆͛,KQqRX+%A\JU2gh5Q1e 2POCY8*]Vqh\nx. +&%rĮsqf-VιBffwx*`j2oj r͢%!\ q6v-[.ᯘ=.ocxwf6Zܨ.3| DY*D! r˔.GtDQsjGw 3u`leVLJފI.E򉁁ܩ2/zηמt_>^TɱV\֑Ji'E$5+WlN?}NjKtoE(;:63MіhkCoAI^*QdlgTqX9xDfdlNbkXifLI޶T_l+ XJ aa=_.D"t |пѹD/}g:S$ҺZI6']%e+$:W2iڼܗy}1|W +endstream +endobj +992 0 obj +<> +stream +xoLwzwӢFy=M4sp(ӄtQ iz2umYBAǗǟjc Etd L6G%$d:Ȝ afd;^'y|1q\mkxXa{\'IDK .?8kQc)zݞ²b.q2M[̌6db23PƼǛ,ӖrRVG +o7޲qY%LpǙ=|3Z9&V9%=oU89;csr,ðuX"`ZET`8l5<F|kiWx +Bj)3yXPY#'d~0ZviS:3tq&ve ݰ#|VIր<%+w6(2{gC2rDq*+2?}y(^Xavy22 ܤI7 wZO^ ipCc@}u"]Fwe/| 5PBPn +DQ ԇҊ2!!hnIf4IZ*US~qxJi#yrI;S]B8Z-EJJ=pN'D5]AN @yS5y:Vhl\mWgX棎ÐD45 p +Ӑir%UsWPҷ֠J6HqpZ=סW)3$zL- +endstream +endobj +994 0 obj +<> +stream +xcd`aa`dduq v4 va4L?=b$YD/@:`<'QZi``g``_PYQ`hii`d``ZXX('gT*hdX뗗%i(gd(((%*ݮ&s JKR|SRbf:-{rECݽ;:8Z&LwŻb s[={vO7?}Ҫod]0 0jFٲ˖/gh{][}wGC5C:>)mBEMY8uٴeӖNYY}ӻrJ[nfw }Ӗ>ܾ~C7)%5E|8O:{| SXpN^u{u?" +endstream +endobj +995 0 obj +<> +stream +x]Pj0 +t# c`ivI{ѱ԰qNa $xOIQ+<$?Έ=tJK@hWd~b$).~!9狀~-.v-wحl6Wf= 9HEpnݧ4-ݷaw+i&kq@!%El$rI dw+ăY,HJF}`tO#oCTL-?b`Di|X)o +endstream +endobj +997 0 obj +<> +stream +xUOSWrZK8 l6s8F`ѽZ -FPt@[)(,.04şLe?lDr˖=9ϓ9C +A սYYSg?LE$> tN$IYX\t w_7#dQ4LȎi'N.,o[ӕXd/nl)_zln;Ov\fo9Ϻ̼kYy`/fpʅ5fn "TD>#Vn>R I?/$$DqHIIdIP'+N>IN%.K3A NԣUD<AZ5l'@O+51[i5/;Vo}Ǩؼt4LBϔT5]GthrVݣQǍOÐr/}L #8 +, >ܡVэ ^qǍ@y7p#ycg{+ؤr*-fl[i5llKa2 +> +f%𨌰j#3> +stream +xڭUkTg!m"."/,t-"!,$HP5K (@BB$*)/ZZkVx|ú;=s{=ᘫ+Ǧ-7{/XV>~ibyJBT"U!KH+Ԣk$ +Eŋ2e䵞D) +(\)gEeR(,>M,=diJX. +%Rp.|Va`X&S1)c 6 sDŽ4l:6,m Xb6cl cXf^A%.ɓNs tչMuKu?l%xFF;adXcᡐQ-6ʂe9*CyhgMʆ Y2=A64SSlyC߲$!(OjD *0@9QYb(~Q+D5>yVx'x?FC%;,RqG! H7Di-L9Ocvk4%XwM@KuAs~! 2jXkEGQ(y&_cs}Y +jX'A2A-?z0rfYF߲]ChD7H. ҤM(,߾غk}pzD׆G0@qM6K7Λ|z:`@Q`8@3#TKJw>8NI.5%IeS'T`^8DڼTlC~f{TRvz+!rs]<&!|mNafwQA8mhEHtH '6`ٶPnmmseԄ۷a1 ˣևobcجٙ .׭GhyܿbǯGp X2G_Bc3uC/@Ilm%N3,,3#W??JO{5>?jmiˬQR:>#xҠFHbSZ"rb\d=sB +RT#Hil)fw`h: r̃-}&-zڌv桙̗#zّ +q +J#2k3 -}E:QŻiWʪ8>hڗcJ,1bɉXn ¨s;TuruFA 9@W? 1aH3f٬ʥ +yZ`uP= QGQt.ot|5Cc_ =7@ ʩos +j1~=&i/dK>f7]xSKCn%$H]@Xj)#ᙅb8SK&=wElFkjN~d O%LSV_a*vtvϞ nAª"jm"ln:V;["ɍ J6yGsPIEW2HM%>KIWEcVAL>SRA~hM)i&ڹKjQlko(!:ь?3F6edʬ4jnjX+TEUq60s .5W[K?0^pS ^YM9YE_ 2Z8EHDz>KhxUx!>ryS.6L:ny8YnljuGW7'H fD;Tq30nj F *eQAjcj'z$EҐIpѩ= #ۗRAC e2]E)g?D>ivg%&`#L@7p]mUɭA*kj= +PmH-+~0WNh64f>:ٹ(D1GKde[,.]H၉eejz8'[:"n)Y +endstream +endobj +1000 0 obj +<> +stream +x]P=o0 +<^UU| w BHU!14RI"}I57CEVvaF.v%0 rPZY±j3[|__{dgP8>u-gnF E>p]_v%{E[e=NVDfBVi EӔ ;(3DUt'W}oAtk79*mM +endstream +endobj +1002 0 obj +<> +stream +xڍUitSeiJR!&GQA(*bEG +E.-nl훥ٚ&M6PK0sP@Qu0˜29=~[yp8oB%e/=_~/]P8y:& ZȡE".=/E |Gr簕X̖ILpx)yb UWT5ryDR(eZeKS3%V|bҕRN&*:^7))Jk4eumʦX*ҴP͢ mbZ(zA.DIŢ)Z˦j\PQb\(VX3*b h!dj]tr\l>1b-XODTUD5Q"4s ]QHV~<-[6}7RwiW1}ƴ梽_M^ލ|gc z*<x) _wZAnrvj3X>h{rpP2\ާq13\F!T/ٌR+z_7Њjf򚗆?'ᓣx .Bk&8&8|HSn[=Gag՞>wJʟ/.-R}n''ٳ̦^8X(VoT,Wؑ5d F/8vFD&MI1zèÇs8Cs|I +!(-_-6lh +^^?ǶwKF!3Vx/o ]nH٬੡{>Fpx !H[ϘTg J*&g¸.@[%mvx$_̵ɝqV h57 pAotjuN_Dfߝ6͏6CZzy< { ūu %#CM#NF@-,'p"_/ӑe +61,GFi ^g:;IB AT|%SJmܹYԺ.6Wz@kLawyVrK*~Z,9fҧfK uݱ#;>]E UvcF| af̬N!MF.Uo8>Lh',w!4$V[ e]pg ҉, Y"=;ý&"}>~CjpȻLpqJu`Z75t A zە[5_;0I Q<'HYCcd*3DLQ`x,; +<}oiJ}7LB0G":tSB[[]Ŋ O'g>,(.56Yc"|i_ +endstream +endobj +1004 0 obj +<> +stream +x_HSQsn3?; +67 ELdLknn%4iX*(VZЈzSЇ͗A%(8Ny_>}P x;F[\AwZiJVULK[M7Xk_vv::E":j +5#OWWg+jwaE֢F'PT'PӁvqWPsСVdm\cꈎ.e հ--A 8 (ҫ3C~.4%+MA +|* C '+"X k Yp,)')"alJS4f%lʑƊkCX {,n;'0|se!?hkw9͙cIH&gf@{yxzuvg9[y([J3-njCo܏ +endstream +endobj +1005 0 obj +<> +stream +x]QMk0+qK)&)- B +BmK] $D࿯M}MK&ߝ5N)-Be (b6W> YT/_YI]s.#HVyl˼ Rw$?f8> +stream +x}UmPSg@@[%;$ږAP)_~tU+nL)!7$e TX]u֎juuvj՝nk]Gu<7kwo?}<{/2,ˆe:kodd&!IAIq40_!+#edt0mt&"aPe&ϼż)dlLL/39Ĝdb0?2u-/3Z-%E 6SaZ_0_H>iA4Ȕ3SM,&le&12lBܲi6 61lX\l +ʊeU01$$ǧ~SlK YF[4XdXUWhUbKM;*X\Wj_<'PUh+0RaVZ̆%6baTǸѿⲍ6ՐUjXK4 ƳL*Y̼ZY;`Xu.v]l7f{^zpLs] XpPDu!pN`kAMAuz|pdrym;YxjBp?l?4=;r npiv]-^5 +}2*fAz/,zS0.7-l+\jZzhw;G?zŻ_8nz| ikV55\scN3^L +.L +LbN(7vun(}Oea1R6NGf;.Z^EkjM1~)D6JJj y1j@tLſ/x@y0ZX}Á +oK +َvco9(9HR +ʤ\zt۔x˘MD.g㟜T`7Ulc +n؟y1Sɜx$}S5} +]'ttu +ZMgf˹ oـ]tbϦC}Nk: Uʾ>i@]xjrȴuO,bE ]Y 4O(/FsΣߏc)^9JT>FW 0<~ ~g\AͿqNUܫ!Y+Q0 +Jld$5G鸀bRW͢L"SI'J 4ヘKS ny mNϒ^)gO0 /PP ]_I3f1oD7x+W)羼m<910IiyK(9*Q;}+KT5vu[FW3BN3(:S$Hd^TIf9Xl/LI.2H,=\VRJCS@VEfQklƇ=i +W Sj/t˅ W2cJZ1p)N#0 UW[L+^rQأJGwI"&2!= bh(W[[t\dV쯆$?i'cIk#!u MNOɛ IddhhjQm]uwGptҋ}7k'?Lea$j+E+Y4YQE[0Lmʋ@m֯LK'_iə>z[Vë5s졙4LeX1hnA;\8z7~q}E3`D=t?Ǹ(S\vwAa->,Hk1 ͯZFŕms)8Z~v`LG{1R\/unͷ6_[RTnBqoO& *a4HD/7 ªv## + Q~:M`ui4>+ +endstream +endobj +1009 0 obj +<> +stream +xcd`aa`ddurrtuv 4 ضa5 YrL?=b$OD@:`"-T29((3=X9WHT04Q020TpM-LNSM,HM,rr3SK*4l2JJ +s4u3K2RSRSJsS%E +)Ey@110(ݺEk_aK3~sK.-ꮖV]]X{< ˱ K.3WPo^Ӓmճ-陴b{'L> +stream +xcd`aa`dd rp v5 2C Yr?Yd TLB ,UzFE% +ɚ +: +F +Eɉy +%%@NBp~rfjIMFII~yy^bn^~QByfIBPjqjQYj[~^_bnz`ҵ4'p,nbOu#ՏN6wFoIsk+~+UiI-Su.v6-[yo:O7gI/DŽٽ@zUVt61sA،3/=|wuϘ ;j[ ]:7|VbBM_i}&OU}-ӻ%wM0{O)ڤ ݋jrm<()]m]9ͅ^/1e^lmNy?Z昨%W>> +stream +x]Mo@=R%B"6P*D ?d!fQE!Ό=lfR_c_ܤMWʩ4BGnIrX,rQN-o2*ow-M Tƾ-;Z?kFq"}~Mw^ g?iPOۺ?/~޳pkg*\l6>m(+7-ֳp,\W No9>x&z)d("A11-""KvLPzF3%&BAN@SXHWC@.D 5}L(% +3 |!YO!z제58KCN5!j_J O`pҗ +)5(X!rЗ̠2#Ĭ}%'}EL+$ѳZHe/Zf2M3+$]2\X43:BseޫvC̷Y +EkhhC{LHkψ7RDN[: +~kH/B!:ksKVqߥ~=Pӹu;NC +endstream +endobj +1031 0 obj +<> +stream +x]_k0)X-%#Rdž0:?(ClC6V϶t9Z^fkFFqnڻ['wiTnWm9,k9|+['ٗhVݢ%::xu~6Utm_߷e'U~-s??q҈ڝQmZ'?~Fs/6˟?ӮO|oxzώ> WN2Dnvv/[l& Vlgp]}Xw:WK??/_8@Y CR&RxR4$@dA{*P{kA!Aށ%X +i{) +EC 4wz`A@N֣NP'TQ5 $@!tx0$xHYDլN$$ $oHp,!,0- +Xi'L1Z, ZR̒Kb#6NݒPY -QR5R5 "%I"3˷)H1/,>g1+yWqe9#!l#PHFƘl)BR2L+i@Y :!9yS'7PL' u(a]HT sQ8SO"$aOx#;Q +j:!mNj=_tXӹǧnyU#\ +endstream +endobj +1032 0 obj +<> +stream +x]A0 +w6*% EնUz%`(d!7ʡQKf0ޤٶ3rCy13[[93 wWv3Mk.XՖ3.b 6g1(z6{$h\ѳ~߯o>Z ^Gۨ;zkZq=?1 +endstream +endobj +1033 0 obj +<> +stream +x]O@~>:Q !12&{5fW9lH?*oǮ˓Dtcw{m NDՔm1~-ysc|??"yYuMc ֔᭝mq:{ +O(skQ-sH1N=vu/6@Y8xU>/~ʺ䯜pBDv돋+;Ei]]m5D[6]}Qv˿[ǣH[O'M{J$ HIҫA;Ii2u +$cKAPIP&_A +-RA $O~`@@jyQ5S5HE- z B. +4 4V𠐙M=;=<(8$8PƒAI 1=)<R$\R8JtOL !3̐,Ŝi(3$ޟ)Ԃs)Ӑ):S̒F> +stream +x]O0:nX%eKdBٶ4YձAv 94$Gf:;};/?T'7k+'.+DV3W]9G9(;'ٷ(lpe'~vz}h]??F˭[~^uqGBQ&pzL}3v%wp4!^pq_g?}|_gv'8\\xv5UC/[mx'EVi[e|8;ȀBLĘ% bKCy)@(i À,bLł m@Jc8;X Lw&xIQ_;cvƄ.9]2 /KhAǠ2B}>jpXИA',5in{j/4V2>gA0?zӲׇ,*B=A*9Q\~YXYP7J:*TY' JjS *.ȁBSSEAyjC^X[r=o}8tgwkm%~00 +endstream +endobj +1035 0 obj +<> +stream +x]Kk@Lyv[YX^WsȢ! |F|Ww;m='?n#^\nge] h~6߽b{LIvx>[]$f ]6 i&CfE+8DŽ$}ͱ:Z̈́݇//g?CC^?9=1Hgu|\+ g1C"űKUt{oOS#"Yp-I)I2dA[AHז ^۠!%!ڀ$p`@p$8HEH +Fڂ`dI0R|&ȁhDzсYtX@F_4, -zZg-ILNh&=hp$8($3)<`IpP讁88:a`$YF70b`$nX5]Sgӑ8/xmZT ˜ȳE2GB+ bϢ׎^V;hF$up0㷘rZ,>SfB6qqLhZ{x0.㪜Zwt*!D] +endstream +endobj +1036 0 obj +<> +stream +x]M0:nX-%% l[,rj?C}y=t]xlǏ]CW2=kǥFԮAK'x~NN}3n%wPf/z/˳vo#;ӓc "^tDRPi,+VŮ?ۮMrq"D)w +iC#} t$ +rK@4\L +ހ J&xjOg'pv%1m(܂ؓ ;&XT0uJ$6Lؓ LriK +0Z)"X[)rP +S,}1n=ŝ0nO4i8 AtӠ 5|&j9:dq' {"eO&6J w -\,zkfb>Qr;2FG XYtK$w-˔V*I߮*()TJtP4>xN,dczx WtLj{9a\v?w7Q +endstream +endobj +1037 0 obj +<> +stream +x]n0<4C3"4RTuZ54[0%-CyAq|fqjfه3D3M$.J'y:%H-&Y?H,S⚑@S^۴7zRcI7K0{4 s ݃_|GbEtf7lK>}Cn3-/]GN Oj@oBh$ %;*!am/5n9?㜯*PHZZAmB: +Y$ P "!N<~jPڠ8h ?%&@e+A܆aĿeWpâY&45v +7_*Ɇ +endstream +endobj +1038 0 obj +<> +stream +x]Kk@Ly?v[YX^WsȢ! |G|Ww=m='?n#^\nge] h~6߾b{LIvx>[]$fm[$_U|lO7ߌ!D:[2(]}^W?[ҵXƟ̷)]ogoTgHHddIn@Υ L$Yȁv{TP $VLCNփ֠΁H42 YFdQ0蒂 Ys:)S1d dl b2zᮑӒS9- 95yKBgy # ?K;20/F%HFe`H-1IL ?$u &!#q^`sM3i~¸rrju?wөf] +endstream +endobj +1039 0 obj +<> +stream +x]Qk0vv"lvncO$o&w.*S%SKVV$gZJd#UATz#BT> +stream +x]Qk )q٘tK#]!ncia\2!Q1~FK&*θ/xz!;Z Ghq2JRW;ꅸaĈ39@ّ^I;QڋFvFMLr22Qda99-We8ղWP@l\S-ޯgC#w'͢4*K. qGQ<ewU_ft)r4.s*>Лzʃ. |(DO[bZxF& +endstream +endobj +1041 0 obj +<> +stream +x]Ok0:e' SCXlRث[sȷ_YO67(NǓV ~9ӝiaҽ\GI^^uK&YD,^R/puj5Ҝ~Ê}:̩Qu8י"m?e9O?/u.XO/>O}^h:!a,ۙwgiq]zrJ_gu+盵#MƓ r9 u6F_)9xʄt#[76/UȱAm *bzGTc؁$Hż@U"mA z=*PpAv j4% [ +"#Ap+PA­*p+cXn%<}8xZq59?aø4}kӲ +endstream +endobj +1043 0 obj +<> +stream +xz XSW \Dksޠ+UmkkJ;, Ⱦ$'a7 DqKpijkuVki]fwNmy|s~{D %]fׄ#}"L472a0sG H`0ϳ`ocaqlS(| ieJpK傕(J" tyuM<gԍ<Y2$~pH,)&aDaa^VZTU/03y˚Ӗ\6f[)Wlh@C-4mn`;y+y;.+Bz~I3BևxM"0̺;ba,NǮx0D @v~`g-\D&9ψZ8&>!0: ij c{g϶ƺGoa`vm1};V-..b PH_H!C!wڼpM92 H]Y@'@əg%}VXR#!<~m6- /J}|o:,d;$ؑl;X\/ X@xA7ѵqY0ƖFX &O0T$Cum{&blVK">5[D=>M381;Jt AXXPh>IWyns7OVB3ƹx@/5/!?3AA;`k-&(;h| [c[n3woZWfo"uo@b] :۞M)ҖK^I~,=.PG Ae 5e}z7hƆJӄ*Yƚjȷ֞8\/GeAYs3q㺔x]F.MFxAǣ%:mIWQ{Mzc,(gTgA=tR[C6L|p}pRI`bY M y`/M7jh{2{>,"GxdIg7{7`[[[˟ܧ[J0 +.6o_ec_b/s+ߜVk 'ʽ9aJLGr^o5Gq 뗠ilf ʋcH$;+#ړK檆jmNVN"~׮:mD9.9.5rȃy,(hvwRS΢J$kWvH&'[&gSP@6PtS\.[079ae#З`,"Dp[ၣo}V׽ibzݻHC0 ż_/5S}p8$ q4am61ȇt7 lCm1R6@38 +v1h&GMY{JϴQC!~{j3xSap&a80By1'CG*3ѓ6؈~s NHI l}5dB:Z,#u%F;rXzSӥq;Z[Cc z'3V/lӺ$Z +亣)^_c=! 6Kˋ&ZFhޛ7hRwlT9!ou9yYu(#7'=ː8 2"RWS*\%Q +iSܔ +:9%eŗe*n]tĸlNjhM3_37L]徚Ueݜ9LJ.XH9^F^x:n۞=#TP>{ +tq4{MeecR敁=)v#<Ϙ>;!&#p}l&"\Eim;wP~Y Dk rMH"pf5 +喼,(?ț ։I$Q竅TP³8^ ++M^;;.B3d t٬6(L]r +&ԫ8;RnÑHыUk?| 8sģy- ,l}U=+WTAi}h QMvឬ:=wG&c[dd\gvf\ǔvGYT-]|}П>ؖUϷx0:qKg^vmlf:~K`F,O?ߺ-o v0k ݙn_43PӠ-Akh&De5]kk-&w[c9W+ =HIPmK_(_UKЫ[&3?γ9 vbd<)m-ٳqB+!c>l,z}$X;O~^C)AlJtFXd-dwjJvg''erfLg%L$OH-+,geɥX,t$^X*S +@T7 AENتC V"# 02;$YC/ +{]` 5c׏cBVU|+S-p6 6Z댭*yœo>=Ƽ6<_[{ qW#{6rP{go oU5*M63ed˷1 ؠ7!gL)Yϛ+[["}9&cODǫ` /;8CD`(x`k"zC QfxnOHx`[1XywrS|xM[#;{s^=כX%NMC6a&-l>=uşSB㑣a;+ p*oC' 6tlKCŪbM[Uy\'/R +M"02x)I:~`$;v>b#!V, źzH= ~We{<#c_s4ͧl[*./-.(jq7E/j\YiDNL7W nx9!cI3YoNlDݼW"+,!̊}hH֘N-;o-}gUt djr`h5f)_a +RxlS ɭw XWc/GMgLgYv4]E Həs%)=Bˈ?GI.{d&-DzNHq;j&̲`9=nv`$"HťHW MEu}Xw%LR:C*&-H #$ ᫀdbb' )+IJÆƔש*H_ANp*ٶ3gT^wD5e[DW%ffc4ɨ]vjRwl3bp%'7}<K`<|#̧ 4Al7?mOS,i gX0m7B˞#jӑq;m[=l ǻ; C~Y,n%RߖB#bTً3Wt:LJȟs!)~ R-eb!舨ڨ\NXcd33K}ž߇42nx +Jr/eÿ#rYRr~9N<ځz?$x%s)T-K)nOXNpxؚef3Ff +1|=w~?||d'8ݩI _^veYMcһN#$S9$ ŰygIYi7فs67Wް7) n_ +endstream +endobj +1045 0 obj +<> +stream +xk``0N\G㻿GL +2,AA&" A +endstream +endobj +1047 0 obj +<> +stream +x{X,$a\3: +bX7T4Qإwpb( 1Hb$<ܛvoLn̜ym=/GB  prx1˽}=M7AY6rkmBCl|a!cmVn o{{{x{لɼmB7{_b<,[m3fMiƅkBw/ +gܘyKWqZ8yܱ6>`/P?v,'C $ooÈ–I"Fc8bQ}.YͲ鵬nވ|ZJS?A'oL߷C/ Gf!vabsY6 v\?o=y㐎܇% 4bƈ +mKlFyxQG}|jlF;lfu_!\H.quEjmzĨ8 nƋ ۀVCW\LeR+Je%U7u njk/Jy7ғa+!qޠd+㶛ݱ5ߍj$r{+a~=$F)3hjoO|`ݐwSv* M9.u0g6Y+;2acus;h|av();7äFrVC96FD.'5x2o*l(ZJk}xAT繫ڐ5jkQ=JղDo:Ȉ-ěxVufW3|3}\#ܡS><~tY BYp)O%|Tp"mb[ݕ+]9IL9]KI=Afm͑XZP +!cm.^wc]xɢe˩J(o)C[qH.Xh(ԋw3Za* +ݔNsmˢb7mNSfpV#RǺujvj3oRH Wncڍ8HF~u=('D>1J)!:fh. pI+BrS6Bop>@B~&Jf'e +;s Az$1m6j \eP^YWT^LRDmZGE$gԒ$Ru>WiB.~}؀}mۙLTp>L0LЅ<vid2J%Pt?5W4Iz%\ns4zta!lTTh\DSiE6~ͱz."Z6?l$##%"QjcF4 +a*J6|lшƒ/w"ڧ#}HsqFA=>Zic9 ]ԩX4!Id{.oRnhr|ZA%Y dV̺Lt_ȠE#O8{mhRCrA};t)GҬ$Iii9aV1Zh8M'b*m>`SHQteEIPϱo#k;[(e [BSҚв`YDhp@UdEMyY-n58t,5j^Ȱ C:T%nYFU*ʐ)$Y_SdA~w m)\ 4{?[-\٥HW,zlYi +V{I"f0̓69cn~a G׊sq^q%_BD$n"-h$GBGąTMuL"˹{wrKl?ʜwr6,xCr8P.)K&Fv!!s{ $T%ĕ0$(jDb8|:4+QW3Vql,%pMu];L1A 4yH>G򅗮WkܒdBӿis(N|]e5Gb/@ ,^Ώn^56؜͌> @-6JE/T7__\Jpvz:0qN%Q2;.J/g9̝|Vشug!`` @Qf)*VYl(g d!YYd2~(E5.*na$zI0nÑ2,p E`"g&m"q=U_K6f_fKbmT c}'+%͎8Fϖq7KHvXyɦIm=H4дsY8V=@1V9vG_ ) UוT`l@mFp5!-o;bEmy[ߘ|ˍ߰tUSl Ӷ֗>,ahQ=|Yh6t,:KyCR^A&f0\[@h>KI %E4գ"gBַᙻeK{=ǻC*px+ݍ ^Kdۀ+|*'ѱI a,:`;y$|/+eV. +0ńJNQ#t qf#bTW ЫSTɴĘ?q(c^i0d?:x <49D5I٢Գ셏$F["]nB XL֭E|8I]yecKքKڧ+ywg(8Ui]P>9y3Grd&>!o}-[lؿܱy 60~SgF I]>j +f<}K'"9$$eиgT FŔyZ}48TRH^"EZjb67sPi%J*~*z4Sxy ?G%^1gqʝD$rn&ULzu+8w;j g䫁>[Au- #JK cx_Hv?@df"fm鮻St4} +_ ? ϱtƽҋR|o1)! b87ѧMJ-$R$duj}0.67%AA1Az܂o>p `ܑN5)XIOlMq.4+ucM|8sz3oCh"f%np|8NٱR9fA-nIHZ)y\KԵ y7E +?! =TN>ŰWК% m`7Fz3>Gd\݇{&pzv_zf(nFCc1,O~Aȏg''h0O % Y3GA lcǩ;m gVbba'ރS yȫ#o#Ew~_N{Oϵ<SXn~_ '$r\6q{CO2*f~tEzq-KcS@)CY\}eR6{SڎkT_+OIk'E&:(SFD,ҽXZTRZ]_';,Stil:&9U( +KKjp 7vN}~JA';Y9^Ȣ<ף'~)GmzfrIIgљ r$f?t}['WUp)>D\~PU+Y8g nD8+PUvz>7ȳ qaA`u@uˎ,w{`\I@CGw }MLl512,!Oʠ> V* 'yIql^v^?aGaXtV 4LrJ5d}AdCS+(b~9~.{v`כsS; +L>ڼ5&GD3y9̫ ŃhQ0Zl vGIh[ %ΛХ^ͩool*qj{#5Iӓp-3J=: ۼ&ꪢqcGRjX,(㦦HHov}o'p,KVH_kxxǯ-i+86Bʿ!wʥyxMB +:T@;E<hsl89~4ԣGjLq-frmtq/?vg%mA.7U4Vi% E6MN:EXVSkua+IG|p;`#99L;N# +]yI|R߭}!֟ܝ{)vQE쭪W>M=5rlgbfynO,(,: I}\lԬsn~@PEԺZiAWMsG7ovY?cG;TF\pQ- +cx<$((d)^Cn7$ NǴ]R#IHZX\Sq\uz GCҐ e;j#K Blc:>gdaE^@Zn +Zb?3Uޫ5(Jrp>u@W7aHLuȌ2=eLF~}o8R=47 + v+] 5ȧu[#h&QĢ]24"]63kx6ޢ̹[-.#>?ݵ?ȫ&Rw T>:dO>Z.]YL!i|!|_4h24ťGp2k<vF*8 +#5ٴHD +*$Dm#(3 !߄oZڔ ɹ[2"&#MQJ4f7(1:ִXzk1$La lzD1X,&'5#'eEX'UUy\azlKC@}(+* 0!kǸ͚hZNNNA Ҥ3 t~Ya&ۭ٪e\t9t$ߗ15mC_UD2ҳX8nJSۢt^2w]F8 |ǧ ЛpiokIـ͇2v0 k09NP$'=9+N7ץA]R{JXhHMKКl*7Nej҃}H Œ<60tbbLY#8>c&5k,j1z"g*J֦eթf\C9ݸ^s=uzn e} / +oj痵ˌ%WUq~2LofFPdQC`r>4 +rB4}T?]nV8 :ە,O+#X :\)ni9|l5g3Dk0V`{Јv?LYǡ zO!)t +D]NbEwJel'3pD) +w1Xr~L0'DG1C#(+P9I E&^ A(=(g51OvnHo7790NňGf84agru)#pU)zf}0Sk|HօP)>EǶcNN*i+ǧ9ágoQlwk_Ny'ަ*i i݂k#l[tZ-cPO(x::C㯐UqR\؆38jGÊ@V>£t3km^ Z0NLġ;Iݴ~1ɜ. hi,<"/; ݭgX0#1 2(, + ğ;k"^mxG-?ыFCG-Qy_Qb.-.KNR$7mH6U-|]Tr bC֕[Lr]WrCyBZ^ZQQST^‰~w +VV9DXgD!* d8 +=DXG ??)G"88M= eg)_9wQC\Kcc"X?Q];`JBMtj:Vi?85/.=Eq⯦(Se?EЬC/g + _ҿ^ >1ʒvEϏ$6/$ :G53 +(ˑ^کNE_;R84FZYX]ΐG.Y液AeP%Lċ+<KʫYwr=Lϧe5yMIJQq`ڼyll))^qmOo/kV?UbATʒP {xު~%u׆%?6g0y?m-|y66BFϓms +, e#6-h4<[keI:h]WFeS$umݱXP|+[wk\u~'v=KYgOkP&^~7C/[J6ŸN-eayr 52ޱʳ3l+=eoc%)zi)=5tC^fه +endstream +endobj +1049 0 obj +<> +stream +xk``1_yX0p`&AeJ +05k. +endstream +endobj +1051 0 obj +<> +stream +xZ Xڞ "cLlTzR^DAva E}_QTZmi]Z{V<z'sr7=aFa<o˦Vma$+m-Qbý$v2YcK"Sv(4Ũ]k!d %&|sMo1,a ì =a?lwo4P`?VJb#"ߜk.}'X" y>mmȸwE3%"o/H'*GH"gًFd`7W# +I|Ek9oJEN{|C#}Evv"Q(@* {g cԜ^'J UB!kd: ѸA3V= 9*dD{.}Om[$֞{%="paB&TgA'h +=Y!!fp ~a@RPumGg)R5w.iȼȇa}/}  +vėq*~3T䷳,\aWXJEg)ujk +g@S'ȃ|^ +7{m +|ZhYdc+yʡO_ؾ41OҔ$-qrD;<8.lӛM&;P׈<kGv2ͰR,X$ELHm +'Z׹a^N;vBո}6F-p9Xa$dEF/W( 0hG ':BeؔD2"6zY_C~S +/Y_xn]l8%fow6o~ +.(R.(S5p) +ژez!op^mDt֍-g;-d [e+V>JDEGޕ8$%ǝ\3ɱAet&70r5 켜<:=z0pLqWmHO'cˋjhG/=+[ITpZ,EwmJLW@}D1?,n{}&M_Uz&p9.4y'Ulj3.FMwXZ "UxG@{ln'žl!@whj5M awvpM7x!ohe#Id?J!̷piPhMF![ɸ?hbXeB6G gx[( +˘zoT6ά*ґ 18)90{ 1uhҨ>h蒑 `:Tə2(~]KgNkԶz\.h1Ax ).̊eU{ɸܘ]'V 5GD|0N\'2o8׳8naO4}:os7])i ;|e+SU ߩx89ݰyQPO58>3Wv"maCjoaќ=>CW9)D}B}!sw +?R5}uX"N@|楯6 \z{0_(/@oZ!Zȥ.N.-̰#><-'2 +- sWU1$Gڕ|y^"* ۅ׃6q'l2RNԱ8!ro==!7W")kHx?:VKp@f^]4a4qHFO6I"cC|ל ' p .==-&̤mIL8:W>n\aHC[N1 +A +ThTq +Yp<>ZyBwV'#֓UDVG͝tk}wΈKmidRvG}>WQUqAxoJ 43ѩ|.$@qiY.}f GΏ#uh&~ J6 ocnM w7=D(C?hgZ]QNkEZwQe=G.r4MNC{0phAFՙK*OQj&"~ JqsN\TDHF"d2p?zt=8Z {/\7+դ4A=˻ iwJ9$07=wnRg龦cS +<IdHM\myc|MAg?ǪGŎ¯]VMНIMboW_\Y\Ov\ӔS͉SWz%3!brcY*UH&2Opo ϑ~۷.<1S!N./ Nz~sC n9x÷oo\# } B%bs9Wq Y&dt[{ZqUsA:Əzoz +Gd2M9$ YF`t^?ӏ~U F`8<8-[Gïݹ + |p۞.fyl+A(9] 1'ZyQqd2=#8Xa-_d΅ݻ@ hgK8=N+sr q2TKQ֨Թlߐmg Z>ƒJ4bG2KH& bȜ:= unejq'd=_!vTr0ݖ:(pWp3rb>xsR +idjZB`ʏa&tait[ 2M(wf8^JSiJGfV2fuD W?/V1=OY/LNfMA#.IŞ~=?gЉ]Xa[sdp}ʹ.1Qvh3V c>ǤYZ<돆%+p"S =4%4fbpaWw4cdy\Ti nGխp9lOKQ*Sȸ.)#uC:AXé礋AxSQ$_BLYB/,sAf"P(ȝףW'QKG3I{+O'Q-WW2[5䈤 ݯ |>`j 4Y<JJJ yߴkjJw7\_]ܒwKϢYhwz:j.;r^ xiY|lj{a~lIHX]i4ͭМ_Wjh hh+9i!.Da>ȋOR'hdVN-a3k?4[3j5eF"7j4*1v]o_;Bh)Z]=z¥BKHoR$ZDpmf~'/upUsbb(/L,C \€x$~)cbbb:;͜o/S.yO^r6:kӌ2㲨}Կ5>+\7\'&F/˃i, V ٮ=Ĉ|(NU}Hzۂ(Nc/IFϦm4pBG [JBAg;sMj}js5Wo]%nW1(z!l n{2cv+tJxlAg^=wvt/}c6IK'&"kX@;8r.}$} yb)1 [hL*ve V hQ[%1:ժ3s?iJ49L6bBD +endstream +endobj +1053 0 obj +<> +stream +xk``n|Qo_]Û/GL +2 W] s +endstream +endobj +1055 0 obj +<> +stream +xڽZ XW"Ui13i*UTq@طa"lnj*v,j֭jv=;Y i]O`s;0++ٿtS=<=7fN + +>{ǎm 0" VlɾlkCm,oX E=klge`wp$1#Ǥ3ȚK^lh?v؊!  +|D?Ko?>v|HFPԀe5ZiٗVv%F)h @/UJZ! +M IШ}|o+oVMNR-Њ-Ȋ*h^~UݤN_v"nH:1RW`-$}^QPԕw4\^Z#jO˺RZ.\.Si%=pHYG +%SهEMM:iH*h@tmDkwuv8 +G1(v^$'I9{@M_'[>JOWnڼ%<|B)(\vls=;瑰Ŗ':eYQth6) +W@j<24o+Ztf'钵@}mME4#Õ!">v:Wx-ڵ04G1G Æ7+[TUOWAቑF5 xbj/Sq" Zp A?8 +'>3Go[o ?f]M!2YHXKd{WSk@W=I4<R'[5ѝ{fyGQqn^UlNNȈ&UU>}b@J˻jΔ T4& f؆C>|ΤrI4r-E<0U=ơ~85-.6.-)|*ojӧ";HG/wyC_:hLIp6IteՇ_aNdinIfCʦv5tcA{A{c k,& {'aV].tvYA"LWL9izaE>PBc jN#rv +kCph4v{$O|BB@ P-~o/sCws!D/=f6r/l\JsNp3;704yu'7}ĕI!+ rOxu! ֿ{giyS\n. f{|p}w2km 0_0C(hKB'OВZCgvBS:CdIat ^ja1'SV&ӶLWp YA)pk@ÆZ87[R[L',~sLa@. +Czia?il#O7.ӝ.jϼs k:.yK^{$(,/- R_ݽu` +|@B1ZNWN]i,u K7Uӻ{@P܂8>H +w>r>} +>>3% l=/sH6(GS8 +緛}Bp49OV>yg@̒LQ.~S8 !he/19ʻ;jCw ܐUgүvPI>6Ԏf^v>hlTP8ԨR:W/+./j@v*'NQEw??9==%Y[^m,.Q*k4&{#FH-FSmɑ*jZM-N9%'hйnTHQssQ2WP RiHS]RSBV>]Q|p(q6iBkϘqĻlrJ@CYA{"@:6ю4ẺcEFHwP_e4]CqkPC@{cJ zn^ L6Cρ<<%4r`'+h_wfp|<4f3tp vMa-mb6Zox/t_)wPZ7㜏EHXF<9 sǎ46ui"4:2Pmb}ddBb-@CnKo/X_|Sx) s3"ÄC[cѭFGpX}t `sJQ4#x +t~'R~h{Gt3ycN/\-s<-OSNϞ} nT%..?:9ɁtWy[W-q$5%ٸ1:!':;RWs4/ ,%0A<֗J].%|pBx8^pG.yxkxҿب|cCq|S ק>|eHck8S-ZEM/H,<w‰PTeTeK׹ ǣk +K)r%|Eƍ]K?)qi5>/|#MF4UF0(S-sh|w/`[Z^78%w}9R44>yW{)$aơTv ~=>{{c\t.3&;z}MPJS٬i(,u] ~>$2(,@:A8RsG j#t̎!SGd]^yX<-=kwl}.JmImRk;~ewpFMvRDmJc4%\AȪźK):ܺst _ ձ5[Ne~f*nά%{|- >ӗIؽEr)_ &w+,s +A`bQcUuit쾠#t]Dz +IM+*%9kw bi9*dгի8Hų/RSG}3]lZDɤ ,rAɩqtVI! Հ].w _RW0Q%" pU̪\SvTy@W1u]/\-AnZ)Bscض;ID鷒{}?Y2DiJJpMNhü^&N+4 xy}8ڄBSMDtuvT|(./+0Por5맰נ $`f]ڗ}ݷƬJ*3#3#ASRYxLmv 5\{eF)e5BYZ`B>v%܁$DR38n?+=+=]]\Y_RU^^=¡~x)Y"l1TU04x +T̪l1c?PI Ne,nu5 :*JUҧ(H9f;FRĂysL#w(O[u]퍷a4!LWfn}=% W0-n[*iNihRpjQ1ίSą=ٙ"evFR0/sg+B~Aq~D+BC[hwcc-ڝoC'x&h9@jsCK!ħ 9(YEIW^Q@8~@+wmµk6lPZOIJ:1k L\0ļFdG< 6O @wߏ8O?GI[ ޟ IpмUQ;;lg4}pK8_dvD %+D絼Vfɦ4.Mt;5]OB1)GSgoo2=m+orq8vXZ uR + +f~GAhcl%;[df kf ;Zp(@O t_NA|oj {T1lf-񽩝LlF" +LvóbsMP?a& #jGAEUYJ.QZIEoUчf#:sO0DZ2qяƦ?|Ң'ӝ3?ج9d8}heA4D evGof_8B: #!<7OZq(FT:ґ3@*۾КX_T.$ +8E@S%|7sF'ͥߞni +|)/(vE17@n6"'df +%\N1f9pͣ;ZC BI4.XGBp黫W/MF$R4)ǩ_SxJ԰dyFC0@Du0+OrI5%%B# sOpnAH7YM' ?%Cߕ('zO =,.UkҢqwCo -`P'+$\nLOBžlF"I1 2d 뢁 *sq0[j3Όh+ϭ+j2 > +stream +xk``1_3_u0)  " +c +endstream +endobj +1059 0 obj +<> +stream +xZ xSe>i8`B sêࠣ"e+ڽKB&ݳIҬݛ6mJ[Q(kʦ(8lxz8{E88wO'9'6 xr+Vd̞3}iVLZJ\(v<$X +ciK">02~쿇p _uǣ'1gx x2locaOM†`Ri֘U T]eoTO:<ڥatt(s*7ɷHV# G6jj&%CK=z:gpХٜ~)IrVNq£)MlƏ䤔HH sYq:ӣ^_rJp {t!7no#+='}9ZX!n?!?0 J7W{Mx/ǣzo#IGsOœ:M9T=|?Y_M<.h!1j7 s>Eq +2̌,2v*YrnPyٙ^B>v nظ| +-j%\Z&L= js.RvUz֬&OI`p,8FpKo$NJ;=]Vmuv8IU'nX2`29h+ +hԲ𳩛.T+0d:[7NOj#Mxy9kE8_'>; +K8zg)X@ma*l#篽#0&GCfz}&r:rk=z[h9;']v{(.=Mtn_FÓKZ·Gš*i8]S*ohi@6ei슼-2>x|[XkIL5j_E9X=.THlJ8Tx@ ,vNNq'6J&zApYM/A>=^N!CyhW;4eơ,PAzJA7ZKi83v'rNc6P95\(z2}M.hW2=ga,gQ^v\hU724r2#crSI.jz +qsb&T c+RR1v|;Xh^f' +L3 G `'6J TZoR koVӊ +QyC!y hTF`2x/Ô V@ T;z?Kշ9ݝt`?\ Ď9zhr 1B"Hd\W*'NA<x<{6S,{qࠩt!epk@>ħ Xp] IJڤƃy,2+u*9_\e.c]b1טE +:[.ƪ+rzϮ vbrcS+ +}VXeRGE(ےH*&'Q]ߞu8GWJ7BG*h\u/)S:)SU|U&)A2SkSɦRZC + U$ rCpέ8O޻_e$ޗ4 YZ&I +pEi/2nnW5\Y>S?oQnV,D>u;M&<=:)^yT0=t-#JYri^jBg]奚r|&zTG ^A{s>fIMv,*퀝x^Q=hJJL$)qgǹFA.3ɬc,ILS)bg:L*D۸Ȍȥl;,T|S0`sʝ\XZ-5e}>oS?O O`0XV 76t9UPpk+m۫툹F y%>V-tkA8Tځv5N +xSbB%1\TZ%C~l$N,T ii2L# + /{#n?r쵤RQ\W_Vu> ᮽgqbwC:(F5;??Cւ]6~K5٠HM锵nQ$l3&C*zp/(4ȩh:FY\iwNTvMGe1eZ2R4R[_D*Ze4Q N owtΣD8\^&-dRhUmTsJJ 6{mœ]d³X\j`lwR +H衶äץ41t^#- dr>iS5?y :% r/$loo[K]505X$dpZ,US3vqp3MxN:5A4t\).>Ā0(PZ=2oa=2A td:tKQުt !2MjК|k,Z.Y{K)4 dF[^kMf&FX9ߛd)G1,}&@~ 8tFh%\6B{xb,!KťN&,ҭmm(KF d@Ňѕ˺m-icZv2kjI,Z Ma:[^}C6r= ©*pxa^S\~ |9<^UF%B,*m~ + )2gh9AtBZ( 斱 xHNm] @WŞqlW;)|nG%a*#6 f=l%Me-!K.Yl~̂Yo"L-hjQ&i2vyF^l?N߶6JXgI#X\%8lTٷlhfYy6TaBM6ګ]?@qS4jf0l.f +M8ꬃt>u%b[- ·0?\BM:.Ñu\M(aY$7Fp6 - +>ܽ*wnv>kIظ\jS"2C4V@*kboihje X]\AK{pb `E45>}˓+Di008Uu;6nܖ \#G+ݫc%+H[1sy ;@}rwoQ}.s&-A0`p(S/8'%O*jF,=%29ä3?2Xly?$yC~`ؠ4ژ/NMM}4(,#.QE1k LD9a.:b[5)Z)>hEczn5$xV:Viq4jYC1:f#';7&Rgջ%''T#g4%dq#( 9ҁ> ?01z6WPxk[5έ0 K+y ʄ@Bp_0gܲKj*Jk D)QX%-ɪҿ+?;*~1gk^G1N܅t_i2qh eÔ><' Gaq86|p1>8)bؓ=D}Td0뫬j=ױ K+ZRQнhB숒:jQ,N' E TF==y'|6$t"*nϮlCio45ǒ%'{O.-r&Ps1^Saʑ1wd]+).wvٜ(#V:{U=Fɩos4P0:T0>,Zb6C7 d~@fz:[DX;0:)8xmO +|[ɠ +&˜q氣'䥹9Ҝ,EJ'&{s%܈Mδ~;G9rqߐ$&&]/%Y60W[UԚV-bR*N;]݄B2h(?Kƚ^L=w'vofpQ< mY Qrh5׽DC ΰ%t^1`KM&C2PNZTYwMat8@]iZ">8<@݇Le'bháPX~>G񩢂Dj,u&2hnp^ϡ,JFsR\ni/__uN298P9S?^?Bh.;2MGTDm:8ކP`<7,kc:q6b %&rjM@V1]N|wZ8fi?gnLN7_4B*򟸧(E>pswG; ? +Z5A>+M2qo,ՃC|&(P@~>۩`B}/}gATo7Mo%c۬KWYvl?a~yb[ |tuoJBҦk׮Nڛvӽ{"~~S&姰a,w?-}X2l ~s1u7̴Tâa#@#T#Oń0R0-lST +endstream +endobj +1061 0 obj +<> +stream +xk``0O6~řW- P&X"p0 K:0204L P +endstream +endobj +1063 0 obj +<> +stream +xzyXW~!T*R*SF%nq-*h@r}eFE7LTLȪIhĜj/|qfy~n=y;dÆ rպ@iy +-I/"'A(I^4a!'|j,~{z_/tr^FQL/ʎH j$zbG+w{/WxEFzL8q0߽"\=&N<>u^{}]+&:8\u{Wk-a{Â#CNpݰ75:8ߕ|yx{{+\#a]n\uIpPJ=Aޮǻ{{wBp^w'=gS{㗬Ya ^xBDLOp;7 |Ÿ^@F FFS/Qc+8j<5r&Qdj +5FJMfP3Ykj.5Z@-QK2j9zZIVSoPkuzjDmP[.ʓvS{(MP(_ʏ@* +BP*"(*Nr'!#?k9Pqvv۫^f_! ZG_M1s|Gg볪OeNœKwYpNt_o P xe aPA.ϒ\1 _r\΋{ =/%,6 +gDwkU?qlݒ dfiSHfIj~]$ ]i"NDPnLFs3jjtYSe0f'/ K؍6j.d + gxq 8A;K2%3Rnҍ>کPyf~w;l}_ )A kHmy{ +d(`vRtkhѤٶsX`z='"T”% +E5EF烾jq܈ +¨LI5(ȩ$[[w}`|j38P1W}\c,oWj:4(X'V2OH(ж W ]JYƧ-5Ef|*tzip9>.n/~>TјbI1w +wČ/Zo{sԎdbR\*Ǔ7 ldPѱv(g۟ jĭa??g_&;xfc8[D-ٮ- Aˋӥ$<>p/; 34׈ }j)_r*DP2(?.YNN6̥/}hr<o;`9`Ig阪Idw.޷$/GmJ-'F8G%*9‹r5ۏFú:QB#Un\W~4&/#pddI#o ilkp\m~;f +'TDT+rI^}UFƥ&X.U۰>a#Jxd=Ya*բ^"iUbWx Xfzˮ݌\}Ag`nlVNn'Twv=M`]&L=WΝ%5L8#aI]rO׆r2Y| + =D:YT+H)N kuX,ב%Ghy3Ietސ\ʗrKQXWo"4^GeGr^w-2+Nn?" ̧H}Z40FR1/ 7H /`n:b9 U7=6C=,ʹyp]]=x" 53TitE"QYl<]a f̃y[]ƅE54U +=w4A;B C&!/XbkT+&aj*]iخBQ!uܻE߶1tRԼ%ʼn4%3rSۇo~Eq%G.'Y.: +}7^0j&q@m'Q]e.7jj{Y*xd61Znz?h' j^ I )r3 \o2c#'d‘!b +x-ЀV~ +>;"~pQn$C!x~!9Ƃ)}SUq Ș +`@gep=Fl $CYKDPj2YT0%Zqj(O4-2禂CBЛd_Oaji>\pDG¸(@QDS'f9>Oj(*(("n3nO2yVe(B%+8SBP%H/t+PsI߹ѕ GkEJ@mDX.6pbGe;Om؉2YR/xe #;P0?qVpQ6y.^w[/TI v3Z%Vž68bVh+XPU{T@&Q<^0Ԡr1K纳/GɯGZ(B2c>D+qoNްc{#~⧆ΘD +}ipCͣ8Z-G<˱;2ޫyOo=oۻFPmX, (SvnU9W[(5cbf~ LvޢIo̚*PeI +>;v̍Ʋvx!bd+=^[lÝx+H{@~4&`b9NcxHxuVAס]{"a v +£=@ hp#,˕oGx,!{Uh>|xOؼ-lM0w]dldP!A5 +^_> +Lm d&x*dgosH}Vb J]iT_pX?P+e1F$y&&I } S+6R$4< w!{dd ܥ{.S#&Qו d'czLҸtcrA$'nM&Ϫ>Y l Z>yqb21-U"߶T1?ȑbyxDnc4vMͩ%bs6T{I뺵U MMff:;7#3}]̒o^{ 6D̓0峼s$H/=zOWgCx?')oOAzUVaq30u֐p3E5.2\r.Di~Ǜ6?g*$e`? +ONn2x..ɬg2dOfa'!x{Su~qA2% S{#H2X B1qDNخS.vϓnnZ2Nͷ:Gxd'oϠUU&dgp#ӭqb?\-Cz lklɸ3׏8['v|I] 5F9`$# u-{F~dIK޵lٻ,@=-oW4ÙN $'躺:k "}pl";`cʼnba˩,}NR +_oЧ(\ PRuu x˓6Wj> +" +r,Hl-YpT<:A"^O褒\CFN`4V*Wz?]B w<&.WwNˏF,ZdsWPǧCe z}SS,MעxAky<)pα'zx<rNs+{}-jYʧח iϓPc̷.?.o~j_xu4YinNh&ouA?L J䶉Z}{+8_;\oTیjG^LȌyrFiiq\hY0Q#0jY/ &Kh}}qyv<<<翸~0ʿZW=NiTU*ut=쏩t". (//p'S"8gRϙuGfI`9#GZY;dXIˋͅ +ϺV6"1j +zi>)wg-y Z2v>U0/+bY&X|O naF,D Px:atcG\!Gmg?_]Fǿnt81'L̗{P5v½=6lL+k:Y!{:§@jC+/ Im2%⹸|T*\}u~(k!nYv挒:p^cz"<{3}l/5ҀiIi3kd0uu:8S8"O1哦r,-*K8u_Ͻ6sћ .bU*.ʈx2[d_0)@5`SI{qfX H:\X}h0UOl3ben6nYɘmYĕSELZ'J~Chq?!H-]vt&`ș;vi||yF}9)4M#qd0rum@9`9s%?%Tu _S%Btn;N T(\eJȳz>cZUx0TњLMv6WLRٜߢ<<7 s(LCȿШO"w H y; +)N/>o޳`霔l1/d ҨU޽|Jvrp?I |yF~A&)cRlΦ33 _G=!\MI_ 5+-(j7ʐHMTɪاSv🝹4QOw/6ɳ"R5*Rpi,b d5)BTT2҂*E@;eo66["b +}ՌF㰧I4fB CѬ͊L)=Pa9[aE`d5a|J!ֹ̚jb)t39w"^cEj.,4<*.p};bvK6\:$&2IQ:rLف`!+ODBwoYkhtvc-⡟ IIHErAzAf-(&K/ݥpt'Ob-"\`!•-Oq)  UtqOWЍ3M;Gέ7̱QQ=YywwOS+I(S&$C^:DJhe>E"^ՊݵCsq|LBL\Ѵ*x$%q]Ɣ +x].%SDW2MTHpspkД¢D KFhd#/!1yB1E0O+7@FHQT럿yDUJ !8/R&q95kF![oȹb8g + +endstream +endobj +1065 0 obj +<> +stream +xk``(_; D^ + +endstream +endobj +1067 0 obj +<> +stream +xڵZ XڞAETXљյZ↻a@XIN/ rkWmբngOZ{ O sx5lXu麉kn r6uFOT{2v(; , X1n[mчCH0 xIw+0oe`h x=`nV[!Y% Nw:%!p?HSgL2;:W{D݃īkBbOB_@oqxd8*B!  + ! s?%8*K.;o,^)^) 'O#$odd)S"|B}xsDL )b&/sZyK>XHwHKu!AEaCHl6M&a1l +6fcs<=}l![9bK2l9[`kuzlۄmƜ-6s1 `ޘ/cXbX$bR,a붲i5*JR}֘fp^&wTuVZ $`Z\6JzwGm;Va{kO f?~%'hC A~sԓ~$K 6% Ƥ׈ =8R L1< wn1($)8<>AIyuV B\!0 ZuZtwOuFNmt m@+BQBh oXL_W6Kt&|!\.O?I]x;hi[.۵2|OuMiyu~Zn5Ӹ郞:zk:oS|Xd/|+I= z&=3*.~ɠ%~.;<n fvm\:hC'!WeW.Fޝr 52 +Qާ#١B"w_V4 UMa6Tۢ[玢.evz~cOy=n޹6&0Pp.i ?( 4'uoHYԾ3 +1s"oS -wo&hKI聗>r::&b==H;hDZyw+ u‹I[Ѱ߸ڇ:b/&xv&(iwZ7M< $F"mp5)g5@QHm-KO)ł&m&R D34~hl4xoí Gtv^Mm! gj?{Ix(A dXiLMuyI' [G G6y4,xC<ͬ6*88""8*F79Ds\CWrD44,$0+OGk懬se#Tdjfzf͛0M<#w> OK7" +NC ^xVB8p\όN>;ИPcz=[J+QK3ϝTxOsf lWIHتAF #NQf(o +vvPAC JXERA.QnO&Mql\=D+4= z^m2)de87uEVp ZAahebC67G":1]NF-*-QV&ކ< +kc=Yg[}nq>4܊6z +~A"3!za@tr̎ayήŤh @JRRfeźS_R' 9Lk; "iݔƓ0ĢE*VJ UU{ 񾩻b+d04Q1u}!.s*kZ`l$n?fj;dzXGFס]~A}s*INW +@BI/X[z%0Oo8sshd^- T[8$sKVW +q`xk8S1p~x lW'8F +o+Bk37[!˗ti=;x:`)B'9Tx9vA0|et^-W7/WafnrܴƍP3CsI <[°|8f>ΕsF<+Q7OE"8ZV.J3ҳF6hZ?Clg%&D + 0M#t§lߴ&Fȗs> 1D~]uSHyC,weS>\Gsf?ɮ +%nGo'zo2M2p=ל1A74;r4<epg@zTaLD71ܾ G.E.3S-Q_4`q*q">}q99"JDo\+:BbNU;h~VT Bfe%~gg2f=WM$z @A ityDT]ˈ0-@5do|hMψM֬\h7h^}&8ؗOQvNq)G4Q]B8 ahNҳCW`mK=1^Cw&l+PKsv翽߃Pf/ҜV0'=Z{vqp6 A{cxW(U=%48#@%ӵiކ6@FpgU~0{r;Ԋn`PI'Qt(ˤ̣qg9U-!BodGtB"P*HyFzV޽O q>!+Ң{+a;S$7#x6Ў(3~#HNUKpjGo㙄/w4l.HKk"uEvv+UMB}N%j-ш _5yh.\C_w1Dn>+ihem{w-[TZI #C*K fFx\e2MDOVޚ]NF"SOO]ӣ9.Y\ :d1pTFAmGttҏ'~g_j]jMEX?t 3n7R\V5RJRT]Z˦6$gE^_+5 t!S3B!0Ź +mo +z +95]0 QM&p(>֞9EgT9\V}<8{!nnnq1{_mg ]sٿxUOO.U{u-\AD( C2ip03M- 񡝂vERk.aE)yɽHzm;vl3;|,%ӓ4?i d]aF^(2Y͕hk2.c8Դ&5A@a,bg5Ti5P1@IrmGОf:Y'>7SrPXAkt@'fL{10x%I~ ΆoIW%44‘F4< ǧDkT+DMlZsr^UhGUO?2\.n1ܧ7[3Li>X= 쥏; Q\~p*%BJRUI,GC-*94Ȧxש߮u?N JuMkDQh3 + P8 dLt hK۪վ)JRWj>Gp\7f/ɀ2dq!r~|\eaR]<qC4Zs'h~m=WotMpҙ5pbUѦYF^i'l!@OUfxBUI(J9VwGMF /= 4N|qz?.B~!TP%LF_6D=Ayn=6fE"whV"cdezr5 ̫URn5SB=՚ N ]ʐ0p,MZUwʒ;LjZ,,=f,hp" ^Y5` 띥Hpq݁Gڊe2,KS:3W(sȸ49v<"r4Q)ѻԚPO*c$6ٰs2#sj~EQԂ"R_p +rdqr29yo&=q_JYϥ_=j/8U{$2-T du3(Mj_&t 6G,[M9]3rdulqdLTBKϱKmgVp)Ppc;#l/>;:qMz'G" +B#k+ՙSW4&"U ((dl:x[h$irp ^}gSNaL2-}x-(uodd޸I-eI{7P^ KsE`9#ls.#'V;EؤT +2-C{leP_s?"E03+:)-!3zӘuЦl7rck&gK^ZUrǃnP:<ڜ7xn;(9~(q&n&f{&/d{E\Onbji[j[Yv0 f}]RuYz!zsm/`JZhMjY}|7 +endstream +endobj +1069 0 obj +<> +stream +xk``0oᆴ:,`R#CG +endstream +endobj +1071 0 obj +<> +stream +xuWyXMmeޙ.Ps u颵I $1 $aQ*" /"UjZǶXh.}yǻ|2sg=932*(dc.zeWZd4͌ _d2$HbqxY\8:W\e`25|Sl(4B9\)/*'I7OP@&{D5~=_F&44F9yiku6nVd0?[P'd=6&p+"sSLF.NS9S"^ +jXbJ5[Fpuz+g7Y9rh U4Φp6[-5m*}hpgh8f~z [6dH$2~! i_֬_%k-9l\%hlj1/EGM&RӨT5zK-QKj%ZMHb8JOPfBRL +]AMҀ{1ǂ]`ULT)N v: v Z8-\ıv׮*۹?k,u y;of蘤tMȳ\vΜJxTm-Ng+dP%׹yIzWy^Th +\aN!fCfƬԊ/7\ÓL=__C²',k !^Gl [G{CzX~;RSFQ9܎LHef}bck׷MhLKbEj-B~{D:vI-=n|aHh@}]ǒM!^:A܆*4*7.6>˚Ep1#lVzҟ7UZɳ9 +743{ uř'>pz3pd Yt@ito6u܅gwcgBg+sap5j;ȅ9j(1XC +3p?BHM%ߣzTuN|}]y.拫Q,=<ʬgj*ZX 7kY& ID ևz tFf1_3li:kp^hψCQD5pe~W/! NK_cabb޽daP[BX:? w܉_(4Yse9~&uNW7 +5F/f٪t)=S[; 7m&Ƣ (y2;uUUˌ8ujhz/GWF!T"Ń8`D 3"=F!K~ H-B>}g8XѮjqi!r(&;oMaR.:ZǮ$m3Q=(ZsFE(WwuTXIrJ%hxWbbWZ+)T& nK%v; 8L$"te}Gm=)A4}fE'.V*_|}ZO>S,XVHԺH:RM2؆;u׻ @{% +e/?Qb>EO +Jɕ5vAyLѷ@xἽ,[R}O_<Y/>d#Ś&>u  q`ӆ~`ydᗮ$-ճa?YɏMAS|hob~|3_~*hOB |K7JܹxZ|ReQ^lvU7C =I(<^+ơ1xluR\.ߺ\RJs5ߓUVB{4U ē]jΎ,RW)ݚ˗{݀(/6HEfU%πZyAfSi'^m\jhQmxҳr{ǾÐl[`z@EΎXrR)a5 <Ps5+ŕjw5soϢtE^3\i]|!U4@XsU@]A~[lOsoj* ^ ͔W5_=c̻Eo/ckot'JW)󎧼~.ɛ+=ّr~9B;t2 +NA;Z8|?/;mIvc`xOqۡ1H3ni=u$zTqGDF9|tPOK ?dJмO Ã֛naoĉj/E=Jew%}>Cb  +endstream +endobj +1073 0 obj +<> +stream +xk``00RfHe +endstream +endobj +1075 0 obj +<> +stream +xڵZy\S׶>r*u+j+NuhNVY20( 1p$ӈ b&1C%>$>"‰XJ8.2•XN VXG'6Mfb Nl#;O]nbAx^7KDHD!#B0BN( &"H"چ@lgv32h&{6'mmqqS-%??[o=|bݐlv{C2lҰa{xkDpnJLyRG +Ff+(pd"FF}>wGup#R:1Ɣ+#~z&}W@\"~25 e񱑙3R&I”ra(8 +$خ`!3YB.E\im`i=|Wee)ƵFѾӄT&*dA$wM<ӉpqhYxCY]!= +@WELV9FSڥWVYCN+:R;Eu] +*}"U+Zҍ5 f`0$CLJu-z9^BcK؁FŸ9( ㉂EI9q: +a*/&!==6Ld@|nm\B lM>Q҆ W'n%kU° +mQ{J3 ˏ(*hd37VDEytގQ9s. 6L}`JMjAH|hܔWH&G 鬸hy-̽<+rLbW4 ć4nH!XgǙ8rdbk)HfDFG&4m6QǘhPpkybp[kV>kQ(-IJ/ݡ68䎆oܤtnX?HFYa F1raBz ^z{֏S(@9`)m:XLI'#VmQGEE/5sjץ?Wx_;ysgtSR޴ :(e>/I|$6>m5}xȹnBm@D*rT T&=Z?<ׯjQKцt]zP5Uݞw1=FJ C$Bsv =[(knolؙx +і3mп{! ?kXBOHHFGsij30rP>{yq͞}Ȩ>*QDXȇDY}a=6b;g0'$$Ϛ]UP tONvy aaAYL#&Y\g9hjڸkʵ7Νڶ.#˟\?w'OWGrw ,U ~rJBBZ/h}'C@MuuY(];MXۙ\*(FTJrdSd4!4P@ ›7 +q" Xi-&-P㺑L `шY7( ! VK$P>( keI3hI@}d%eÙQTX[j`bSݱr= +[GXfe~J[İ`'&heEON~lҝ,M^`z1;^`E J)l5gmN$0+?>f>rc;XalecL`n[,3k 0rJ6L0 +Xp;Es{4({[y?(0>#^3?\оo,\5e9dUDq6eob,w77!Y]`HMw0sʊo,2r\@.!["r{~޳]f|t}r67h n+˥3 ].cDFN2 +P +"bYT +L oꓕ0Fd!հ] Eb`y4rQ'9^p/uؼAː+r-m*h +3O"ԫ`!ݮQWj3:b L+ħ!a]X kER]ͤW/ҐZ{"?U +}ѷl5ID-1` Yh^7wdtZy\7u:[E2 +]d%{m0n&Ӣ%K*2j[2@37uް-+sքJL:Tux^㎊PClFg>TTq_/sylܛu tnE؟}nB2sa贗&tw3GD"34,t[v]fN_ecDCY2 Tbr޴396>왾kop_e:;Y<+d t)g#J쭃$F1pzXo1QVcEhx^{ +E$ l4l ?[P{Qַ 5 '\n[%ڬ P 3o6+GNg3 @ qFߦ҂ 5lЯf{0Pf$Vyckl?z&MLjr;eKv:3,xS +m6XF9D#LcgeRl&)X]˩//1*D;Kٮޫvj-YEV**cUMe.YN_]?ˑQ]CM6> ',UgHAME3堁G]p5o4%<RMX +8w<>bQME~ƈ>5rk6LZ(> $mYy7v8~ +g`n_qꭥD&'HEhM>9 a7GOD =8ybAYzzH4x1P֔_bh''Eh-% hjD7(H0^PxHx7dW=$,nzAgBʔTP "8#ACNC' ] +͗Z$ţ"rA3\W^Qۇ ʏI}bOq>r,FEU8V1{}i\߰7*=XHӚ%䫣v63#xBB PuPg ÔQhwOE{ѾNRLA]_yN`iy½ Mg\z(D'#%ƃ?^!M 8PuM) tKӢ{7v}th쇗qclʣp6ѽaB1lȨOtG `9yVw5]/ؙD֒n|2ŋ''քeLMTbz U]_:9FP埋XOθ([wkQY af?S1]FNa_|6pKG)dJ~l :<ϸ&Z `OO'։*a[.pZ)V1lZ(m=3 U*r>?V Hb$HdJ +al?$10E惘wXh]7z:܅VQhQ +Fh=-ՕN5֦dZ|C`P,˧O"#37->5s'jP쫉*ϕdUdw5t2V<]\V`3{aFL +e߸U"?KH<D6hZx}+u^Gܒ~2v<gr}d< `8}b +}Xm.0x폘PHa6dR.$Nͪ%mxJ̮Oy&z!b< +Cnnp,Nˬg"1אK԰ * L雚S61=H! +UGTw㞮]/W4-L:/#7T_P=GO!Rȹ:}U# @zĸ󀢈J>3#/s +avw >nP<|h`bзw~d&w0^^w?! +,15&_?qkG<X_7B9 PAֳ۹)1j!Әy4\fg +!Έ&%C;Aj\%-.2H0v-h784N~ vv:CNWeٽ?W0 +endstream +endobj +1077 0 obj +<> +stream +xk``L  +endstream +endobj +1079 0 obj +<> +stream +xڝlϱϥ叧rGfIi@*0i Qh $%Aĉ/vlq88c;~v$I-$%-Ka+* B5!NP;h'6M}';H$'ƽoj+MY +UI[}H@XRI,%d׋$qD(w~Z"p=pd?{$DDH + yhB[LVXY%GիʔFjsV/6jʓ5kTʗQ~UEi5T1WRR)UmLeTRejz5ſt-7 +ZQIS_Hj^U 1TFEhR홙2V_Y1dV$62ez0c܂2Hj6Uٿh +됍H&ى#E +DB?$$L{.D8/.Fe&6隐e`4`Ou3jޫ«@,z:k0ϏC7{8's/q[/^?3??MNNn2EdY(Z~_bޡ)j\P /'> GGAYf|[D[=N7f; ?gvB?g|GMǸAn2adž|b ޹ͻ~KZgU[E"RWa7ꝅqJ[Nã);<`N][꛸D{p- &`!w'`7CVp/[u6`>~794,Ŋ/xdqW/ ٥ٳ~ Ϣv ڻk*{ uւZ~if5` E2%8G;c_s]ehYdUnUAl˒wFF͑ox2ə%m7D6' FL,j%O +fL-LK$#l{l$ +endstream +endobj +1081 0 obj +<> +stream +xk```T`Pha`hpa`& +endstream +endobj +1083 0 obj +<> +stream +xmT[Lge/+^Ƶ 3 EiR[S"DTw]݁]p]`gw."׵#jmI[ F5mRŢmLMLjPSӇ:[}y8ɗs9_0F^pgkKvbVO{#+cml¡PNy)Lid"IZuҤ1f;4g Ohi!J2-U-i0 #e* itT[m6d[61 쬬-k۬kz f;,WQ'\x`!S =,,V[`z.6hz4,]V 8r4 ^oLnaX{fe^8qJ3JXGaZ.Jץ 붺0UaX1Ī0V*F̘kƾ5Qۄ>Ij#AߣC|ol# |3mꭂ EC*I_E@U_L@ک;Sr6rcawï8*e 0Bh zJ$Ԫ`ZN-@~@d{],'*Y I L/UYm +$J^64K(DW;3AeS]Ux<)7%7 YmR5\cB1|G5g|EG%J6qjwSٷy5(D.S(1]Sg|Ǚqjע[> +stream +xk```b, F +endstream +endobj +1087 0 obj +<> +stream +xڥX{XgHAQ6cgF@Y U][A0j^ +rKK( ( պ+mjZؾg9yγyd}wfDXLD"ź%׾R2Wm?`h{8Gxal.Y2nx.>^>Q+yD cIFyM"aREњ蘔m3}|fiR%g3}|fM BpDMvzb-{ 2M69 A"DG& +X!,f.ĥi2Sӧz a B&-Q ۴h!3%:&MȈWÄMJ9&%=F!>##3225iq3bILA3yy-^^응!j҄蘌Ȅt"?HM(w5ʛAͤRoQP(_ʟ +PKPjFKERQTLRiT@#?쉩4Hѝ+FX<:|/N-MiOs<pJN'dk&EVpVd׻Z=iauGd9ېf[ٺW٨VI X,Xb5˫.8 ܓ^nY*iY-bT)!)Lb Yςb.fpexUG[M{wp~ =3}j8]qWHN}A]ȴ-y9xӋ'N4sOvaK<DfqYף"v麣>T7V|\(Yln;N-B`b1s)<*'z1ؑŧ`>p0dUW+^+|Pg5Yt"D.>2ŋ}ܱb봖%cal;@0aoB<$x-|A7W*WG:fYA4; l[HA-:Rn%Lox f`b?t519↶~2Ie2x>SDĽsx%ha ғV|G%kۡRfij̤6  c*x8 ltHgr\Z)풨{P4?wokvR5~~xaPߘ1-t?}TVr¢^+<` e{B;JXԍM_{h?*=(ݾ]=|?X=H:vbzZ-J d] `x<\ v)1(ag3^;8v¤ЉpĬlUu<` 4JNfN@SV5/`jI'XGB/fxWŞF" o||.#0_]`oS䄫eY0&cgLޚ2QhG1S&K}ݡsVS8jaţ S.|B8>/i<I4Z! `L1 lu~EwyLafzhO,L!&3«Vu#\SɊ& +B:])ψ ʈΌc'uq`X?p@^?WrkmǷvm(I\ǵT8p+;mveZed,A}K! S9Z#+Y4r'ڗ0)k&S9Ǹ-O﹨?B^SeHҐv`1f)X}ȤIO:9Õ_~1.eV$S{ؙvsY}Y$iuvqvUS~?j "&x7²塚L__̈́nPI,$uIf/rY^PW+tiHͪ0^+Xz>'.*!rgux&OZCl,\+. KÞֵLLD۱a}\]g9(-kxpJC)lia Y!9)|Wф|oEMtH) +oAvFsX +7a1\tXY5,c(JAsv3ˌPhfJI-q(Yh8pte +h,/{%dλa SXZCp\MS7C_iaI}Ȧdfn[ yDqX"]N3n?~ +N[Zd|7tu4 לoY{D}6aؠ';9&YRq^y7⑍\zb{y}EŨK"v %rs^51w&6~/@?r+^NQjװ;^g \M":59\itk,D_!b.}-}]রn>pr7j*WQ#ʸF3jz0œ]yܾ5(MC5|hB:WIu -;kܥ7j#XeD \i2|;!J0\o-F8￁^qW2t:nZǵ4s\'x~s?|Rϫ fڞ[sгMGrfZ_> +stream +xk``(V̚eb +endstream +endobj +958 0 obj +<> +stream +xڽ\[sI~_ u0WcЃQ<3?_feR/Uu{Vwuv9A=4nE3p6RN7e;*yTB0Zq@[)47>jEE> L,|Bi40` +m 5G?,Ș, )rz0jqaq b@ZQq 6@AH..(0 Gl +(=)Bkr4p!a(คa9OT%p) aG&" +LS QX@\+Lt9K(_a%?Zi+L U +sl0 QeAU ,B Ua4$EC U3z E +¥kqS@sh `#'LƜTPd@W$i +Jj!׉zn"UMP=Ѣ!Q4B&t/BV4$+2p)L#c HO9+tq.6H@sDjE<Н/"\hd9P]b'(G6`rB&R2ρ+GW0:0pD]izN +S"Yi*%Ur-`;nB`V +(+(4KA! ?IK5J(EA!!0#Zh7hVTv 6ƒ +B&@̀@ b#uٌ!f!_D5T@;.!l5`Sz5>,rpw5Y958MC 6&$֯ѿf铣H%I`)FJ+KR&)xZixZixZgxFgxFgxVYgexb~}u:Y0 l-q:xl\=YA +*NPqTdiNdiNx^yx^y' / /<K2\F^xQE^xQE^x". $K/ $K/.g-^c^^Љ:B'ZE h-^ЋzB/Z.n/@Ԩ{Q`/ +E(^؋{Q`_xŢ۠Xw0Y$lפWӋ!bH/ċ!bH/ċ!Vdx2kx^+ +x^/V`tг(kz4oͶk\7 +/.ċb/}l1 tu@[C=R7h7U')鰂VL%bj׸v,Wzd8 n-m!nkv;.z^O=R[f::%!v[g9l Q%\,z{,)rQ&:݊BP끐6 EAuY}WLYz !qk=0jkyw؂xAӷXh Ej׸A NY(%5ƣhr6Xh±^d_||2y7k4ٮ&^]ϮO'W?P2h:=/'???R@5R-UJdJN#^lRYL^^//3,3ؗJPը($?^/%K{ԯ9^k%{ӞsO1=B.oG0g>QBbr{z]ڳk3ƹ9so+~y׷FEy"QfHޭ0D.F? #ZhC~&6}?~܅h!B`}G)I%UY;(6B^ʯ$ mãYb18Z~$)ulrx& *sCPL"H,xiAԛsCbP|cRA;vwEW(11IaY5DM ZV~Uy|gaX~-SlNi%!c%elް?T؅y2Ԃ̵VJL*%tU:,6lR|Uf X&N=[)Md&xM,xagޢP_YQ_zEޞ"TiX,9i!_x`@"CC\:E[2+$6̐Th3ۻL7E:1{:Ae7;ސbpYFÒnFW'7)^%|;=[~Zs_-?a|\_PxG?:z O`8^"/ۻ/O矐B$[/N)# Uԇi__,_l1_]"t6]~&_&..ƋOlj1 ʺF6=_ggՇ)~\øyoguiuNTgtv^S3=xG6'jj]B8,!Ml36rrP#J7H۷\_Tv 3p8u1c jV󊈗cWИN|6ͫ姫 yeZL*FMёUAQP5^woNAbASSr;4:}Cv 'kKD[ +_5Vu7>||_^uz=׼ZwMI~p^1 +M6km V V%- +qpW$wfVsYU=PyS m4lsK5PhRtѨh.mRaHYˆ嚢\vt+PNoov>$vMߙ'<kϾA.&mAܺ =x3fK6HKCGI5R$mڠUsA[{9sݥSSa2JƘ۔&E"QS#Mq9/ s&=ԍ6mcϞxsXnG\Z;dCFbߧu)6 :>!`hQy{y|~}ۗgߖEm G׆ q/tŞ,ٟ3c#6JCkW7}oHh{gw8:*d]3," b5p5,Fu`:"uG6l]bOaz0;j:h54omX{FфMTvx&7oڵN܀5Φˋ񗆔N~욺t*ݕA5D#$5]f{U7V%N)×d+4wvrxoC/iSK4u8nG @{>fG. S0%MPy0Bes+F> +tTsCx[C =!B8ȖNo009_ægC 1!~lC497%uolHL+()x. ðiȈ!!oggH0sim<* [5$0y|H#V3yrs#W_BO-]֫q*9$"۠@ȫǭwb*m17ܯ(e6mVHrq2\"r'Eyx|4֓y-E [)JFQ1]ι(?YMCn=IՓ>įIl9980ы2*qT,x/QȧaPP@DGE($7 <ᆨ=)C+q<UC$Yt3)GE^"T ђWMEqIv8!ŇPY0qН+jm }nE@h Wl $/k5ڿ1MFL?4IR_ >,9gS$*)w\z0~'eɛ^Sme{tvo|=m7*XϏ{)R>4{r%eoSi/cin@ +E.rPpm$E0W=x/a%HrW۾q#ۥ&ױ>SR(Sje-MPMkqleIJbyeDYlجZzն# S +-毁 Y.VBWM߬ R6JQ/_ +ot(ndvQ+ ʯo'+YpZǛ$:4od(2 jUO38IZS ř7 +*.ϋy^<е!+0#fKh'= ;NzKY%TEb5q݉ӏ_=F[mh6}-?m9 p nbi-[Il_.yщ2"X` EMةzmF*iBH܎+Z~VB69"ꎰ'wvK>Kodn+AB#Oyww}x>}W<ꓺRGߝGonD_d.4lZD^i"Քxu>jÜ>#_jgX=߁?abvg}W]/Size +1091/W[1 3 2]/Filter/FlateDecode/Length 2458>> +stream +x5gPyy02LbF #fQsY10`BŜ,V konn_]uwΛ>Ͻԯ~tn%S㕧v 9ѳ)xē eupX$U6Fa3<)miK%mhr 5.ךZJ-(uֻ%Kyzn85zk6[fAEF`#Fa}l 6&Ÿ6oQc%m-xL;b'LΘ]+vMȷV{b/Lb +8 vk3fTCqo^6~Kě<̚4{٫Pgi1`&S0&;ZƳ ,խƉ8 'p:+qLb-Y:HL8uWc 3lsqx3+l-Y!.ʱfaBEX_Kr\ȫ0F1'y 3'u=<]?7f܂W/`Y^Uv+C!kI3q pgo{W)aEr)}G7[z7ɺB|kژˌMWŷK.Yru[X:>>ߥ6C'[_+_eytj|o9_Q|#=CwaJm5aXkb-u#7m~3?'G`#Fa}l 's$7f>&6l[oE6k/ .>`[l%6%wN1 `WݱD|^ed^%y6c>b +8@"do=c*8 0 q4fı8p.4L\\q .eWJ\yZ\qnM`>V܆qbb܅q`)깩~< aom#?A>Cv@*||z~zlMMOP]c# X4@xk4M$dM$MFɚz4$0)֚(XcM} bMX }kMC8[lM#Vx5zh-[ӄ~ߚ4m%9}j'_g[ӌ&^4۝|[dž4sؒXVw"MY86xDӖH>OInx9Li`Wu# 숺}I /%x b;Ԧ uGYژyM4z5n#7 N!_xK^ed3r_/S^K:dwS:[Bߢȇɺp8iiFN|0 w!,tǘSr]8Fi89nx>Ֆ/c6NW'1^j}*qȓq;^kc8p:1F3v.L|qV>/x98&H~sh} +1R8oPJQYB\k0:\T$y.%7R܂X˘F,'7MW*϶p#fp76gP.=(LC=Vq4cQ}w/zfDcl2Nǩ8 ^%\Q߇n.\\Q~,EۺWJ\yZwzB[PNA=G +q'2,ES@bթQz8g-@rS ԧJ;}|zf=g+Xҧ7?H{k`-h_Hk鿗.Z`&hs&o/1=šn9II쎜oMWqfTZ&Β "rqV-g˽tԝm_I.-gMqW)֤sb~\(_K{-`7CpQp}|U_V6mG9|7\ JPhy$aygY^/-/` ˫$8& + ./&'-`4k%x4P`y[b˛%mO|f0+,oqz" +endstream +endobj +startxref +1108095 +%%EOF diff --git a/korektury/testutils.py b/korektury/testutils.py new file mode 100644 index 00000000..5e75173e --- /dev/null +++ b/korektury/testutils.py @@ -0,0 +1,69 @@ +import logging +import os +from shutil import copyfile, rmtree + +from django.db import transaction +from django.conf import settings + +from korektury.models import KorekturovanePDF, generate_filename + +logger = logging.getLogger(__name__) + +@transaction.atomic +def create_test_pdf(rnd, organizatori): + logger.info('Vyrábím testovací pdf ke korekturovani') + try: + testpdfs = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'testpdfs') + + # smaže minulé pdfka a obrázky k nim a vytvoří (znovu) jejich složky + pdf_dir = os.path.join(settings.BASE_DIR, os.path.join('media', settings.KOREKTURY_PDF_DIR)) + img_dir = os.path.join(settings.BASE_DIR, os.path.join('media', settings.KOREKTURY_IMG_DIR)) + rmtree(pdf_dir, ignore_errors=True) + os.makedirs(pdf_dir) + rmtree(img_dir, ignore_errors=True) + os.makedirs(img_dir) + + def gen_filename(filename): + name = generate_filename(None, filename) + print(name) + copyfile(os.path.join(testpdfs, filename), os.path.join(settings.BASE_DIR, os.path.join('media', name))) + return name + + # TODO silent ghostscript (vypisuje odstavec za každou stránku…) + + KorekturovanePDF.objects.create( + nazev='B', komentar='Neuronové sítě', org=rnd.choice(organizatori), pdf=gen_filename(filename='B.pdf') + ) + + KorekturovanePDF.objects.create( + nazev='A', komentar='M&M: Jak řešit?', org=rnd.choice(organizatori), pdf=gen_filename(filename='A.pdf') + ) + + korekturovane_pdf = KorekturovanePDF.objects.create( + nazev='A', komentar='M&M: Jak řešit?', org=rnd.choice(organizatori), pdf=gen_filename(filename='A.pdf'), + status='zanaseni' + ) + + KorekturovanePDF.objects.create( + nazev='A', komentar='M&M: Jak řešit?', org=rnd.choice(organizatori), pdf=gen_filename(filename='A.pdf'), + status='zastarale' + ) + except (FileNotFoundError, Exception) as e: + # TODO najít správné chyby, které vyhazují různé systémy při neexistenci ImageMagick, nebo knihoven + logger.error(str(e)) + logger.error( + 'Chyba vytváření testovacích korektur, pravděpodobně není nainstalován ImageMagick nebo některá z knihoven' + 'pro práci se soubory pdf (ghostscript) nebo png (libpng?).\n' + ''' + Instalaci na linux provedete např. příkazy: + sudo apt-get build-dep imagemagick + git clone https://github.com/ImageMagick/ImageMagick.git + cd ImageMagick/ + ./configure + make + sudo make install + sudo ldconfig /usr/local/lib + cd .. + rm -r ImageMagick/ + ''' + ) diff --git a/korektury/urls.py b/korektury/urls.py index ecad4804..452ab1e3 100644 --- a/korektury/urls.py +++ b/korektury/urls.py @@ -1,13 +1,10 @@ -from django.conf.urls import * # NOQA -from django.conf.urls import url -from django.contrib.auth.decorators import user_passes_test +from django.urls import path +from seminar.utils import org_required from . import views -staff_member_required = user_passes_test(lambda u: u.is_staff) - urlpatterns = [ - url(r'^korektury/$', staff_member_required(views.KorekturyAktualniListView.as_view()), name='korektury-list'), - url(r'^korektury/zastarale/$', staff_member_required(views.KorekturyZastaraleListView.as_view()), name='korektury-list-zastarale'), - url(r'^korektury/(?P\d+)/$', staff_member_required(views.KorekturyView.as_view()), name='korektury'), - url(r'^korektury/help/', staff_member_required(views.KorekturyHelpView.as_view()), name='korektury-help'), + path('korektury/', org_required(views.KorekturyAktualniListView.as_view()), name='korektury_list'), + path('korektury/zastarale/', org_required(views.KorekturyZastaraleListView.as_view()), name='korektury_stare_list'), + path('korektury//', org_required(views.KorekturyView.as_view()), name='korektury'), + path('korektury/help/', org_required(views.KorekturyHelpView.as_view()), name='korektury-help'), ] diff --git a/korektury/views.py b/korektury/views.py index 56f198f2..47f62b6d 100644 --- a/korektury/views.py +++ b/korektury/views.py @@ -5,6 +5,7 @@ from django.utils.translation import ugettext as _ from django.conf import settings from django.http import HttpResponseForbidden from django.core.mail import send_mail +from django.db.models import Count,Q from .models import Oprava,Komentar,KorekturovanePDF, Organizator from .forms import OpravaForm @@ -12,14 +13,21 @@ from .forms import OpravaForm import subprocess import shutil import os -import unicodedata class KorekturyHelpView(generic.TemplateView): - template_name = 'korektury/help.html' + template_name = 'korektury/help.html' + class KorekturyListView(generic.ListView): - model = KorekturovanePDF - template_name = 'korektury/seznam.html' + model = KorekturovanePDF + # Nefunguje, filtry se vubec nepouziji + queryset = KorekturovanePDF.objects.annotate( + k_oprave_cnt=Count('oprava',distinct=True,filter=Q(oprava__status='k_oprave')), + opraveno_cnt=Count('oprava',distinct=True,filter=Q(oprava__status='opraveno')), + neni_chyba_cnt=Count('oprava',distinct=True,filter=Q(oprava__status='neni_chyba')), + k_zaneseni_cnt=Count('oprava',distinct=True,filter=Q(oprava__status='k_zaneseni')), + ) + template_name = 'korektury/seznam.html' class KorekturyAktualniListView(KorekturyListView): def get_queryset(self, *args, **kwargs): @@ -45,178 +53,185 @@ class KorekturyZastaraleListView(KorekturyListView): ### Korektury class KorekturyView(generic.TemplateView): - model = Oprava - template_name = 'korektury/opraf.html' - form_class = OpravaForm - - def post(self, request, *args, **kwargs): - form = self.form_class(request.POST) - q = request.POST - scroll = q.get('scroll') - - # prirazeni autora podle prihlaseni - autor_user = request.user - # pokud existuje ucet (user), ale neni to organizator = 403 - autor = Organizator.objects.filter(user=autor_user).first() - if not autor: - return HttpResponseForbidden() - - if not scroll: - scroll = 0 - - action = q.get('action') - if (action == u''): # Přidej - x = int(q.get('x')) - y = int(q.get('y')) - text = q.get('txt') - strana = int(q.get('img-id')[4:]) - pdf = KorekturovanePDF.objects.get(id=q.get('pdf')) - - op = Oprava(x=x,y=y, autor=autor, text=text, strana=strana,pdf = pdf) - op.save() - self.send_email_notification_komentar(op, autor, text) - elif (action == u'del'): - id = int(q.get('id')) - op = Oprava.objects.get(id=id) - op.delete() - elif (action == u'update'): - id = int(q.get('id')) - op = Oprava.objects.get(id=id) - text = q.get('txt') - op.autor = autor - op.text = text - op.save() - elif (action == u'undone'): - id = int(q.get('id')) - op = Oprava.objects.get(id=id) - op.status = op.STATUS_K_OPRAVE - op.save() - elif (action == u'done'): - id = int(q.get('id')) - op = Oprava.objects.get(id=id) - op.status = op.STATUS_OPRAVENO - op.save() - elif (action == u'ready'): - id = int(q.get('id')) - op = Oprava.objects.get(id=id) - op.status = op.STATUS_K_ZANESENI - op.save() - elif (action == u'wontfix'): - id = int(q.get('id')) - op = Oprava.objects.get(id=id) - op.status = op.STATUS_NENI_CHYBA - op.save() - elif (action == u'comment'): - id = int(q.get('id')) - op = Oprava.objects.get(id=id) - text = q.get('txt') - kom = Komentar(oprava=op,autor=autor,text=text) - kom.save() - self.send_email_notification_komentar(op, autor, text) - elif (action == u'update-comment'): - id = int(q.get('id')) - kom = Komentar.objects.get(id=id) - text = q.get('txt') - kom.text = text - kom.autor = autor - kom.save() - elif (action == u'del-comment'): - id = int(q.get('id')) - kom = Komentar.objects.get(id=id) - kom.delete() - elif (action == u'set-state'): - pdf = KorekturovanePDF.objects.get(id=q.get('pdf')) - if (q.get('state') == u'adding'): - pdf.status = pdf.STATUS_PRIDAVANI - elif (q.get('state') == u'comitting'): - pdf.status = pdf.STATUS_ZANASENI - elif (q.get('state') == u'deprecated'): - pdf.status = pdf.STATUS_ZASTARALE - pdf.save() - context = self.get_context_data() - context['scroll'] = scroll - context['autor'] = autor - return render(request, 'korektury/opraf.html',context) - - def send_email_notification_komentar(self, oprava, autor, text): - ''' Rozesle e-mail pri pridani komentare, - ktery obsahuje text komentare. - ''' - - # parametry e-mailu - odkaz = "https://mam.mff.cuni.cz/korektury/{}/".format(oprava.pdf.pk) - from_email = 'korekturovatko@mam.mff.cuni.cz' - subject = u'Nová korektura od {} v {}'.format(autor, - oprava.pdf.nazev) - text = u"Text komentáře:\n\n{}\n\n=== Konec textu komentáře ===\n\ - \nodkaz do korekturovátka: {}\n\ - \nVaše korekturovátko\n".format(text, odkaz) - - # Prijemci e-mailu - emails = set() - # e-mail autora korektury - email = oprava.autor.user.email - if email: - emails.add(email) - - # nalezeni e-mailu na autory komentaru - for komentar in oprava.komentar_set.all(): - email_komentujiciho = komentar.autor.user.email - if email_komentujiciho: - emails.add(email_komentujiciho) - - # zodpovedny org - if oprava.pdf.org: - email_zobpovedny = oprava.pdf.org.user.email - if email_zobpovedny: - emails.add(email_zobpovedny) - - # odstran e-mail autora opravy - email = autor.user.email - if email: - emails.discard(email) - - if not settings.SEND_EMAIL_NOTIFICATIONS: - print "Poslal bych upozornění na tyto adresy: ", " ".join(emails) - return - - send_mail(subject, text, from_email, list(emails)) - - def get_context_data(self, **kwargs): - context = super(KorekturyView,self).get_context_data(**kwargs) - pdf = get_object_or_404(KorekturovanePDF, id=self.kwargs['pdf']) - context['pdf'] = pdf - context['img_prefix'] = pdf.get_prefix() - context['img_path'] = settings.KOREKTURY_IMG_DIR - context['img_indexes'] = range(pdf.stran) - context['form_oprava'] = OpravaForm() - opravy = Oprava.objects.filter(pdf=self.kwargs['pdf']) - zasluhy = {} - for o in opravy: - if o.autor in zasluhy: - zasluhy[o.autor]+=1 - else: - zasluhy[o.autor]=1 - o.komentare = o.komentar_set.all() - for k in o.komentare: - if k.autor in zasluhy: - zasluhy[k.autor] += 1 - else: - zasluhy[k.autor] = 1 - zasluhy = [ - {'autor': jmeno, 'pocet': pocet} - for (jmeno, pocet) in zasluhy.items() - ] - zasluhy.sort(key=lambda z: z['pocet'], reverse=True) - - strany = set(o.strana for o in opravy) - opravy_na_stranu = [{'strana': s, 'op_id': opravy.filter(strana=s)} for s in strany] - context['opravy_strany'] = opravy_na_stranu - - context['opravy'] = opravy - context['zasluhy'] = zasluhy - return context - - def form_valid(self,form): - return super(KorekturyView,self).form_valid(form) + model = Oprava + template_name = 'korektury/opraf.html' + form_class = OpravaForm + + def post(self, request, *args, **kwargs): + form = self.form_class(request.POST) + q = request.POST + scroll = q.get('scroll') + + # prirazeni autora podle prihlaseni + autor_user = request.user + # pokud existuje ucet (user), ale neni to organizator = 403 + autor = Organizator.objects.filter(osoba__user=autor_user).first() + if not autor: + return HttpResponseForbidden() + + if not scroll: + scroll = 0 + + action = q.get('action') + if (action == ''): # Přidej + x = int(q.get('x')) + y = int(q.get('y')) + text = q.get('txt') + strana = int(q.get('img-id')[4:]) + pdf = KorekturovanePDF.objects.get(id=q.get('pdf')) + + op = Oprava(x=x,y=y, autor=autor, text=text, strana=strana,pdf = pdf) + op.save() + self.send_email_notification_komentar(op, autor, text) + elif (action == 'del'): + id = int(q.get('id')) + op = Oprava.objects.get(id=id) + op.delete() + elif (action == 'update'): + id = int(q.get('id')) + op = Oprava.objects.get(id=id) + text = q.get('txt') + op.autor = autor + op.text = text + op.save() + elif (action == 'undone'): + id = int(q.get('id')) + op = Oprava.objects.get(id=id) + op.status = op.STATUS_K_OPRAVE + op.save() + elif (action == 'done'): + id = int(q.get('id')) + op = Oprava.objects.get(id=id) + op.status = op.STATUS_OPRAVENO + op.save() + elif (action == 'ready'): + id = int(q.get('id')) + op = Oprava.objects.get(id=id) + op.status = op.STATUS_K_ZANESENI + op.save() + elif (action == 'wontfix'): + id = int(q.get('id')) + op = Oprava.objects.get(id=id) + op.status = op.STATUS_NENI_CHYBA + op.save() + elif (action == 'comment'): + id = int(q.get('id')) + op = Oprava.objects.get(id=id) + text = q.get('txt') + kom = Komentar(oprava=op,autor=autor,text=text) + kom.save() + self.send_email_notification_komentar(op, autor, text) + elif (action == 'update-comment'): + id = int(q.get('id')) + kom = Komentar.objects.get(id=id) + text = q.get('txt') + kom.text = text + kom.autor = autor + kom.save() + elif (action == 'del-comment'): + id = int(q.get('id')) + kom = Komentar.objects.get(id=id) + kom.delete() + elif (action == 'set-state'): + pdf = KorekturovanePDF.objects.get(id=q.get('pdf')) + if (q.get('state') == 'adding'): + pdf.status = pdf.STATUS_PRIDAVANI + elif (q.get('state') == 'comitting'): + pdf.status = pdf.STATUS_ZANASENI + elif (q.get('state') == 'deprecated'): + pdf.status = pdf.STATUS_ZASTARALE + pdf.save() + context = self.get_context_data() + context['scroll'] = scroll + context['autor'] = autor + return render(request, 'korektury/opraf.html',context) + + def send_email_notification_komentar(self, oprava, autor, text): + ''' Rozesle e-mail pri pridani komentare, + ktery obsahuje text komentare. + ''' + + # parametry e-mailu + #odkaz = "https://mam.mff.cuni.cz/korektury/{}/".format(oprava.pdf.pk) + from django.urls import reverse + odkaz = self.request.build_absolute_uri(reverse('korektury', kwargs={'pdf': oprava.pdf.pk})) + from_email = 'korekturovatko@mam.mff.cuni.cz' + subject = 'Nová korektura od {} v {}'.format(autor, + oprava.pdf.nazev) + text = u"Text komentáře:\n\n{}\n\n=== Konec textu komentáře ===\n\ + \nodkaz do korekturovátka: {}\n\ + \nVaše korekturovátko\n".format(text, odkaz) + + # Prijemci e-mailu + emails = set() + # e-mail autora korektury + email = oprava.autor.osoba.email + if email: + emails.add(email) + + # nalezeni e-mailu na autory komentaru + for komentar in oprava.komentar_set.all(): + email_komentujiciho = komentar.autor.osoba.email + if email_komentujiciho: + emails.add(email_komentujiciho) + + # zodpovedny org + if oprava.pdf.org: + email_zobpovedny = oprava.pdf.org.osoba.email + if email_zobpovedny: + emails.add(email_zobpovedny) + + # odstran e-mail autora opravy + email = autor.osoba.email + if email: + emails.discard(email) + + if not settings.POSLI_MAILOVOU_NOTIFIKACI: + print("Poslal bych upozornění na tyto adresy: ", " ".join(emails)) + return + + send_mail(subject, text, from_email, list(emails)) + + def get_context_data(self, **kwargs): + context = super(KorekturyView,self).get_context_data(**kwargs) + pdf = get_object_or_404(KorekturovanePDF, id=self.kwargs['pdf']) + context['pdf'] = pdf + context['img_prefix'] = pdf.get_prefix() + context['img_path'] = settings.KOREKTURY_IMG_DIR + context['img_indexes'] = range(pdf.stran) + context['form_oprava'] = OpravaForm() + opravy = Oprava.objects.filter(pdf=self.kwargs['pdf']) + zasluhy = {} + for o in opravy: + if o.autor in zasluhy: + zasluhy[o.autor]+=1 + else: + zasluhy[o.autor]=1 + o.komentare = o.komentar_set.all() + for k in o.komentare: + if k.autor in zasluhy: + zasluhy[k.autor] += 1 + else: + zasluhy[k.autor] = 1 + zasluhy = [ + {'autor': jmeno, 'pocet': pocet} + for (jmeno, pocet) in zasluhy.items() + ] + zasluhy.sort(key=lambda z: z['pocet'], reverse=True) + + strany = set(o.strana for o in opravy) + opravy_na_stranu = [{'strana': s, 'op_id': opravy.filter(strana=s)} for s in strany] + context['opravy_strany'] = opravy_na_stranu + + context['k_oprave_cnt'] = opravy.filter(status='k_oprave').count() + context['opraveno_cnt'] = opravy.filter(status='opraveno').count() + context['neni_chyba_cnt'] = opravy.filter(status='neni_chyba').count() + context['k_zaneseni_cnt'] = opravy.filter(status='k_zaneseni').count() + + context['opravy'] = opravy + context['zasluhy'] = zasluhy + return context + + def form_valid(self,form): + return super(KorekturyView,self).form_valid(form) diff --git a/mamweb/admin.py b/mamweb/admin.py index b483bf18..12d063f7 100644 --- a/mamweb/admin.py +++ b/mamweb/admin.py @@ -7,7 +7,8 @@ from django.contrib.flatpages.admin import FlatpageForm as FlatpageFormOld from django import forms from ckeditor_uploader.widgets import CKEditorUploadingWidget - + + class FlatpageForm(FlatpageFormOld): content = forms.CharField(widget=CKEditorUploadingWidget()) class Meta: @@ -22,3 +23,4 @@ class FlatPageAdmin(FlatPageAdminOld): # We have to unregister the normal admin, and then reregister ours admin.site.unregister(FlatPage) admin.site.register(FlatPage, FlatPageAdmin) + diff --git a/mamweb/context_processors.py b/mamweb/context_processors.py deleted file mode 100644 index a07ddc7e..00000000 --- a/mamweb/context_processors.py +++ /dev/null @@ -1,27 +0,0 @@ - -from datetime import datetime, date - -def vzhled(request): - ''' Podle casu prida do templatu, zdali je nebo neni noc ''' - hodin = datetime.now().hour - if (hodin <= 6) or (hodin >= 20): - noc = True - else: - noc = False - return {'noc' : noc} - -def april(req): - if 'HTTP_X_APRIL' in req.META: - try: - year = int(req.META['HTTP_X_APRIL']) - return {'april': year} - except: - pass # Fall-back to regular behaviour - - import datetime - today = datetime.date.today() - if today.day == 1 and today.month == 4: - return {'april': today.year} - return {} - - diff --git a/mamweb/routers.py b/mamweb/routers.py new file mode 100644 index 00000000..003dd5a6 --- /dev/null +++ b/mamweb/routers.py @@ -0,0 +1,15 @@ +from rest_framework import routers +from seminar import viewsets as vs + +router = routers.DefaultRouter() + +router.register(r'ulohavzoraknode', vs.UlohaVzorakNodeViewSet,basename='ulohavzoraknode') +router.register(r'reseninode', vs.ReseniNodeViewSet,basename='reseninode') +router.register(r'text', vs.TextViewSet) +router.register(r'textnode', vs.TextNodeViewSet) +router.register(r'castnode', vs.CastNodeViewSet) +router.register(r'problem', vs.ProblemViewSet, basename='problem') +router.register(r'uloha', vs.UlohaViewSet, basename='uloha') +router.register(r'reseni', vs.ReseniViewSet, basename='reseni') +router.register(r'ulohazadaninode', vs.UlohaZadaniNodeViewSet) + diff --git a/mamweb/settings_common.py b/mamweb/settings_common.py index 84a9d7b3..5a3d2e9a 100644 --- a/mamweb/settings_common.py +++ b/mamweb/settings_common.py @@ -43,7 +43,8 @@ STATICFILES_FINDERS = ( ) # Where redirect for login required services -LOGIN_URL = '/admin/login' +LOGIN_URL = 'login' +LOGIN_REDIRECT_URL = 'profil' # Modules configuration @@ -52,14 +53,15 @@ AUTHENTICATION_BACKENDS = ( ) -MIDDLEWARE_CLASSES = ( - 'reversion.middleware.RevisionMiddleware', +MIDDLEWARE = ( +# 'reversion.middleware.RevisionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', - 'mamweb.middleware.LoggedInHintCookieMiddleware', +# FIXME: rozbilo se při přechodu na Django 2.0, nevím, jestli +# se to dá zahodit bez náhrady +# 'mamweb.middleware.LoggedInHintCookieMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware', @@ -73,10 +75,11 @@ TEMPLATES = [ 'OPTIONS': { 'context_processors': ( 'django.contrib.auth.context_processors.auth', + 'django.template.context_processors.request', 'django.contrib.messages.context_processors.messages', 'sekizai.context_processors.sekizai', - 'mamweb.context_processors.vzhled', - 'mamweb.context_processors.april', + 'header_fotky.context_processors.vzhled', + 'various.context_processors.april', ) }, }, @@ -103,7 +106,8 @@ INSTALLED_APPS = ( 'ckeditor', 'ckeditor_uploader', 'taggit', - 'autocomplete_light', + 'dal', + 'dal_select2', 'fluent_comments', 'crispy_forms', @@ -113,14 +117,24 @@ INSTALLED_APPS = ( 'django.contrib.flatpages', 'django.contrib.humanize', + 'sitetree', + 'imagekit', + 'polymorphic', + + 'webpack_loader', + 'rest_framework', + 'rest_framework.authtoken', + # MaMweb 'mamweb', 'seminar', 'galerie', 'korektury', 'prednasky', + 'header_fotky', + 'various', # Admin upravy: @@ -177,6 +191,27 @@ CKEDITOR_CONFIGS = { }, } +# Webpack loader +VUE_FRONTEND_DIR = os.path.join(BASE_DIR, 'vue_frontend') + +WEBPACK_LOADER = { + 'DEFAULT': { + 'CACHE': False, + 'BUNDLE_DIR_NAME': 'vue/', # must end with slash + 'STATS_FILE': os.path.join(VUE_FRONTEND_DIR, 'webpack-stats.json'), + 'POLL_INTERVAL': 0.1, + 'TIMEOUT': None, + 'IGNORE': [r'.+\.hot-update.js', r'.+\.map'] + } +} + + +# Dajngo REST Framework + +REST_FRAMEWORK = { + 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination', + 'PAGE_SIZE': 100 +} # Comments @@ -212,6 +247,14 @@ LOGGING = { 'handlers': ['console'], 'level': 'DEBUG', }, + 'seminar.prihlaska.form':{ + 'handlers': ['console','registration_logfile'], + 'level': 'INFO' + }, + 'seminar.prihlaska.problem':{ + 'handlers': ['console','mail_registration','registration_error_log'], + 'level': 'INFO' + }, # Catch-all logger '': { @@ -230,10 +273,28 @@ LOGGING = { }, 'mail_admins': { - 'level': 'ERROR', + 'level': 'WARNING', + 'class': 'django.utils.log.AdminEmailHandler', + 'formatter': 'verbose', + }, + 'mail_registration': { + 'level': 'WARNING', 'class': 'django.utils.log.AdminEmailHandler', 'formatter': 'verbose', }, + 'registration_logfile':{ + 'level': 'INFO', + 'class': 'logging.FileHandler', + # filename declared in specific configuration files + 'formatter': 'verbose', + }, + 'registration_error_log':{ + 'level': 'INFO', + 'class': 'logging.FileHandler', + # filename declared in specific configuration files + 'formatter': 'verbose', + }, + }, } @@ -250,4 +311,4 @@ CISLO_IMG_DIR = os.path.join('cislo', 'img') # E-MAIL NOTIFICATIONS -SEND_EMAIL_NOTIFICATIONS = False +POSLI_MAILOVOU_NOTIFIKACI = False diff --git a/mamweb/settings_debug.py b/mamweb/settings_debug.py new file mode 100644 index 00000000..7dd34fae --- /dev/null +++ b/mamweb/settings_debug.py @@ -0,0 +1,13 @@ +# Debugovaci nastaveni settings.py +# Pro vyber tohoto nastaveni muzete pouzit tez: +# DJANGO_SETTINGS_MODULE=mamweb.settings_debug ./manage.py ... + +# Import local settings +from .settings_local import * + +# Vypisovani databazovych dotazu do konzole +LOGGING['loggers']['django.db.backends'] = { + 'level': 'DEBUG', + 'handlers': ['console'], + 'propagate': False, +} diff --git a/mamweb/settings_local.py b/mamweb/settings_local.py index 501326dd..0aadd27e 100644 --- a/mamweb/settings_local.py +++ b/mamweb/settings_local.py @@ -10,7 +10,7 @@ import os.path # Import common settings from .settings_common import * -MIDDLEWARE_CLASSES += ( +MIDDLEWARE += ( 'debug_toolbar.middleware.DebugToolbarMiddleware', ) @@ -24,10 +24,11 @@ INSTALLED_APPS += ( # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True +INTERNAL_IPS = ['127.0.0.1'] TEMPLATES[0]['OPTIONS']['debug'] = True -ALLOWED_HOSTS = ['127.0.0.1'] +ALLOWED_HOSTS = ['127.0.0.1', '192.168.43.34'] # Database # https://docs.djangoproject.com/en/1.7/ref/settings/#databases @@ -47,7 +48,52 @@ DATABASES = { #} # LOGGING +LOGGING = { + 'version': 1, + 'disable_existing_loggers': True, + 'filters': { + 'require_debug_false': { + '()': 'django.utils.log.RequireDebugFalse' + } + }, + 'formatters': { + 'simple': { + 'format': '%(asctime)s - %(name)s - %(levelname)-8s - %(message)s', + }, + }, + 'handlers': { + 'dummy': { + 'class': 'logging.NullHandler', + }, + 'console': { + 'level': 'DEBUG', + 'class': 'logging.StreamHandler', + 'formatter': 'simple', + }, + }, + 'loggers': { + # Vypisovani databazovych dotazu do konzole + #'django.db.backends': { + # 'level': 'DEBUG', + # 'handlers': ['console'], + # 'propagate': False, + #}, + 'werkzeug': { + 'handlers': ['console'], + 'level': 'DEBUG', + 'propagate': True, + }, + '': { + 'handlers': ['console'], + 'level': 'DEBUG', + 'propagate': False, + }, + }, +} # set to 'DEBUG' for EXTRA verbose output -LOGGING['handlers']['console']['level'] = 'INFO' +# LOGGING['handlers']['console']['level'] = 'INFO' +# E-maily posílat chceme, ale do terminálu :-) +EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' +SEND_EMAIL_NOTIFICATIONS = True diff --git a/mamweb/settings_prod.py b/mamweb/settings_prod.py index 918fd4b2..0374d88b 100644 --- a/mamweb/settings_prod.py +++ b/mamweb/settings_prod.py @@ -61,7 +61,9 @@ CSRF_COOKIE_SECURE = True LOGGING['loggers']['']['handlers'] = ['console', 'mail_admins'] LOGGING['loggers']['django']['handlers'] = ['console', 'mail_admins'] +LOGGING['handlers']['registration_logfile']['filename'] = '/home/mam-web/logs/prod/registration.log' +LOGGING['handlers']['registration_error_log']['filename'] = '/home/mam-web/logs/prod/registration_errors.log' # E-MAIL NOTIFICATIONS -SEND_EMAIL_NOTIFICATIONS = True +POSLI_MAILOVOU_NOTIFIKACI = True diff --git a/mamweb/settings_test.py b/mamweb/settings_test.py index 9f971f45..f8fd844e 100644 --- a/mamweb/settings_test.py +++ b/mamweb/settings_test.py @@ -12,7 +12,7 @@ import os.path # Import common settings from .settings_common import * # zatim nutne, casem snad vyresime # noqa -MIDDLEWARE_CLASSES += ( +MIDDLEWARE += ( 'debug_toolbar.middleware.DebugToolbarMiddleware', ) @@ -32,7 +32,7 @@ DEBUG = True TEMPLATES[0]['OPTIONS']['debug'] = True -ALLOWED_HOSTS = ['*.mam.mff.cuni.cz', 'atrey.karlin.mff.cuni.cz', 'mam.mff.cuni.cz', 'mam-test.kam.mff.cuni.cz', 'gimli.ms.mff.cuni.cz'] +ALLOWED_HOSTS = ['*.mam.mff.cuni.cz', 'atrey.karlin.mff.cuni.cz', 'mam.mff.cuni.cz', 'mam-test.kam.mff.cuni.cz', 'gimli.ms.mff.cuni.cz', 'mam-test.ks.matfyz.cz'] # Database # https://docs.djangoproject.com/en/1.7/ref/settings/#databases @@ -65,3 +65,14 @@ CSRF_COOKIE_SECURE = True LOGGING['loggers']['']['handlers'] = ['console', 'mail_admins'] LOGGING['loggers']['django']['handlers'] = ['console', 'mail_admins'] +LOGGING['handlers']['registration_logfile']['filename'] = '/home/mam-web/logs/test/registration.log' +LOGGING['handlers']['registration_error_log']['filename'] = '/home/mam-web/logs/test/registration_errors.log' + +FILE_UPLOAD_PERMISSIONS = 0o440 + +# Testování e-mailů +POSLI_MAILOVOU_NOTIFIKACI = True +EMAIL_BACKEND = 'various.mail_prefixer.PrefixingMailBackend' +# TODO Pouze na otestování testu… Zvolit konferu! +# XXX: Je to pole, protože implementační detail backendu. +TESTOVACI_EMAILOVA_KONFERENCE = ['betatest@mam.mff.cuni.cz'] diff --git a/mamweb/static/css/mamweb-dev.css b/mamweb/static/css/mamweb-dev.css new file mode 100644 index 00000000..576da844 --- /dev/null +++ b/mamweb/static/css/mamweb-dev.css @@ -0,0 +1,38 @@ +/* +.pink { + background-color: #ffc0cb; +} + +div.borderized { + border-style: solid; + border-radius: 5px; + padding: 5px; + padding-right: 20px; +} + +div.tnmenu { + float: right; + margin-right: 0px; +} + + +div.parent { + border-width: 2px; +} + +div.children { + border-width: 1px; +} + +div.node_type { + background-color: #d4d4d4; +} + +.hidden-tn { + display: none; +} + +/*test*/ +h1 { + color: chartreuse; +} diff --git a/mamweb/static/css/mamweb.css b/mamweb/static/css/mamweb.css index 6e5b9488..69f99ca3 100644 --- a/mamweb/static/css/mamweb.css +++ b/mamweb/static/css/mamweb.css @@ -1,21 +1,143 @@ -@import url(https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,400,300,600&subset=latin,latin-ext); +@font-face { +font-family: 'OpenSans'; +src: url("../fonts/OpenSans/OpenSans-Regular.ttf"); +font-weight: normal; +} body { - font-family: 'Open Sans', sans-serif; - font-weight: 400; + font-family: 'OpenSans'; + background-color: #fffbf6; + min-height: 100%; +} +div.content-wrapper { + padding-bottom: 200px; /* Footer height */ +} + +div.container { + width: 970px; + margin: auto; + min-height: 100vh; + position: relative; +} + +.org-logged-in div.container { + margin-top: 20px; +} + +div.login-bar { + background: #6a0043; + color: #f9d59e; + width: 100%; + + position: fixed; + margin-top: -20px; + min-height: 20px; + z-index: 20; + + padding-left: 5px; + padding-right: 5px; +} + +div.login-bar div { + display: inline; +} + +a.login-ref-admin { + display: inline; + color: #fffbf6; +} + +/* odkazy a nadpisy */ + +a { + color: #6f2509; +} + +a:focus, a:hover, a:active { + color: #e84e10; + text-decoration: none; +} + +img { + filter: drop-shadow(0px 3px 3px rgba(0, 0, 0, 0.4)); + max-width: 100%; + height: auto; +} + +h1 { /*todo: odlišit 1 a 2 */ + font-size: 200%; + font-variant: small-caps; + font-weight: bold; + color: #6f2509; +} + +h2 { + font-size: 200%; + font-variant: small-caps; + font-weight: bold; + color: #6f2509; +} + +h3 { + font-size: 160%; + font-variant: small-caps; + font-weight: bold; + color: #6f2509; } +h4 { + font-size: 140%; + font-variant: small-caps; + font-weight: bold; + color: #6f2509; +} + +h5 { + font-size: 140%; + font-variant: small-caps; + font-weight: bold; + color: black; +} + +h6 { + font-size: 120%; + font-variant: small-caps; + font-weight: bold; + color: black; +} + +.button { + margin: 10px 0px 10px 0px; + padding: 4px 0; /*vertikální centování textu*/ + text-align: center; + background-color: #e84e10; + color: #fffbf6; + font-size: 150%; + font-weight: bold; + font-variant: small-caps; + filter: drop-shadow(0px 5px 5px rgba(0, 0, 0, 0.4)); +} + +.button:hover { + position: relative; + top: 2px; + left:2px; + background-color: #df490e; +; +} + + .org-logged-in .mam-text-plugin { - border: dashed 1px #f77; + border: dashed 1px #6a0043; padding: 5px; margin: -5px; } .mam-org-only { - background: #fff0d7; - padding: 10px; - margin: 10px -10px; - border: orange 2px dashed; + background: #eee4ec; + padding: 10px; + margin: 10px -10px; + border: #6a0043 2px dashed; } .mam-org-only .mam-org-only { @@ -43,8 +165,11 @@ table .border-b { border: solid 2px; } +.podproblem { + color: gray; +} + div.container { - background-color: #fff8eb; padding: 0px; } @@ -56,6 +181,8 @@ h1 { margin-top: 0px; } + + /* Comments */ #id_comment { @@ -65,392 +192,750 @@ h1 { /* Headline & Header */ -#header { - position: relative; - font-size: 250%; - background: url("../images/header-bg-uvod.jpg") no-repeat center top; - height: 255px; - top: -1px; +#title { /*dělá blbosti šířka, je to kvůli fixed pozici, zatím natvrdo, vyřešit*/ + height: 55px; + width: 970px; + position: fixed; + z-index: 10; + background-color: #e84e10; + filter: drop-shadow(0px 5px 5px rgba(0, 0, 0, 0.4)); + + font-size: 28px; + color: #fffbf6; + font-weight: 400; + font-variant: small-caps; + text-align: center; + text-decoration: none; + padding-top: 8px; + text-shadow: none; } +#title-mobile { + display: none; +} -#header.cojemam { background-image: url("../images/header-bg-uvod.jpg"); } -#header.soustredeni { background-image: url("../images/header-bg-soustredeni.jpg"); } -#header.zadani { background-image: url("../images/header-bg-zadani.jpg"); } -#header.clanky { background-image: url("../images/header-bg-clanek.jpg"); } -#header.archiv { background-image: url("../images/header-bg-archiv.jpg"); } -#header.NOC {background-image: url("../images/header-bg-uvod-NOC.jpg"); } -#header.NOCcojemam { background-image: url("../images/header-bg-uvod-NOC.jpg"); } -#header.NOCsoustredeni { background-image: url("../images/header-bg-soustredeni-NOC.jpg"); } -#header.NOCzadani { background-image: url("../images/header-bg-zadani-NOC.jpg"); } -#header.NOCclanky { background-image: url("../images/header-bg-clanek-NOC.jpg"); } -#header.NOCarchiv { background-image: url("../images/header-bg-archiv-NOC.jpg"); } +#header { + position: relative; + background: url("../images/header/vikendovka.jpg") no-repeat center top; /* poměr 350:970, TODO: aby to nemuselo být přesně na pixely */ + background-size: 100%; + top: 58px; +} #header img.logo { - position: absolute; - top: 40px; - left: 55px; -} -/* -#header h1 { - font-size: 130%; - position: absolute; - top: 125px; - left: 30px; - height: 110px; + position: absolute center; + width: 100%; + filter: drop-shadow(0px 5px 5px rgba(0, 0, 0, 0.4)); } -*/ -#header img.header { - margin: -25px 20px 0px 0px; - height: 145px; - float: right; - visibility: hidden; + +#header img.logo-mobile { + display: none; } /* Menu */ -div.menu.mobile { +ul.menu_mobile { display: none; } -div.menu.desktop { - display: block; + +nav.nav-button { + display: none; } -div.menu { - position: relative; - top: -10px; - z-index: 10; - background: url("../images/menu-bg.png") no-repeat left top; - height: 60px; + +div.dropdown-backdrop { /* tohle způsobuje, že funguje mobilní menu */ + z-index: -1; } -div.menu ul { + +h1 a:hover { + text-decoration: none; +} + +/* nové menu */ + +ul.menu { + width: 100%; padding: 0px; - margin: 0px; + margin-top: -5px; /* posune celé menu nahoru (pak potřeba zvětšit mezeru mezi menu a submenu) */ + + font-variant: small-caps; } -div.menu li { + +ul.menu a { + text-decoration: none; + font-weight: bold; + font-size: 105%; +} + +ul.menu li { + margin: 0px; display: inline-block; - border-radius: 0px; - - padding: 6px 0px 0px 0px; - width: 16.66%; - min-width: 140px; + width: 16.666667%; text-align: center; - + font-size: 140%; font-weight: 400; - font-variant: small-caps; - border-bottom-left-radius: 8px; - border-bottom-right-radius: 8px; -} -div.menu a { - display: block; - padding: 8px 10px; - color: #006400; - height: 48px; -} -div.menu a:hover { - background: url("../images/menu-bg-selected.png") no-repeat left -7px; - background-size: 100% 68px; - text-decoration: none; - color: #003c00; } -div.menu li.selected a { - background: url("../images/menu-bg-selected.png") no-repeat left -7px; - background-size: 100% 68px; - text-decoration: none; - color: #003c00; - z-index: 15px; + +ul.menu li>a:hover { + color: black; } -h1 a:hover { - text-decoration: none; +ul.menu li>a:active { /* TODO: nefunfuje */ + color: black; } -#submenu { - position: relative; - top: -15px; - background: url("../images/submenu-bg.png") no-repeat left top; - height: 60px; +ul.submenu { + + background-color: #e84e10; + margin-top: 10px; /* mezera mezi hlavním menu a submenu */ + margin-bottom: 10px; + padding-top: 10px; + padding-bottom: 5px; + filter: drop-shadow(0px 5px 5px rgba(0, 0, 0, 0.4)); } -#submenu ul { - padding: 0px 15px; - font-size: 120%; + +ul.submenu { + background-color: #e84e10; + z-index: 50; font-weight: 400; } -#submenu li { - padding: 4px 20px; + +ul.submenu li { + width: auto; + padding: 0px 20px 0px 20px; display: inline-block; - height: 40px; } -#submenu li>a { - color: #003c00; +ul.submenu li>a { + color: #f9d59e; text-decoration: none; + text-shadow: none; } -#submenu li>a:hover { - color: #3c003c; -} -#submenu li.selected { - background: url("../images/submenu-bg-selected.png") no-repeat center; - background-size: 150% 150%; -} -#submenu li.selected>a { - color: #3c003c; + +ul.submenu li>a:hover { + color: black; } -/*#submenu li:first-child { - border-top-left-radius: 7px; - border-top-right-radius: 7px; - padding-top: 8px; + +ul.menu li.active>a { + color: #f9d59e; } -#submenu li:last-child { - border-bottom-left-radius: 7px; - border-bottom-right-radius: 7px; - padding-bottom: 8px; + +ul.submenu li.active>a { + color: black; } -#submenu li>a:hover { - text-decoration: none; -}*/ + +/* konec nového menu */ div.novinky_name { text-align: right; font-style: italic; } -div.zadani_azad_termin { - text-align: center; - font-size: large; - font-weight: bold -} + /********** - * Footer + * Footer **********/ -#footer { - background: url("../images/footer-bg-top.png") no-repeat top center; - background-color: #ffd546; - padding: 20px 30px 0px 30px; - min-height: 210px; -} -#footer-extra { - background: url("../images/footer-bg-bottom.png") no-repeat bottom center; - height: 39px; +#footer { + position: absolute; + bottom: 0; + width: 100%; + background: url("../images/mozaika-footer.svg") no-repeat top center; + height: 200px; + background-position: relative; + background-size: 100%; + filter: drop-shadow(5px 0px 5px rgba(0, 0, 0, 0.4)); + padding-top: 3.5%; } #footer p.license { text-align: center; font-weight: 400; + bottom: 0px; +} + +#footer p.license a { + color: #333; +} + +p.license-mobile { + display: none; + margin-bottom: 0px; +} + +/*********************/ + +/* přihláška a další formuláře */ + +table.form td, table.form tr { + table-layout: fixed; + word-wrap: break-word; + padding: 5px; } -#footer p.organize { +table#reseni.form td, table#reseni.form tr { + display: inline-table; +} + +input[type="file"] { + max-width: 250px; + text-overflow: ellipsis; +} + +.field-with-comment{ + position:relative; +} + +.field-comment{ + display:none; + text-shadow: 0 1px 0 #fff; + background-color: #f0f0f0 ; + border-color: #dbdbdb; + position:absolute; + z-index:100; + border:1px; + border-style:solid; + border-width:1px; + border-radius: 5px; + padding:3px; + top:50px; + left:10px; +} + +.field-with-comment:hover span.field-comment{ + display: block; +} + +input { + margin: 5px; +} + + +/* titulni stranka */ + +.titulnistrana { + display: flex; + text-align: justify; +} + +.titulnistrana h1 { text-align: center; - margin-top: 50px; - margin-left: 30px; - display: inline-block; - max-width: 350px; } -#footer img.logo-left { - padding: 50px 0px 0px 0px; - float: left; +.zjistit_vic{ + text-align: center; + margin-bottom: 30px; } -#footer img.logo-right { - padding: 40px 0px 00px 10px; - float: right; +.zjistit_vic hr { + display: none; } -.foto_org { - width: 250px; - text-align: center; +.graf-svg { + display: flex; } -#seznam_orgu h1 { - text-align: center; +#svg-graf { + width: 100%; + height: auto; + margin: 30px; +} + +.titulnistrana_obsah { + width: 66%; +} + +.vitej_titulka, .temata_titulka { + width: 49%; + padding: 10px; + display: table-cell; +} + +.titulnistrana_novinky { + width: 33%; + padding: 10px; +} + +.novinka_obrazek { + margin: 10px 0px 10px 0px; + width: 100%; +} + +.novinka_datum { + font-weight: bold; } -@media (max-width: 991px) { +.novinka_autor { + text-align: right; + font-style: italic; +} + +div.org-text { + font-style: italic; +} + +div.odpocet { + margin: 20px; + text-align: center; +} + +/********************** + * Zmenšování displeje +***********************/ + + +/* stránka přes celý displej */ +@media (max-width: 970px) { + + div.container { + width: 100%; + } + + #title { + width: 100%; + text-align: center; + } + #header { - height: 196px; - background-size: 100% 100%; + background-size: 100%; } + #header img.logo { - top: 27px; - left: 35px; - height: 140px; + width: 100%; } - div.menu li { - min-width: 120px; - font-size: 130%; + + #footer { + width: 100%; } - #submenu ul { - font-size: 115%; + + ul.menu { + font-size: 90%; + margin-top: -7px; } - #submenu li { - padding-top: 5px; + + ul.menu li { + margin-top: 10px; /* posunutí textu hlavního menu níže */ } - #footer { - padding: 20px 40px 0px 40px; - min-height: 270px; + + ul.submenu li { + margin-top: 0px; /* aby se spolu s textem hlavního menu neposunoval níže i text submenu */ } - #footer-extra { - position: relative; - top: -10px; - height: 39px; + + ul.submenu { + margin-top: 8px; /* mezera mezi hlavním menu a submenu */ } - - #footer p.organize { - margin-top: 50px; - margin-left: 0px; - max-width: 80%; - min-height: 70px; + +} + +/* stránka přes celý menší displej, větší mobil, tablet */ +@media(max-width: 800px){ + + ul.menu { + font-size: 80%; + margin-top: -2px; } - - #footer img.logo-left { - padding: 50px 20px 0px 13px; - float: left; + + ul.menu li { + margin-top: 10px; /* posunutí textu hlavního menu níže */ } - - #footer img.logo-right { - padding: 20px 0px 20px 0px; - float: none; + + ul.submenu li { + margin-top: 0px; /* aby se spolu s textem hlavního menu neposunoval níže i text submenu */ + } + + ul.submenu { + margin-top: 8px; /* mezera mezi hlavním menu a submenu */ + } + + a.ref-org-foto { + pointer-events: none; + } + + table#reseni.form td, table#reseni.form tr { + display: inline-grid; + max-width: 300px; + } + + /* titulni stranka */ + + .titulnistrana { + display: block; } - - div.novinky{ - max-width: 100%; - margin-left: auto; - margin-right: auto; - float: none; - } - div.graf{ - float: none; - margin-left: auto; - margin-right: auto; - width: 70%; - } + .graf { + padding-top: 40px; + } + + .titulnistrana_obsah { + width: 100%; + } + .vitej_titulka, .temata_titulka { + width: 49%; + padding: 10px; + display: table-cell; + } + + .titulnistrana_novinky { + width: 100%; + max-width: 500px; + padding: 10px; + margin: auto; + } + + #svg-graf { + width: 100%; + max-width: 500px; + padding: 10px; + margin: auto; + } + + .zjistit_vic hr { + display: flex; + } } -@media (max-width: 767px) { +/* malý tablet, mobil */ +@media (max-width: 650px) { + + .no-mobile{ + display: none; + } + + #hide-if-small.login-bar-flatpage { + display: none; + } + + #title { + display: none; + } + #header { width: 100%; - height: 196px; - height: 0px; - background-size: 100%; - padding-bottom: 25%; + top: 0px; + background-image: none; + } + + #header.cojemam, + #header.soustredeni, + #header.zadani, + #header.clanky, + #header.archiv, + #header.NOC, + #header.NOCcojemam, + #header.NOCsoustredeni, + #header.NOCzaani, + #header.NOCclanky, + #header.NOCarchiv { + background-image: none; } + #header img.logo { + display: none; + } + + #header img.logo-mobile { + display: block; top: 0px; left: 0px; - height: 100%; + width: 100%; + filter: drop-shadow(0px 0px 5px rgba(0, 0, 0, 0.4)); + margin-bottom: 3px; } - div.menu { - height: auto; + +/* mobilní menu */ + ul.menu { + display: none; } - div.menu li { + + ul.menu_mobile { display: block; - width: 100%; - height: 35px; - font-size: 130%; + z-index: 10; + position: sticky; + font-variant: small-caps; + font-size: 150%; + font-weight: bold; + list-style-type: none; + padding-top: 3px; + padding-bottom: 3px; + padding-left: 12px; } - #submenu { - background: none; - height: auto; - margin-left: 90px; - margin-top: 15px; + + ul.menu_mobile a:active, + ul.menu_mobile a:hover, + ul.menu_mobile a:focus { + text-decoration: none; + color: black; } - #submenu ul { - font-size: 110%; + + ul.menu_mobile ul { + list-style-type: none; + font-size: 90%; + color: black; /*černé šipky submenu*/ } - #submenu li { - display: inline-block; - margin: 5px 8px; - border-radius: 30px; - background: #ffd546; - height: auto; + + ul.menu_mobile ul li>a { + color: black; } - #submenu li a:hover, #submenu li.selected { - background: #ffd546; + + ul.menu_mobile ul li::before { + content: ' \276D '; /*https://www.w3schools.com/cssref/css_entities.asp*/ + } + + ul.menu_mobile br { + display: none; } - div.menu.mobile { + + nav.nav-button { display: block; - position: absolute; - top: -1px; - background: none; + position: sticky; + position: -webkit-sticky; + top: 0; + z-index: 10; } - div.menu.mobile > div.dropdown > button { - font-size: 20px; + + #navbar-content { + background-color: #e84e10; } - div.menu.mobile > div.dropdown > ul { - margin: 0px; - padding: 0px; + + button.navbar-button { + color: #f9d59e; + background-color: #e84e10; + font-variant: small-caps; + font-size: 160%; border-radius: 0px; + border-width: 0px; + width: 100%; + text-align: right; } - div.menu.mobile > div.dropdown > ul > li { - margin: 0px; - padding: 0px; - display: block; - font-size: 20px; - background: none; - font-variant: normal; - height: auto; - } - div.menu.mobile > div.dropdown > ul > li > a { - margin: 0px; - padding: 5px 30px; - height: auto; - } - div.menu.mobile > div.dropdown > ul > li > a:hover { - background: #ffa500; + + button.navbar-button span::after{ + content: ' \2261 '; + font-size: 120%; } - div.menu.desktop { + li.dropdown div.submenu_mobile{ display: none; } - + + li.dropdown.open div.submenu_mobile{ + display: block; + } + + + /*patička mobil*/ + #footer { - padding: 20px 40px 0px 40px; - min-height: 270px; + display: none; } - #footer-extra { + + p.license-mobile { position: relative; - top: -10px; - height: 39px; + display: block; + font-size: 90%; + background-color: #e84e10; + padding: 5%; + text-align: justify; } - - #footer p.license { - font-size: 80%; + + table.form td, table.form tr { + display: inherit; + } + + /* titulni stranka */ + + .titulnistrana { + display: block; } - #footer p.organize { - margin: 30px 0px 0px 0px; - min-height: 80px; - width: 300px; - font-size: 90%; + + .graf { + padding-top: 40px; } - - #footer img.logo-left { - padding: 30px 20px 0px 18px; - float: left; + + .titulnistrana_obsah { + width: 100%; } - - #footer img.logo-right { - padding: 30px 0px 20px 0px; - float: none; + + .vitej_titulka, .temata_titulka { + width: 100%; + padding: 10px; + display: block; } - - div.novinky{ - max-width: 100%; - float: none; - } - div.graf{ - float: none; - width: 70%; - margin-left: auto; - margin-right: auto; - - } + .titulnistrana_novinky { + width: 100%; + padding: 10px; + } + +} + +/*stránka organizátorů*/ + +div.seznam_orgu, div.rozcestnik_temat, div.seznam_archiv { + text-align: center; + padding-bottom: 10px; +} + +div.org_pole, div.rocnik_pole, div.tema_pole { + display: inline-block; + width: 30%; + min-width: 300px; + text-align: center; +} + +div.tema_pole { + display: inline-block; + width: 40%; + min-width: 350px; + padding-bottom: 20px; + text-align: center; +} + +div.cislo_pole { + display: inline-block; + width: 15%; + min-width: 165px; + text-align: center; + padding: 10px; +} + +div.seznam_orgu h3 { + text-align: center; + margin-top: 10px; + margin-bottom: 0px; +} + +div.org_email { + margin-bottom: 10px; + font-weight: bold; +} + +/*otáčecí karty (orgové, archiv) */ + +.flip-card { + perspective: 1000px; /* Remove this if you don't want the 3D effect */ + margin-left: auto; + margin-right: auto; +} + +#organizatori.flip-card { + width: 200px; + height: 250px; +} + +#archiv.flip-card { + width: 210px; + height: 298px; +} + +#archiv-rocnik.flip-card { + width: 144px; + height: 205px; +} + +#tema-rozcestnik.flip-card { + width: 300px; + height: 300px; +} + +/* This container is needed to position the front and back side */ +.flip-card-inner { + position: relative; + width: 100%; + height: 100%; + transition: transform 0.8s; + transform-style: preserve-3d; +} + +/* Do an horizontal flip when you move the mouse over the flip box container */ +.flip-card:hover .flip-card-inner { + transform: rotateY(180deg); +} + +/* Position the front and back side */ +.flip-card-front, .flip-card-back { + position: absolute; + width: 100%; + height: 100%; + -webkit-backface-visibility: hidden; /* Safari */ + backface-visibility: hidden; +} + + +div.flip-card-foto, div.flip-card-foto img { + width: 100%; + height: 100%; + +} + +/* Style the back side */ +.flip-card-back { + background-color: #f9d59e; + color: black; + transform: rotateY(180deg); + padding: 10px; + padding-top: 20px; +} + +#archiv.flip-card-back { + background-color: white; +} + +/* karty archiv */ + +div.popis_rocniku { + text-align: left; + font-weight: bold; + margin: 20px; +} + + +div.popis_rocniku a, div.cislo_odkazy a { + font-weight: bold; + color: black; +} + +div.popis_rocniku a:hover, +div.cislo_odkazy a:hover { + color: #6f2509; +} + +div.cislo_odkazy ul { + margin: 0px; + padding: 0px; +} + +/* aktuální zadání */ +.stranka_aktualni_zadani { + text-align: center; +} + +#azad_obrazek { + margin-top: 15px; +} + +div.zadani_termin { + text-align: center; + font-size: large; + font-weight: bold; +} + +@media (max-width: 420px) { + div.zadani_termin { + font-size: small; + } + +} + +div.zadani_termin .datum { + color:#e84e10; + margin:0px; +} + +#obrazek_cisla_archiv { + text-align: center; + margin: 10px; } @@ -473,7 +958,8 @@ div.zadani_azad_termin { top: 0; } .predchozi_obrazek:hover{ - background-image: url("/static/galerie/prvky/predchozi.png"); + background-image: url("/static/galerie/prvky/predchozi.svg"); + filter: drop-shadow(0px 5px 5px rgba(0, 0, 0, 0.4)); background-position: left center; background-repeat: no-repeat; } @@ -486,7 +972,8 @@ div.zadani_azad_termin { top: 0; } .dalsi_obrazek:hover{ - background-image: url("/static/galerie/prvky/dalsi.png"); + background-image: url("/static/galerie/prvky/dalsi.svg"); + filter: drop-shadow(0px 5px 5px rgba(0, 0, 0, 0.4)); background-position: right center; background-repeat: no-repeat; } @@ -515,32 +1002,24 @@ div.zadani_azad_termin { } /* titulní obrázek hlavní galerie soustředění */ -.titulni_obrazek { - border: 1px solid black; -} .galerie_nahledy{ /*margin: 1em 0;*/ - margin: 0 auto 30px auto; + margin: auto; + padding: 10px; text-align: center; overflow: auto; } +.galerie_nahledy img { + margin: 10px; +} + .galerie_nahledy div.navigace { display: inline-block; - width: 150px; } -/*.galerie_nahledy img{*/ -/*margin: 0 10px 0 10px;*/ -/*}*/ - -/*.galerie_nahledy a{*/ -/*height: 100%;*/ -/*width: 100%;*/ -/*}*/ - -.galerie_nahled { /* frame */ +.galerie_nahled, .podgalerie_nahled { /* frame */ display: block; position: relative; float: left; @@ -548,19 +1027,19 @@ div.zadani_azad_termin { height: 200px; text-align: center; border: solid; - border-width: 2px; - border-radius: 5px; - /*border-color: #ffa500;*/ - border-color: #ffd546; - /*background-color: #ffb52d;*/ - background-color: white; + border-width: 1px; + border-radius: 4px; + border-color: #f9d59e; + background-color: #fffbf6; white-space: nowrap; - margin: 10px 20px 10px 0px; + margin: 10px; + font-weight: bold; } -.galerie_nahled:hover { - background-color: #ffd546; - border-color: #ffa500; +.galerie_nahled:hover, .podgalerie_nahled:hover { + background-color: #f9d59e; + filter: drop-shadow(0px 5px 5px rgba(0, 0, 0, 0.4)); + color: #6f2509; } .vystredeno{ /* helper */ @@ -573,12 +1052,6 @@ div.zadani_azad_termin { vertical-align: middle; max-height: 180px; max-width: 180px; - /*border: 1px solid white;*/ - -} - -.galerie_nahled img, .podgalerie_nahled img { - border-radius: 2px; } .galerie_nahled div { @@ -588,30 +1061,6 @@ div.zadani_azad_termin { text-align: center; } - -.podgalerie_nahled { - display: block; - position: relative; - float: left; - width: 200px; - height: 200px; - text-align: center; - border: solid; - border-width: 2px; - border-radius: 5px; - border-color: #ffa500; - /*border-color: #ffd546;*/ - background-color: #ffd546; - /*background-color: white;*/ - white-space: nowrap; - margin: 10px 20px 10px 0px; - font-weight: bold; -} - -.podgalerie_nahled:hover { - background-color: #ffa500; -} - .podgalerie_nahled img { margin-top: 20px; margin-bottom: 15px; @@ -627,10 +1076,10 @@ div.zadani_azad_termin { /* plus a minus tlacitka */ .mam-org-only-galerie { - background: #fff0d7; - padding: 10px; - margin: 10px 10px 10px -20px; - border: orange 2px dashed; + background: #eee4ec; + padding: 10px; + margin: 10px 10px 10px -20px; + border: #333 2px dashed; float: left; } @@ -638,8 +1087,8 @@ div.zadani_azad_termin { padding: 3px 5px; margin: 5px; border-radius: 20px; - background-color: lightblue; - color: black; + background-color: #6f2509;; + color: #fffbf6; float: left; } @@ -659,42 +1108,73 @@ div.zadani_azad_termin { } -/* titulni stranka */ +/**/ -.zjistit_vic{ - text-align: center; +ul.form { + list-style-type: none; + padding-left: 0px; } - -.graf{ - float: left; +label.field-label { + font-weight: normal; +} +label.field-required { + font-weight: bold; +} +.field-error { + font-size: 14px; + color: red; +} +ul.form li{ + margin-bottom: 3px; +} +p.gdpr { + font-size: 6pt; + margin-bottom: .66em; } +div.gdpr { + font-size: 6pt; +} + +/* Jak řešit */ -.novinky{ - float: right; - max-width: 42%; +.jakresit img { + width: 33%; + padding: 10px; + filter: none; } -.novinka_obrazek img { - margin-bottom: 15px; +@media(max-width: 860px) { + .jakresit img { + margin: auto; + display: grid; + width: 100%; + max-width: 360px; + } } -div.novinka_obrazek { - width: 100%; +/* tabulka odevzdaných a došlých řešení */ +.dosla_reseni tr th, .dosla_reseni tr td { + padding: 1px 10px 1px 10px; + border-collapse: collapse; } -div.org-text { - font-style: italic; +.dosla_reseni tr:nth-child(even) { + background: rgba(238, 238, 238, 255); } -div.nahledy_cisel { - float: right; - height: 297px; - width: 420px; - position: relative; - margin-right: 10%; - margin-bottom: 50px; + +.odevzdana_reseni tr th, .odevzdana_reseni tr td { + border: 1px solid black; + padding: 1px 10px 1px 10px; + border-collapse: collapse; + text-align: center; } -div.nahledy_cisel div, div.nahledy_cisel img { - position: absolute; +.odevzdana_reseni tr td#problem { + text-align: left; } + +/* registrace */ +label[for=id_skola] { + font-weight: bold; +} \ No newline at end of file diff --git a/mamweb/static/favicon.ico b/mamweb/static/favicon.ico deleted file mode 100644 index af06950a..00000000 Binary files a/mamweb/static/favicon.ico and /dev/null differ diff --git a/mamweb/static/fonts/OpenSans/Apache License.txt b/mamweb/static/fonts/OpenSans/Apache License.txt new file mode 100644 index 00000000..989e2c59 --- /dev/null +++ b/mamweb/static/fonts/OpenSans/Apache License.txt @@ -0,0 +1,201 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/mamweb/static/fonts/OpenSans/OpenSans-Bold.ttf b/mamweb/static/fonts/OpenSans/OpenSans-Bold.ttf new file mode 100644 index 00000000..fd79d43b Binary files /dev/null and b/mamweb/static/fonts/OpenSans/OpenSans-Bold.ttf differ diff --git a/mamweb/static/fonts/OpenSans/OpenSans-BoldItalic.ttf b/mamweb/static/fonts/OpenSans/OpenSans-BoldItalic.ttf new file mode 100644 index 00000000..9bc80095 Binary files /dev/null and b/mamweb/static/fonts/OpenSans/OpenSans-BoldItalic.ttf differ diff --git a/mamweb/static/fonts/OpenSans/OpenSans-ExtraBold.ttf b/mamweb/static/fonts/OpenSans/OpenSans-ExtraBold.ttf new file mode 100644 index 00000000..21f6f84a Binary files /dev/null and b/mamweb/static/fonts/OpenSans/OpenSans-ExtraBold.ttf differ diff --git a/mamweb/static/fonts/OpenSans/OpenSans-ExtraBoldItalic.ttf b/mamweb/static/fonts/OpenSans/OpenSans-ExtraBoldItalic.ttf new file mode 100644 index 00000000..31cb6883 Binary files /dev/null and b/mamweb/static/fonts/OpenSans/OpenSans-ExtraBoldItalic.ttf differ diff --git a/mamweb/static/fonts/OpenSans/OpenSans-Italic.ttf b/mamweb/static/fonts/OpenSans/OpenSans-Italic.ttf new file mode 100644 index 00000000..c90da48f Binary files /dev/null and b/mamweb/static/fonts/OpenSans/OpenSans-Italic.ttf differ diff --git a/mamweb/static/fonts/OpenSans/OpenSans-Light.ttf b/mamweb/static/fonts/OpenSans/OpenSans-Light.ttf new file mode 100644 index 00000000..0d381897 Binary files /dev/null and b/mamweb/static/fonts/OpenSans/OpenSans-Light.ttf differ diff --git a/mamweb/static/fonts/OpenSans/OpenSans-LightItalic.ttf b/mamweb/static/fonts/OpenSans/OpenSans-LightItalic.ttf new file mode 100644 index 00000000..68299c4b Binary files /dev/null and b/mamweb/static/fonts/OpenSans/OpenSans-LightItalic.ttf differ diff --git a/mamweb/static/fonts/OpenSans/OpenSans-Regular.ttf b/mamweb/static/fonts/OpenSans/OpenSans-Regular.ttf new file mode 100644 index 00000000..db433349 Binary files /dev/null and b/mamweb/static/fonts/OpenSans/OpenSans-Regular.ttf differ diff --git a/mamweb/static/fonts/OpenSans/OpenSans-Semibold.ttf b/mamweb/static/fonts/OpenSans/OpenSans-Semibold.ttf new file mode 100644 index 00000000..1a7679e3 Binary files /dev/null and b/mamweb/static/fonts/OpenSans/OpenSans-Semibold.ttf differ diff --git a/mamweb/static/fonts/OpenSans/OpenSans-SemiboldItalic.ttf b/mamweb/static/fonts/OpenSans/OpenSans-SemiboldItalic.ttf new file mode 100644 index 00000000..59b6d16b Binary files /dev/null and b/mamweb/static/fonts/OpenSans/OpenSans-SemiboldItalic.ttf differ diff --git a/mamweb/static/images/MATFYZ_MM_barevne.svg b/mamweb/static/images/MATFYZ_MM_barevne.svg new file mode 100644 index 00000000..a718677f --- /dev/null +++ b/mamweb/static/images/MATFYZ_MM_barevne.svg @@ -0,0 +1,120 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/mamweb/static/images/MSMT_logo_bez_textu_black.eps b/mamweb/static/images/MSMT_logo_bez_textu_black.eps new file mode 100644 index 00000000..f4bbac51 Binary files /dev/null and b/mamweb/static/images/MSMT_logo_bez_textu_black.eps differ diff --git a/mamweb/static/images/footer-bg-bottom.png b/mamweb/static/images/footer-bg-bottom.png deleted file mode 100644 index 95be7d8f..00000000 Binary files a/mamweb/static/images/footer-bg-bottom.png and /dev/null differ diff --git a/mamweb/static/images/footer-bg-top.png b/mamweb/static/images/footer-bg-top.png deleted file mode 100644 index 89ebce5e..00000000 Binary files a/mamweb/static/images/footer-bg-top.png and /dev/null differ diff --git a/mamweb/static/images/graf/adrenalinove.jpeg b/mamweb/static/images/graf/adrenalinove.jpeg new file mode 100644 index 00000000..e90ee50d Binary files /dev/null and b/mamweb/static/images/graf/adrenalinove.jpeg differ diff --git a/mamweb/static/images/graf/behaci.jpeg b/mamweb/static/images/graf/behaci.jpeg new file mode 100644 index 00000000..c9930c18 Binary files /dev/null and b/mamweb/static/images/graf/behaci.jpeg differ diff --git a/mamweb/static/images/graf/ceny.jpeg b/mamweb/static/images/graf/ceny.jpeg new file mode 100644 index 00000000..fb6fb475 Binary files /dev/null and b/mamweb/static/images/graf/ceny.jpeg differ diff --git a/mamweb/static/images/graf/deskovky.jpeg b/mamweb/static/images/graf/deskovky.jpeg new file mode 100644 index 00000000..d55acdbc Binary files /dev/null and b/mamweb/static/images/graf/deskovky.jpeg differ diff --git a/mamweb/static/images/graf/dort.jpeg b/mamweb/static/images/graf/dort.jpeg new file mode 100644 index 00000000..21623e35 Binary files /dev/null and b/mamweb/static/images/graf/dort.jpeg differ diff --git a/mamweb/static/images/graf/fyzika.jpg b/mamweb/static/images/graf/fyzika.jpg new file mode 100644 index 00000000..dc80ab70 Binary files /dev/null and b/mamweb/static/images/graf/fyzika.jpg differ diff --git a/mamweb/static/images/graf/hry.jpeg b/mamweb/static/images/graf/hry.jpeg new file mode 100644 index 00000000..9103a3eb Binary files /dev/null and b/mamweb/static/images/graf/hry.jpeg differ diff --git a/mamweb/static/images/graf/informatika.jpg b/mamweb/static/images/graf/informatika.jpg new file mode 100644 index 00000000..43fb342e Binary files /dev/null and b/mamweb/static/images/graf/informatika.jpg differ diff --git a/mamweb/static/images/graf/jidlo.jpeg b/mamweb/static/images/graf/jidlo.jpeg new file mode 100644 index 00000000..98c08463 Binary files /dev/null and b/mamweb/static/images/graf/jidlo.jpeg differ diff --git a/mamweb/static/images/graf/konfery.jpeg b/mamweb/static/images/graf/konfery.jpeg new file mode 100644 index 00000000..eebe44e9 Binary files /dev/null and b/mamweb/static/images/graf/konfery.jpeg differ diff --git a/mamweb/static/images/graf/legenda.jpeg b/mamweb/static/images/graf/legenda.jpeg new file mode 100644 index 00000000..6824b026 Binary files /dev/null and b/mamweb/static/images/graf/legenda.jpeg differ diff --git a/mamweb/static/images/graf/matematika.jpg b/mamweb/static/images/graf/matematika.jpg new file mode 100644 index 00000000..f27ab16f Binary files /dev/null and b/mamweb/static/images/graf/matematika.jpg differ diff --git a/mamweb/static/images/graf/prednasky.jpeg b/mamweb/static/images/graf/prednasky.jpeg new file mode 100644 index 00000000..778d6cd5 Binary files /dev/null and b/mamweb/static/images/graf/prednasky.jpeg differ diff --git a/mamweb/static/images/graf/strategicke.jpeg b/mamweb/static/images/graf/strategicke.jpeg new file mode 100644 index 00000000..88ec8f4b Binary files /dev/null and b/mamweb/static/images/graf/strategicke.jpeg differ diff --git a/mamweb/static/images/graf/vylet.jpeg b/mamweb/static/images/graf/vylet.jpeg new file mode 100644 index 00000000..f7a0eea9 Binary files /dev/null and b/mamweb/static/images/graf/vylet.jpeg differ diff --git a/mamweb/static/images/graph.png b/mamweb/static/images/graph.png deleted file mode 100644 index 41aaafff..00000000 Binary files a/mamweb/static/images/graph.png and /dev/null differ diff --git a/mamweb/static/images/header-bg-archiv-NOC.jpg b/mamweb/static/images/header-bg-archiv-NOC.jpg deleted file mode 100644 index d3732d92..00000000 Binary files a/mamweb/static/images/header-bg-archiv-NOC.jpg and /dev/null differ diff --git a/mamweb/static/images/header-bg-archiv.jpg b/mamweb/static/images/header-bg-archiv.jpg deleted file mode 100644 index 6f00a321..00000000 Binary files a/mamweb/static/images/header-bg-archiv.jpg and /dev/null differ diff --git a/mamweb/static/images/header-bg-clanek-NOC.jpg b/mamweb/static/images/header-bg-clanek-NOC.jpg deleted file mode 100644 index 6c21cf02..00000000 Binary files a/mamweb/static/images/header-bg-clanek-NOC.jpg and /dev/null differ diff --git a/mamweb/static/images/header-bg-clanek.jpg b/mamweb/static/images/header-bg-clanek.jpg deleted file mode 100644 index 29077929..00000000 Binary files a/mamweb/static/images/header-bg-clanek.jpg and /dev/null differ diff --git a/mamweb/static/images/header-bg-odevzdat-NOC.jpg b/mamweb/static/images/header-bg-odevzdat-NOC.jpg deleted file mode 100644 index 3697993b..00000000 Binary files a/mamweb/static/images/header-bg-odevzdat-NOC.jpg and /dev/null differ diff --git a/mamweb/static/images/header-bg-soustredeni-NOC.jpg b/mamweb/static/images/header-bg-soustredeni-NOC.jpg deleted file mode 100644 index f950069c..00000000 Binary files a/mamweb/static/images/header-bg-soustredeni-NOC.jpg and /dev/null differ diff --git a/mamweb/static/images/header-bg-soustredeni.jpg b/mamweb/static/images/header-bg-soustredeni.jpg deleted file mode 100644 index a4f4121f..00000000 Binary files a/mamweb/static/images/header-bg-soustredeni.jpg and /dev/null differ diff --git a/mamweb/static/images/header-bg-uvod-NOC.jpg b/mamweb/static/images/header-bg-uvod-NOC.jpg deleted file mode 100644 index 6963bf83..00000000 Binary files a/mamweb/static/images/header-bg-uvod-NOC.jpg and /dev/null differ diff --git a/mamweb/static/images/header-bg-uvod.jpg b/mamweb/static/images/header-bg-uvod.jpg deleted file mode 100644 index 0236ce5e..00000000 Binary files a/mamweb/static/images/header-bg-uvod.jpg and /dev/null differ diff --git a/mamweb/static/images/header-bg-zadani-NOC.jpg b/mamweb/static/images/header-bg-zadani-NOC.jpg deleted file mode 100644 index fa2c27b3..00000000 Binary files a/mamweb/static/images/header-bg-zadani-NOC.jpg and /dev/null differ diff --git a/mamweb/static/images/header-bg-zadani.jpg b/mamweb/static/images/header-bg-zadani.jpg deleted file mode 100644 index e06a3d02..00000000 Binary files a/mamweb/static/images/header-bg-zadani.jpg and /dev/null differ diff --git a/mamweb/static/images/header-bg.jpg b/mamweb/static/images/header-bg.jpg deleted file mode 100644 index b6e22870..00000000 Binary files a/mamweb/static/images/header-bg.jpg and /dev/null differ diff --git a/mamweb/static/images/header/baliky.jpg b/mamweb/static/images/header/baliky.jpg new file mode 100644 index 00000000..a501fffd Binary files /dev/null and b/mamweb/static/images/header/baliky.jpg differ diff --git a/mamweb/static/images/header/beh.jpg b/mamweb/static/images/header/beh.jpg new file mode 100644 index 00000000..d40cfccf Binary files /dev/null and b/mamweb/static/images/header/beh.jpg differ diff --git a/mamweb/static/images/header/kryptografie.jpg b/mamweb/static/images/header/kryptografie.jpg new file mode 100644 index 00000000..446cf4e9 Binary files /dev/null and b/mamweb/static/images/header/kryptografie.jpg differ diff --git a/mamweb/static/images/header/mam_cernobile.jpg b/mamweb/static/images/header/mam_cernobile.jpg new file mode 100644 index 00000000..701a26aa Binary files /dev/null and b/mamweb/static/images/header/mam_cernobile.jpg differ diff --git a/mamweb/static/images/header/noc.jpg b/mamweb/static/images/header/noc.jpg new file mode 100644 index 00000000..113331c3 Binary files /dev/null and b/mamweb/static/images/header/noc.jpg differ diff --git a/mamweb/static/images/header/ohen.jpg b/mamweb/static/images/header/ohen.jpg new file mode 100644 index 00000000..e5ba844e Binary files /dev/null and b/mamweb/static/images/header/ohen.jpg differ diff --git a/mamweb/static/images/header/snih.jpg b/mamweb/static/images/header/snih.jpg new file mode 100644 index 00000000..b2e0db12 Binary files /dev/null and b/mamweb/static/images/header/snih.jpg differ diff --git a/mamweb/static/images/header/spolecna.jpg b/mamweb/static/images/header/spolecna.jpg new file mode 100644 index 00000000..11cfbb80 Binary files /dev/null and b/mamweb/static/images/header/spolecna.jpg differ diff --git a/mamweb/static/images/header/stiny.jpg b/mamweb/static/images/header/stiny.jpg new file mode 100644 index 00000000..fe763521 Binary files /dev/null and b/mamweb/static/images/header/stiny.jpg differ diff --git a/mamweb/static/images/header/vikendovka.jpg b/mamweb/static/images/header/vikendovka.jpg new file mode 100644 index 00000000..2f53cbef Binary files /dev/null and b/mamweb/static/images/header/vikendovka.jpg differ diff --git a/mamweb/static/images/header/vylet.jpg b/mamweb/static/images/header/vylet.jpg new file mode 100644 index 00000000..da39a72a Binary files /dev/null and b/mamweb/static/images/header/vylet.jpg differ diff --git a/mamweb/static/images/jakresit_1.svg b/mamweb/static/images/jakresit_1.svg new file mode 100644 index 00000000..36a6b7c7 --- /dev/null +++ b/mamweb/static/images/jakresit_1.svg @@ -0,0 +1,26847 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mamweb/static/images/jakresit_2.svg b/mamweb/static/images/jakresit_2.svg new file mode 100644 index 00000000..93fa9f2e --- /dev/null +++ b/mamweb/static/images/jakresit_2.svg @@ -0,0 +1,26847 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mamweb/static/images/jakresit_3.svg b/mamweb/static/images/jakresit_3.svg new file mode 100644 index 00000000..391ebc7c --- /dev/null +++ b/mamweb/static/images/jakresit_3.svg @@ -0,0 +1,26373 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Zaregistruj se a nahraj řešení do odevzdávátka. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mamweb/static/images/logo-jcmf.png b/mamweb/static/images/logo-jcmf.png deleted file mode 100644 index 9dec6f4c..00000000 Binary files a/mamweb/static/images/logo-jcmf.png and /dev/null differ diff --git a/mamweb/static/images/logo-mff.png b/mamweb/static/images/logo-mff.png deleted file mode 100644 index 9c9a98e4..00000000 Binary files a/mamweb/static/images/logo-mff.png and /dev/null differ diff --git a/mamweb/static/images/logo-mobile.svg b/mamweb/static/images/logo-mobile.svg new file mode 100644 index 00000000..a22193db --- /dev/null +++ b/mamweb/static/images/logo-mobile.svg @@ -0,0 +1,240 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/mamweb/static/images/logo.png b/mamweb/static/images/logo.png deleted file mode 100644 index 28b388bf..00000000 Binary files a/mamweb/static/images/logo.png and /dev/null differ diff --git a/mamweb/static/images/logo.svg b/mamweb/static/images/logo.svg new file mode 100644 index 00000000..a67d4be5 --- /dev/null +++ b/mamweb/static/images/logo.svg @@ -0,0 +1,208 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/mamweb/static/images/logo_1.svg b/mamweb/static/images/logo_1.svg new file mode 100644 index 00000000..181f43c5 --- /dev/null +++ b/mamweb/static/images/logo_1.svg @@ -0,0 +1,208 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/mamweb/static/images/logo_2.svg b/mamweb/static/images/logo_2.svg new file mode 100644 index 00000000..263d974a --- /dev/null +++ b/mamweb/static/images/logo_2.svg @@ -0,0 +1,208 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/mamweb/static/images/logo_3.svg b/mamweb/static/images/logo_3.svg new file mode 100644 index 00000000..d79ec4d6 --- /dev/null +++ b/mamweb/static/images/logo_3.svg @@ -0,0 +1,208 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/mamweb/static/images/logo_4.svg b/mamweb/static/images/logo_4.svg new file mode 100644 index 00000000..4b8c1358 --- /dev/null +++ b/mamweb/static/images/logo_4.svg @@ -0,0 +1,208 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/mamweb/static/images/logo_5.svg b/mamweb/static/images/logo_5.svg new file mode 100644 index 00000000..6013f2ef --- /dev/null +++ b/mamweb/static/images/logo_5.svg @@ -0,0 +1,208 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/mamweb/static/images/logo_6.svg b/mamweb/static/images/logo_6.svg new file mode 100644 index 00000000..dc7b3178 --- /dev/null +++ b/mamweb/static/images/logo_6.svg @@ -0,0 +1,208 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/mamweb/static/images/logojcmf.png b/mamweb/static/images/logojcmf.png new file mode 100644 index 00000000..b100d752 Binary files /dev/null and b/mamweb/static/images/logojcmf.png differ diff --git a/mamweb/static/images/matfyz-logo.png b/mamweb/static/images/matfyz-logo.png new file mode 100644 index 00000000..193d24f0 Binary files /dev/null and b/mamweb/static/images/matfyz-logo.png differ diff --git a/mamweb/static/images/menu-bg-selected.png b/mamweb/static/images/menu-bg-selected.png deleted file mode 100644 index 91a2009a..00000000 Binary files a/mamweb/static/images/menu-bg-selected.png and /dev/null differ diff --git a/mamweb/static/images/menu-bg.png b/mamweb/static/images/menu-bg.png deleted file mode 100644 index 9088147d..00000000 Binary files a/mamweb/static/images/menu-bg.png and /dev/null differ diff --git a/mamweb/static/images/mozaika-footer.svg b/mamweb/static/images/mozaika-footer.svg new file mode 100644 index 00000000..4e426f0f --- /dev/null +++ b/mamweb/static/images/mozaika-footer.svg @@ -0,0 +1,664 @@ + +image/svg+xml diff --git a/mamweb/static/images/submenu-bg-selected.png b/mamweb/static/images/submenu-bg-selected.png deleted file mode 100644 index 81d1c817..00000000 Binary files a/mamweb/static/images/submenu-bg-selected.png and /dev/null differ diff --git a/mamweb/static/images/submenu-bg.png b/mamweb/static/images/submenu-bg.png deleted file mode 100644 index 9db66aa4..00000000 Binary files a/mamweb/static/images/submenu-bg.png and /dev/null differ diff --git a/mamweb/static/js/jquery-3.4.1.js b/mamweb/static/js/jquery-3.4.1.js new file mode 100644 index 00000000..773ad95c --- /dev/null +++ b/mamweb/static/js/jquery-3.4.1.js @@ -0,0 +1,10598 @@ +/*! + * jQuery JavaScript Library v3.4.1 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2019-05-01T21:04Z + */ +( function( global, factory ) { + + "use strict"; + + if ( typeof module === "object" && typeof module.exports === "object" ) { + + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common +// enough that all such attempts are guarded in a try block. +"use strict"; + +var arr = []; + +var document = window.document; + +var getProto = Object.getPrototypeOf; + +var slice = arr.slice; + +var concat = arr.concat; + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var fnToString = hasOwn.toString; + +var ObjectFunctionString = fnToString.call( Object ); + +var support = {}; + +var isFunction = function isFunction( obj ) { + + // Support: Chrome <=57, Firefox <=52 + // In some browsers, typeof returns "function" for HTML elements + // (i.e., `typeof document.createElement( "object" ) === "function"`). + // We don't want to classify *any* DOM node as a function. + return typeof obj === "function" && typeof obj.nodeType !== "number"; + }; + + +var isWindow = function isWindow( obj ) { + return obj != null && obj === obj.window; + }; + + + + + var preservedScriptAttributes = { + type: true, + src: true, + nonce: true, + noModule: true + }; + + function DOMEval( code, node, doc ) { + doc = doc || document; + + var i, val, + script = doc.createElement( "script" ); + + script.text = code; + if ( node ) { + for ( i in preservedScriptAttributes ) { + + // Support: Firefox 64+, Edge 18+ + // Some browsers don't support the "nonce" property on scripts. + // On the other hand, just using `getAttribute` is not enough as + // the `nonce` attribute is reset to an empty string whenever it + // becomes browsing-context connected. + // See https://github.com/whatwg/html/issues/2369 + // See https://html.spec.whatwg.org/#nonce-attributes + // The `node.getAttribute` check was added for the sake of + // `jQuery.globalEval` so that it can fake a nonce-containing node + // via an object. + val = node[ i ] || node.getAttribute && node.getAttribute( i ); + if ( val ) { + script.setAttribute( i, val ); + } + } + } + doc.head.appendChild( script ).parentNode.removeChild( script ); + } + + +function toType( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; +} +/* global Symbol */ +// Defining this global in .eslintrc.json would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module + + + +var + version = "3.4.1", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android <=4.0 only + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + + // Return all the elements in a clean array + if ( num == null ) { + return slice.call( this ); + } + + // Return just the one element from the set + return num < 0 ? this[ num + this.length ] : this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + copy = options[ name ]; + + // Prevent Object.prototype pollution + // Prevent never-ending loop + if ( name === "__proto__" || target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = Array.isArray( copy ) ) ) ) { + src = target[ name ]; + + // Ensure proper type for the source value + if ( copyIsArray && !Array.isArray( src ) ) { + clone = []; + } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { + clone = {}; + } else { + clone = src; + } + copyIsArray = false; + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + // Evaluates a script in a global context + globalEval: function( code, options ) { + DOMEval( code, { nonce: options && options.nonce } ); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // Support: Android <=4.0 only + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), +function( i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +} ); + +function isArrayLike( obj ) { + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = toType( obj ); + + if ( isFunction( obj ) || isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.3.4 + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://js.foundation/ + * + * Date: 2019-04-08 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + nonnativeSelectorCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + rdescend = new RegExp( whitespace + "|>" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rhtml = /HTML$/i, + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + inDisabledFieldset = addCombinator( + function( elem ) { + return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; + }, + { dir: "parentNode", next: "legend" } + ); + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + + // ID selector + if ( (m = match[1]) ) { + + // Document context + if ( nodeType === 9 ) { + if ( (elem = context.getElementById( m )) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && (elem = newContext.getElementById( m )) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( (m = match[3]) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !nonnativeSelectorCache[ selector + " " ] && + (!rbuggyQSA || !rbuggyQSA.test( selector )) && + + // Support: IE 8 only + // Exclude object elements + (nodeType !== 1 || context.nodeName.toLowerCase() !== "object") ) { + + newSelector = selector; + newContext = context; + + // qSA considers elements outside a scoping root when evaluating child or + // descendant combinators, which is not what we want. + // In such cases, we work around the behavior by prefixing every selector in the + // list with an ID selector referencing the scope context. + // Thanks to Andrew Dupont for this technique. + if ( nodeType === 1 && rdescend.test( selector ) ) { + + // Capture the context ID, setting it first if necessary + if ( (nid = context.getAttribute( "id" )) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", (nid = expando) ); + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[i] = "#" + nid + " " + toSelector( groups[i] ); + } + newSelector = groups.join( "," ); + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + } + + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + nonnativeSelectorCache( selector, true ); + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement("fieldset"); + + try { + return !!fn( el ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ( "form" in elem ) { + + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if ( elem.parentNode && elem.disabled === false ) { + + // Option elements defer to a parent optgroup if present + if ( "label" in elem ) { + if ( "label" in elem.parentNode ) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + + // Support: IE 6 - 11 + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + /* jshint -W018 */ + elem.isDisabled !== !disabled && + inDisabledFieldset( elem ) === disabled; + } + + return elem.disabled === disabled; + + // Try to winnow out elements that can't be disabled before trusting the disabled property. + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't + // even exist on them, let alone have a boolean value. + } else if ( "label" in elem ) { + return elem.disabled === disabled; + } + + // Remaining elements are neither :enabled nor :disabled + return false; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + var namespace = elem.namespaceURI, + docElem = (elem.ownerDocument || elem).documentElement; + + // Support: IE <=8 + // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes + // https://bugs.jquery.com/ticket/4833 + return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9-11, Edge + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + if ( preferredDoc !== document && + (subWindow = document.defaultView) && subWindow.top !== subWindow ) { + + // Support: IE 11, Edge + if ( subWindow.addEventListener ) { + subWindow.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( subWindow.attachEvent ) { + subWindow.attachEvent( "onunload", unloadHandler ); + } + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert(function( el ) { + el.className = "i"; + return !el.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( el ) { + el.appendChild( document.createComment("") ); + return !el.getElementsByTagName("*").length; + }); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( el ) { + docElem.appendChild( el ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + }); + + // ID filter and find + if ( support.getById ) { + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var elem = context.getElementById( id ); + return elem ? [ elem ] : []; + } + }; + } else { + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + + // Support: IE 6 - 7 only + // getElementById is not reliable as a find shortcut + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var node, i, elems, + elem = context.getElementById( id ); + + if ( elem ) { + + // Verify the id attribute + node = elem.getAttributeNode("id"); + if ( node && node.value === id ) { + return [ elem ]; + } + + // Fall back on getElementsByName + elems = context.getElementsByName( id ); + i = 0; + while ( (elem = elems[i++]) ) { + node = elem.getAttributeNode("id"); + if ( node && node.value === id ) { + return [ elem ]; + } + } + } + + return []; + } + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( el ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild( el ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( el.querySelectorAll("[msallowcapture^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !el.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push("~="); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !el.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push(".#.+[+~]"); + } + }); + + assert(function( el ) { + el.innerHTML = "" + + ""; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement("input"); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( el.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( el.querySelectorAll(":enabled").length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild( el ).disabled = true; + if ( el.querySelectorAll(":disabled").length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( el ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( el, "*" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( el, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === document ? -1 : + b === document ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + if ( support.matchesSelector && documentIsHTML && + !nonnativeSelectorCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch (e) { + nonnativeSelectorCache( expr, true ); + } + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; +}; + +Sizzle.escape = function( sel ) { + return (sel + "").replace( rcssescape, fcssescape ); +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[6] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + // Use previously-cached element index if available + if ( useCache ) { + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + // Don't keep the element (issue #299) + input[0] = null; + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": createDisabledPseudo( false ), + "disabled": createDisabledPseudo( true ), + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? + argument + length : + argument > length ? + length : + argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + skip = combinator.next, + key = skip || dir, + checkNonElements = base && key === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + return false; + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); + + if ( skip && skip === elem.nodeName.toLowerCase() ) { + elem = elem[ dir ] || elem; + } else if ( (oldCache = uniqueCache[ key ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ key ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + return false; + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context === document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + if ( !context && elem.ownerDocument !== document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context || document, xml) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( (selector = compiled.selector || selector) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( el ) { + // Should return 1, but returns 4 (following) + return el.compareDocumentPosition( document.createElement("fieldset") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( el ) { + el.innerHTML = ""; + return el.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( el ) { + el.innerHTML = ""; + el.firstChild.setAttribute( "value", "" ); + return el.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( el ) { + return el.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); +} + +return Sizzle; + +})( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; + +// Deprecated +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; +jQuery.escapeSelector = Sizzle.escape; + + + + +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + +var rneedsContext = jQuery.expr.match.needsContext; + + + +function nodeName( elem, name ) { + + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + +}; +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); + + + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + return !!qualifier.call( elem, i, elem ) !== not; + } ); + } + + // Single element + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); + } + + // Arraylike of elements (jQuery, arguments, Array) + if ( typeof qualifier !== "string" ) { + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); + } + + // Filtered directly for both simple and complex selectors + return jQuery.filter( qualifier, elements, not ); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + if ( elems.length === 1 && elem.nodeType === 1 ) { + return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; + } + + return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); +}; + +jQuery.fn.extend( { + find: function( selector ) { + var i, ret, + len = this.length, + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + ret = this.pushStack( [] ); + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + return len > 1 ? jQuery.uniqueSort( ret ) : ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +} ); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + // Shortcut simple #id case for speed + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + if ( elem ) { + + // Inject the element directly into the jQuery object + this[ 0 ] = elem; + this.length = 1; + } + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( isFunction( selector ) ) { + return root.ready !== undefined ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend( { + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter( function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + targets = typeof selectors !== "string" && jQuery( selectors ); + + // Positional selectors never match, since there's no _selection_ context + if ( !rneedsContext.test( selectors ) ) { + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( targets ? + targets.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } +} ); + +function sibling( cur, dir ) { + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + if ( typeof elem.contentDocument !== "undefined" ) { + return elem.contentDocument; + } + + // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only + // Treat the template element as a regular one in browsers that + // don't support it. + if ( nodeName( elem, "template" ) ) { + elem = elem.content || elem; + } + + return jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +} ); +var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); + + + +// Convert String-formatted options into Object-formatted ones +function createOptions( options ) { + var object = {}; + jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists + memory, + + // Flag to know if list was already fired + fired, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = locked || options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && toType( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } + } + } ); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory && !firing ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +function Identity( v ) { + return v; +} +function Thrower( ex ) { + throw ex; +} + +function adoptValue( value, resolve, reject, noValue ) { + var method; + + try { + + // Check for promise aspect first to privilege synchronous behavior + if ( value && isFunction( ( method = value.promise ) ) ) { + method.call( value ).done( resolve ).fail( reject ); + + // Other thenables + } else if ( value && isFunction( ( method = value.then ) ) ) { + method.call( value, resolve, reject ); + + // Other non-thenables + } else { + + // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: + // * false: [ value ].slice( 0 ) => resolve( value ) + // * true: [ value ].slice( 1 ) => resolve() + resolve.apply( undefined, [ value ].slice( noValue ) ); + } + + // For Promises/A+, convert exceptions into rejections + // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in + // Deferred#then to conditionally suppress rejection. + } catch ( value ) { + + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + reject.apply( undefined, [ value ] ); + } +} + +jQuery.extend( { + + Deferred: function( func ) { + var tuples = [ + + // action, add listener, callbacks, + // ... .then handlers, argument index, [final state] + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ), 2 ], + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 0, "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 1, "rejected" ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + "catch": function( fn ) { + return promise.then( null, fn ); + }, + + // Keep pipe for back-compat + pipe: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + + // Map tuples (progress, done, fail) to arguments (done, fail, progress) + var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; + + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + // deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + then: function( onFulfilled, onRejected, onProgress ) { + var maxDepth = 0; + function resolve( depth, deferred, handler, special ) { + return function() { + var that = this, + args = arguments, + mightThrow = function() { + var returned, then; + + // Support: Promises/A+ section 2.3.3.3.3 + // https://promisesaplus.com/#point-59 + // Ignore double-resolution attempts + if ( depth < maxDepth ) { + return; + } + + returned = handler.apply( that, args ); + + // Support: Promises/A+ section 2.3.1 + // https://promisesaplus.com/#point-48 + if ( returned === deferred.promise() ) { + throw new TypeError( "Thenable self-resolution" ); + } + + // Support: Promises/A+ sections 2.3.3.1, 3.5 + // https://promisesaplus.com/#point-54 + // https://promisesaplus.com/#point-75 + // Retrieve `then` only once + then = returned && + + // Support: Promises/A+ section 2.3.4 + // https://promisesaplus.com/#point-64 + // Only check objects and functions for thenability + ( typeof returned === "object" || + typeof returned === "function" ) && + returned.then; + + // Handle a returned thenable + if ( isFunction( then ) ) { + + // Special processors (notify) just wait for resolution + if ( special ) { + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ) + ); + + // Normal processors (resolve) also hook into progress + } else { + + // ...and disregard older resolution values + maxDepth++; + + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ), + resolve( maxDepth, deferred, Identity, + deferred.notifyWith ) + ); + } + + // Handle all other returned values + } else { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Identity ) { + that = undefined; + args = [ returned ]; + } + + // Process the value(s) + // Default process is resolve + ( special || deferred.resolveWith )( that, args ); + } + }, + + // Only normal processors (resolve) catch and reject exceptions + process = special ? + mightThrow : + function() { + try { + mightThrow(); + } catch ( e ) { + + if ( jQuery.Deferred.exceptionHook ) { + jQuery.Deferred.exceptionHook( e, + process.stackTrace ); + } + + // Support: Promises/A+ section 2.3.3.3.4.1 + // https://promisesaplus.com/#point-61 + // Ignore post-resolution exceptions + if ( depth + 1 >= maxDepth ) { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Thrower ) { + that = undefined; + args = [ e ]; + } + + deferred.rejectWith( that, args ); + } + } + }; + + // Support: Promises/A+ section 2.3.3.3.1 + // https://promisesaplus.com/#point-57 + // Re-resolve promises immediately to dodge false rejection from + // subsequent errors + if ( depth ) { + process(); + } else { + + // Call an optional hook to record the stack, in case of exception + // since it's otherwise lost when execution goes async + if ( jQuery.Deferred.getStackHook ) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout( process ); + } + }; + } + + return jQuery.Deferred( function( newDefer ) { + + // progress_handlers.add( ... ) + tuples[ 0 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onProgress ) ? + onProgress : + Identity, + newDefer.notifyWith + ) + ); + + // fulfilled_handlers.add( ... ) + tuples[ 1 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onFulfilled ) ? + onFulfilled : + Identity + ) + ); + + // rejected_handlers.add( ... ) + tuples[ 2 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onRejected ) ? + onRejected : + Thrower + ) + ); + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 5 ]; + + // promise.progress = list.add + // promise.done = list.add + // promise.fail = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( + function() { + + // state = "resolved" (i.e., fulfilled) + // state = "rejected" + state = stateString; + }, + + // rejected_callbacks.disable + // fulfilled_callbacks.disable + tuples[ 3 - i ][ 2 ].disable, + + // rejected_handlers.disable + // fulfilled_handlers.disable + tuples[ 3 - i ][ 3 ].disable, + + // progress_callbacks.lock + tuples[ 0 ][ 2 ].lock, + + // progress_handlers.lock + tuples[ 0 ][ 3 ].lock + ); + } + + // progress_handlers.fire + // fulfilled_handlers.fire + // rejected_handlers.fire + list.add( tuple[ 3 ].fire ); + + // deferred.notify = function() { deferred.notifyWith(...) } + // deferred.resolve = function() { deferred.resolveWith(...) } + // deferred.reject = function() { deferred.rejectWith(...) } + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); + return this; + }; + + // deferred.notifyWith = list.fireWith + // deferred.resolveWith = list.fireWith + // deferred.rejectWith = list.fireWith + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( singleValue ) { + var + + // count of uncompleted subordinates + remaining = arguments.length, + + // count of unprocessed arguments + i = remaining, + + // subordinate fulfillment data + resolveContexts = Array( i ), + resolveValues = slice.call( arguments ), + + // the master Deferred + master = jQuery.Deferred(), + + // subordinate callback factory + updateFunc = function( i ) { + return function( value ) { + resolveContexts[ i ] = this; + resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( !( --remaining ) ) { + master.resolveWith( resolveContexts, resolveValues ); + } + }; + }; + + // Single- and empty arguments are adopted like Promise.resolve + if ( remaining <= 1 ) { + adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, + !remaining ); + + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if ( master.state() === "pending" || + isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + + return master.then(); + } + } + + // Multiple arguments are aggregated like Promise.all array elements + while ( i-- ) { + adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); + } + + return master.promise(); + } +} ); + + +// These usually indicate a programmer mistake during development, +// warn about them ASAP rather than swallowing them by default. +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + +jQuery.Deferred.exceptionHook = function( error, stack ) { + + // Support: IE 8 - 9 only + // Console exists when dev tools are open, which can happen at any time + if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { + window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); + } +}; + + + + +jQuery.readyException = function( error ) { + window.setTimeout( function() { + throw error; + } ); +}; + + + + +// The deferred used on DOM ready +var readyList = jQuery.Deferred(); + +jQuery.fn.ready = function( fn ) { + + readyList + .then( fn ) + + // Wrap jQuery.readyException in a function so that the lookup + // happens at the time of error handling instead of callback + // registration. + .catch( function( error ) { + jQuery.readyException( error ); + } ); + + return this; +}; + +jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + } +} ); + +jQuery.ready.then = readyList.then; + +// The ready event handler and self cleanup method +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); +} + +// Catch cases where $(document).ready() is called +// after the browser event has already occurred. +// Support: IE <=9 - 10 only +// Older IE sometimes signals "interactive" too soon +if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + +} else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); +} + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( toType( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + if ( chainable ) { + return elems; + } + + // Gets + if ( bulk ) { + return fn.call( elems ); + } + + return len ? fn( elems[ 0 ], key ) : emptyGet; +}; + + +// Matches dashed string for camelizing +var rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g; + +// Used by camelCase as callback to replace() +function fcamelCase( all, letter ) { + return letter.toUpperCase(); +} + +// Convert dashed to camelCase; used by the css and data modules +// Support: IE <=9 - 11, Edge 12 - 15 +// Microsoft forgot to hump their vendor prefix (#9572) +function camelCase( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); +} +var acceptData = function( owner ) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + + + +function Data() { + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; + +Data.prototype = { + + cache: function( owner ) { + + // Check if the owner object already has a cache + var value = owner[ this.expando ]; + + // If not, create one + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + // Always use camelCase key (gh-2257) + if ( typeof data === "string" ) { + cache[ camelCase( data ) ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ camelCase( prop ) ] = data[ prop ]; + } + } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : + + // Always use camelCase key (gh-2257) + owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; + }, + access: function( owner, key, value ) { + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { + + return this.get( owner, key ); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } + + if ( key !== undefined ) { + + // Support array or space separated string of keys + if ( Array.isArray( key ) ) { + + // If key is an array of keys... + // We always set camelCase keys, so remove that. + key = key.map( camelCase ); + } else { + key = camelCase( key ); + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + key = key in cache ? + [ key ] : + ( key.match( rnothtmlwhite ) || [] ); + } + + i = key.length; + + while ( i-- ) { + delete cache[ key[ i ] ]; + } + } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <=35 - 45 + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } +}; +var dataPriv = new Data(); + +var dataUser = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + +function getData( data ) { + if ( data === "true" ) { + return true; + } + + if ( data === "false" ) { + return false; + } + + if ( data === "null" ) { + return null; + } + + // Only convert to a number if it doesn't change the string + if ( data === +data + "" ) { + return +data; + } + + if ( rbrace.test( data ) ) { + return JSON.parse( data ); + } + + return data; +} + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = getData( data ); + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE 11 only + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + + // Attempt to get data from the cache + // The key will always be camelCased in Data + data = dataUser.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, key ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each( function() { + + // We always store the camelCased key + dataUser.set( this, key, value ); + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || Array.isArray( data ) ) { + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); + } +} ); + +jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var documentElement = document.documentElement; + + + + var isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ); + }, + composed = { composed: true }; + + // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only + // Check attachment across shadow DOM boundaries when possible (gh-3504) + // Support: iOS 10.0-10.2 only + // Early iOS 10 versions support `attachShadow` but not `getRootNode`, + // leading to errors. We need to check for `getRootNode`. + if ( documentElement.getRootNode ) { + isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ) || + elem.getRootNode( composed ) === elem.ownerDocument; + }; + } +var isHiddenWithinTree = function( elem, el ) { + + // isHiddenWithinTree might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + + // Inline style trumps all + return elem.style.display === "none" || + elem.style.display === "" && + + // Otherwise, check computed style + // Support: Firefox <=43 - 45 + // Disconnected elements can have computed display: none, so first confirm that elem is + // in the document. + isAttached( elem ) && + + jQuery.css( elem, "display" ) === "none"; + }; + +var swap = function( elem, options, callback, args ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, scale, + maxIterations = 20, + currentValue = tween ? + function() { + return tween.cur(); + } : + function() { + return jQuery.css( elem, prop, "" ); + }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = elem.nodeType && + ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Support: Firefox <=54 + // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) + initial = initial / 2; + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + while ( maxIterations-- ) { + + // Evaluate and update our best guess (doubling guesses that zero out). + // Finish if the scale equals or crosses 1 (making the old*new product non-positive). + jQuery.style( elem, prop, initialInUnit + unit ); + if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { + maxIterations = 0; + } + initialInUnit = initialInUnit / scale; + + } + + initialInUnit = initialInUnit * 2; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} + + +var defaultDisplayMap = {}; + +function getDefaultDisplay( elem ) { + var temp, + doc = elem.ownerDocument, + nodeName = elem.nodeName, + display = defaultDisplayMap[ nodeName ]; + + if ( display ) { + return display; + } + + temp = doc.body.appendChild( doc.createElement( nodeName ) ); + display = jQuery.css( temp, "display" ); + + temp.parentNode.removeChild( temp ); + + if ( display === "none" ) { + display = "block"; + } + defaultDisplayMap[ nodeName ] = display; + + return display; +} + +function showHide( elements, show ) { + var display, elem, + values = [], + index = 0, + length = elements.length; + + // Determine new display value for elements that need to change + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + display = elem.style.display; + if ( show ) { + + // Since we force visibility upon cascade-hidden elements, an immediate (and slow) + // check is required in this first loop unless we have a nonempty display value (either + // inline or about-to-be-restored) + if ( display === "none" ) { + values[ index ] = dataPriv.get( elem, "display" ) || null; + if ( !values[ index ] ) { + elem.style.display = ""; + } + } + if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { + values[ index ] = getDefaultDisplay( elem ); + } + } else { + if ( display !== "none" ) { + values[ index ] = "none"; + + // Remember what we're overwriting + dataPriv.set( elem, "display", display ); + } + } + } + + // Set the display of the elements in a second loop to avoid constant reflow + for ( index = 0; index < length; index++ ) { + if ( values[ index ] != null ) { + elements[ index ].style.display = values[ index ]; + } + } + + return elements; +} + +jQuery.fn.extend( { + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each( function() { + if ( isHiddenWithinTree( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + } ); + } +} ); +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); + +var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); + + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // Support: IE <=9 only + option: [ 1, "" ], + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting or other required elements. + thead: [ 1, "", "
    " ], + col: [ 2, "", "
    " ], + tr: [ 2, "", "
    " ], + td: [ 3, "", "
    " ], + + _default: [ 0, "", "" ] +}; + +// Support: IE <=9 only +wrapMap.optgroup = wrapMap.option; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + + +function getAll( context, tag ) { + + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret; + + if ( typeof context.getElementsByTagName !== "undefined" ) { + ret = context.getElementsByTagName( tag || "*" ); + + } else if ( typeof context.querySelectorAll !== "undefined" ) { + ret = context.querySelectorAll( tag || "*" ); + + } else { + ret = []; + } + + if ( tag === undefined || tag && nodeName( context, tag ) ) { + return jQuery.merge( [ context ], ret ); + } + + return ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, attached, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( toType( elem ) === "object" ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + attached = isAttached( elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( attached ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; +} )(); + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE <=9 - 11+ +// focus() and blur() are asynchronous, except when they are no-op. +// So expect focus to be synchronous when the element is already active, +// and blur to be synchronous when the element is not already active. +// (focus and blur are always synchronous in other supported browsers, +// this just defines when we can count on it). +function expectSync( elem, type ) { + return ( elem === safeActiveElement() ) === ( type === "focus" ); +} + +// Support: IE <=9 only +// Accessing document.activeElement can throw unexpectedly +// https://bugs.jquery.com/ticket/13393 +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if ( selector ) { + jQuery.find.matchesSelector( documentElement, selector ); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = {}; + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( nativeEvent ) { + + // Make a writable jQuery.Event from the native event object + var event = jQuery.event.fix( nativeEvent ); + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // If the event is namespaced, then each handler is only invoked if it is + // specially universal or its namespaces are a superset of the event's. + if ( !event.rnamespace || handleObj.namespace === false || + event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + if ( delegateCount && + + // Support: IE <=9 + // Black-hole SVG instance trees (trac-13180) + cur.nodeType && + + // Support: Firefox <=42 + // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) + // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click + // Support: IE 11 only + // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) + !( event.type === "click" && event.button >= 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { + matchedHandlers = []; + matchedSelectors = {}; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matchedSelectors[ sel ] === undefined ) { + matchedSelectors[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matchedSelectors[ sel ] ) { + matchedHandlers.push( handleObj ); + } + } + if ( matchedHandlers.length ) { + handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + cur = this; + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + addProp: function( name, hook ) { + Object.defineProperty( jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: isFunction( hook ) ? + function() { + if ( this.originalEvent ) { + return hook( this.originalEvent ); + } + } : + function() { + if ( this.originalEvent ) { + return this.originalEvent[ name ]; + } + }, + + set: function( value ) { + Object.defineProperty( this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + } ); + } + } ); + }, + + fix: function( originalEvent ) { + return originalEvent[ jQuery.expando ] ? + originalEvent : + new jQuery.Event( originalEvent ); + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + click: { + + // Utilize native event to ensure correct state for checkable inputs + setup: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Claim the first handler + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + // dataPriv.set( el, "click", ... ) + leverageNative( el, "click", returnTrue ); + } + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Force setup before triggering a click + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + leverageNative( el, "click" ); + } + + // Return non-false to allow normal event-path propagation + return true; + }, + + // For cross-browser consistency, suppress native .click() on links + // Also prevent it if we're currently inside a leveraged native-event stack + _default: function( event ) { + var target = event.target; + return rcheckableType.test( target.type ) && + target.click && nodeName( target, "input" ) && + dataPriv.get( target, "click" ) || + nodeName( target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + } +}; + +// Ensure the presence of an event listener that handles manually-triggered +// synthetic events by interrupting progress until reinvoked in response to +// *native* events that it fires directly, ensuring that state changes have +// already occurred before other listeners are invoked. +function leverageNative( el, type, expectSync ) { + + // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add + if ( !expectSync ) { + if ( dataPriv.get( el, type ) === undefined ) { + jQuery.event.add( el, type, returnTrue ); + } + return; + } + + // Register the controller as a special universal handler for all event namespaces + dataPriv.set( el, type, false ); + jQuery.event.add( el, type, { + namespace: false, + handler: function( event ) { + var notAsync, result, + saved = dataPriv.get( this, type ); + + if ( ( event.isTrigger & 1 ) && this[ type ] ) { + + // Interrupt processing of the outer synthetic .trigger()ed event + // Saved data should be false in such cases, but might be a leftover capture object + // from an async native handler (gh-4350) + if ( !saved.length ) { + + // Store arguments for use when handling the inner native event + // There will always be at least one argument (an event object), so this array + // will not be confused with a leftover capture object. + saved = slice.call( arguments ); + dataPriv.set( this, type, saved ); + + // Trigger the native event and capture its result + // Support: IE <=9 - 11+ + // focus() and blur() are asynchronous + notAsync = expectSync( this, type ); + this[ type ](); + result = dataPriv.get( this, type ); + if ( saved !== result || notAsync ) { + dataPriv.set( this, type, false ); + } else { + result = {}; + } + if ( saved !== result ) { + + // Cancel the outer synthetic event + event.stopImmediatePropagation(); + event.preventDefault(); + return result.value; + } + + // If this is an inner synthetic event for an event with a bubbling surrogate + // (focus or blur), assume that the surrogate already propagated from triggering the + // native event and prevent that from happening again here. + // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the + // bubbling surrogate propagates *after* the non-bubbling base), but that seems + // less bad than duplication. + } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { + event.stopPropagation(); + } + + // If this is a native event triggered above, everything is now in order + // Fire an inner synthetic event with the original arguments + } else if ( saved.length ) { + + // ...and capture the result + dataPriv.set( this, type, { + value: jQuery.event.trigger( + + // Support: IE <=9 - 11+ + // Extend with the prototype to reset the above stopImmediatePropagation() + jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), + saved.slice( 1 ), + this + ) + } ); + + // Abort handling of the native event + event.stopImmediatePropagation(); + } + } + } ); +} + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (#504, #13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && !this.isSimulated ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Includes all common event props including KeyEvent and MouseEvent specific props +jQuery.each( { + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + code: true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + + which: function( event ) { + var button = event.button; + + // Add which for key events + if ( event.which == null && rkeyEvent.test( event.type ) ) { + return event.charCode != null ? event.charCode : event.keyCode; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { + if ( button & 1 ) { + return 1; + } + + if ( button & 2 ) { + return 3; + } + + if ( button & 4 ) { + return 2; + } + + return 0; + } + + return event.which; + } +}, jQuery.event.addProp ); + +jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { + jQuery.event.special[ type ] = { + + // Utilize native event if possible so blur/focus sequence is correct + setup: function() { + + // Claim the first handler + // dataPriv.set( this, "focus", ... ) + // dataPriv.set( this, "blur", ... ) + leverageNative( this, type, expectSync ); + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function() { + + // Force setup before trigger + leverageNative( this, type ); + + // Return non-false to allow normal event-path propagation + return true; + }, + + delegateType: delegateType + }; +} ); + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +jQuery.fn.extend( { + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } +} ); + + +var + + /* eslint-disable max-len */ + + // See https://github.com/eslint/eslint/issues/3229 + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, + + /* eslint-enable */ + + // Support: IE <=10 - 11, Edge 12 - 13 only + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g; + +// Prefer a tbody over its parent table for containing new rows +function manipulationTarget( elem, content ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return jQuery( elem ).children( "tbody" )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { + elem.type = elem.type.slice( 5 ); + } else { + elem.removeAttribute( "type" ); + } + + return elem; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.access( src ); + pdataCur = dataPriv.set( dest, pdataOld ); + events = pdataOld.events; + + if ( events ) { + delete pdataCur.handle; + pdataCur.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + valueIsFunction = isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( valueIsFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( valueIsFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl && !node.noModule ) { + jQuery._evalUrl( node.src, { + nonce: node.nonce || node.getAttribute( "nonce" ) + } ); + } + } else { + DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && isAttached( node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html.replace( rxhtmlTag, "<$1>" ); + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = isAttached( elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + +var getStyles = function( elem ) { + + // Support: IE <=11 only, Firefox <=30 (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + + if ( !view || !view.opener ) { + view = window; + } + + return view.getComputedStyle( elem ); + }; + +var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); + + + +( function() { + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + + // This is a singleton, we need to execute it only once + if ( !div ) { + return; + } + + container.style.cssText = "position:absolute;left:-11111px;width:60px;" + + "margin-top:1px;padding:0;border:0"; + div.style.cssText = + "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + + "margin:auto;border:1px;padding:1px;" + + "width:60%;top:1%"; + documentElement.appendChild( container ).appendChild( div ); + + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; + + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; + + // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 + // Some styles come back with percentage values, even though they shouldn't + div.style.right = "60%"; + pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; + + // Support: IE 9 - 11 only + // Detect misreporting of content dimensions for box-sizing:border-box elements + boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; + + // Support: IE 9 only + // Detect overflow:scroll screwiness (gh-3699) + // Support: Chrome <=64 + // Don't get tricked when zoom affects offsetWidth (gh-4029) + div.style.position = "absolute"; + scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; + + documentElement.removeChild( container ); + + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } + + function roundPixelMeasures( measure ) { + return Math.round( parseFloat( measure ) ); + } + + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, + reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } + + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + jQuery.extend( support, { + boxSizingReliable: function() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelBoxStyles: function() { + computeStyleTests(); + return pixelBoxStylesVal; + }, + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; + }, + reliableMarginLeft: function() { + computeStyleTests(); + return reliableMarginLeftVal; + }, + scrollboxSize: function() { + computeStyleTests(); + return scrollboxSizeVal; + } + } ); +} )(); + + +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, #12537) + // .css('--customProperty) (#3144) + if ( computed ) { + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !isAttached( elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : + ret; +} + + +function addGetHookIf( conditionFn, hookFn ) { + + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { + + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return ( this.get = hookFn ).apply( this, arguments ); + } + }; +} + + +var cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style, + vendorProps = {}; + +// Return a vendor-prefixed property or undefined +function vendorPropName( name ) { + + // Check for vendor prefixed names + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in emptyStyle ) { + return name; + } + } +} + +// Return a potentially-mapped jQuery.cssProps or vendor prefixed property +function finalPropName( name ) { + var final = jQuery.cssProps[ name ] || vendorProps[ name ]; + + if ( final ) { + return final; + } + if ( name in emptyStyle ) { + return name; + } + return vendorProps[ name ] = vendorPropName( name ) || name; +} + + +var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rcustomProp = /^--/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }; + +function setPositiveNumber( elem, value, subtract ) { + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); + return matches ? + + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : + value; +} + +function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { + var i = dimension === "width" ? 1 : 0, + extra = 0, + delta = 0; + + // Adjustment may not be necessary + if ( box === ( isBorderBox ? "border" : "content" ) ) { + return 0; + } + + for ( ; i < 4; i += 2 ) { + + // Both box models exclude margin + if ( box === "margin" ) { + delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); + } + + // If we get here with a content-box, we're seeking "padding" or "border" or "margin" + if ( !isBorderBox ) { + + // Add padding + delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // For "border" or "margin", add border + if ( box !== "padding" ) { + delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + + // But still keep track of it otherwise + } else { + extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + + // If we get here with a border-box (content + padding + border), we're seeking "content" or + // "padding" or "margin" + } else { + + // For "content", subtract padding + if ( box === "content" ) { + delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // For "content" or "padding", subtract border + if ( box !== "margin" ) { + delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + // Account for positive content-box scroll gutter when requested by providing computedVal + if ( !isBorderBox && computedVal >= 0 ) { + + // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border + // Assuming integer scroll gutter, subtract the rest and round down + delta += Math.max( 0, Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + computedVal - + delta - + extra - + 0.5 + + // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter + // Use an explicit zero to avoid NaN (gh-3964) + ) ) || 0; + } + + return delta; +} + +function getWidthOrHeight( elem, dimension, extra ) { + + // Start with computed style + var styles = getStyles( elem ), + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). + // Fake content-box until we know it's needed to know the true value. + boxSizingNeeded = !support.boxSizingReliable() || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + valueIsBorderBox = isBorderBox, + + val = curCSS( elem, dimension, styles ), + offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); + + // Support: Firefox <=54 + // Return a confounding non-pixel value or feign ignorance, as appropriate. + if ( rnumnonpx.test( val ) ) { + if ( !extra ) { + return val; + } + val = "auto"; + } + + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) + // Support: IE 9-11 only + // Also use offsetWidth/offsetHeight for when box sizing is unreliable + // We use getClientRects() to check for hidden/disconnected. + // In those cases, the computed value can be trusted to be border-box + if ( ( !support.boxSizingReliable() && isBorderBox || + val === "auto" || + !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && + elem.getClientRects().length ) { + + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // Where available, offsetWidth/offsetHeight approximate border box dimensions. + // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the + // retrieved value as a content box dimension. + valueIsBorderBox = offsetProp in elem; + if ( valueIsBorderBox ) { + val = elem[ offsetProp ]; + } + } + + // Normalize "" and auto + val = parseFloat( val ) || 0; + + // Adjust for the element's box model + return ( val + + boxModelAdjustment( + elem, + dimension, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles, + + // Provide the current computed size to request scroll gutter calculation (gh-3589) + val + ) + ) + "px"; +} + +jQuery.extend( { + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "animationIterationCount": true, + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "gridArea": true, + "gridColumn": true, + "gridColumnEnd": true, + "gridColumnStart": true, + "gridRow": true, + "gridRowEnd": true, + "gridRowStart": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: {}, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ), + style = elem.style; + + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // Convert "+=" or "-=" to relative numbers (#7345) + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); + + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (#7116) + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add the unit (except for certain CSS properties) + // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append + // "px" to a few hardcoded values. + if ( type === "number" && !isCustomProp ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); + } + + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + + if ( isCustomProp ) { + style.setProperty( name, value ); + } else { + style[ name ] = value; + } + } + + } else { + + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { + + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ); + + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || isFinite( num ) ? num || 0 : val; + } + + return val; + } +} ); + +jQuery.each( [ "height", "width" ], function( i, dimension ) { + jQuery.cssHooks[ dimension ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, dimension, extra ); + } ) : + getWidthOrHeight( elem, dimension, extra ); + } + }, + + set: function( elem, value, extra ) { + var matches, + styles = getStyles( elem ), + + // Only read styles.position if the test has a chance to fail + // to avoid forcing a reflow. + scrollboxSizeBuggy = !support.scrollboxSize() && + styles.position === "absolute", + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) + boxSizingNeeded = scrollboxSizeBuggy || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + subtract = extra ? + boxModelAdjustment( + elem, + dimension, + extra, + isBorderBox, + styles + ) : + 0; + + // Account for unreliable border-box dimensions by comparing offset* to computed and + // faking a content-box to get border and padding (gh-3699) + if ( isBorderBox && scrollboxSizeBuggy ) { + subtract -= Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + parseFloat( styles[ dimension ] ) - + boxModelAdjustment( elem, dimension, "border", false, styles ) - + 0.5 + ); + } + + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { + + elem.style[ dimension ] = value; + value = jQuery.css( elem, dimension ); + } + + return setPositiveNumber( elem, value, subtract ); + } + }; +} ); + +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each( { + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split( " " ) : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( prefix !== "margin" ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +} ); + +jQuery.fn.extend( { + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( Array.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + } +} ); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { + return tween.elem[ tween.prop ]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); + + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.nodeType === 1 && ( + jQuery.cssHooks[ tween.prop ] || + tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 only +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + }, + _default: "swing" +}; + +jQuery.fx = Tween.prototype.init; + +// Back compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; + +function schedule() { + if ( inProgress ) { + if ( document.hidden === false && window.requestAnimationFrame ) { + window.requestAnimationFrame( schedule ); + } else { + window.setTimeout( schedule, jQuery.fx.interval ); + } + + jQuery.fx.tick(); + } +} + +// Animations created synchronously will run synchronously +function createFxNow() { + window.setTimeout( function() { + fxNow = undefined; + } ); + return ( fxNow = Date.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { + + // We're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree( elem ), + dataShow = dataPriv.get( elem, "fxshow" ); + + // Queue-skipping animations hijack the fx hooks + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always( function() { + + // Ensure the complete handler is called before this completes + anim.always( function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + } ); + } ); + } + + // Detect show/hide animations + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.test( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + + // Ignore all other no-op show/hide data + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + } + } + + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject( props ); + if ( !propTween && jQuery.isEmptyObject( orig ) ) { + return; + } + + // Restrict "overflow" and "display" styles during box animations + if ( isBox && elem.nodeType === 1 ) { + + // Support: IE <=9 - 11, Edge 12 - 15 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY and Edge just mirrors + // the overflowX value there. + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if ( restoreDisplay == null ) { + restoreDisplay = dataPriv.get( elem, "display" ); + } + display = jQuery.css( elem, "display" ); + if ( display === "none" ) { + if ( restoreDisplay ) { + display = restoreDisplay; + } else { + + // Get nonempty value(s) by temporarily forcing visibility + showHide( [ elem ], true ); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css( elem, "display" ); + showHide( [ elem ] ); + } + } + + // Animate inline elements as inline-block + if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { + if ( jQuery.css( elem, "float" ) === "none" ) { + + // Restore the original display value at the end of pure show/hide animations + if ( !propTween ) { + anim.done( function() { + style.display = restoreDisplay; + } ); + if ( restoreDisplay == null ) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always( function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + } ); + } + + // Implement show/hide animations + propTween = false; + for ( prop in orig ) { + + // General show/hide setup for this element animation + if ( !propTween ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); + } + + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if ( toggle ) { + dataShow.hidden = !hidden; + } + + // Show elements before animating them + if ( hidden ) { + showHide( [ elem ], true ); + } + + /* eslint-disable no-loop-func */ + + anim.done( function() { + + /* eslint-enable no-loop-func */ + + // The final step of a "hide" animation is actually hiding the element + if ( !hidden ) { + showHide( [ elem ] ); + } + dataPriv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + } ); + } + + // Per-property setup + propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = propTween.start; + if ( hidden ) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( Array.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always( function() { + + // Don't match elem in the :animated selector + delete tick.elem; + } ), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ] ); + + // If there's more to do, yield + if ( percent < 1 && length ) { + return remaining; + } + + // If this was an empty animation, synthesize a final progress notification + if ( !length ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + } + + // Resolve the animation and report its conclusion + deferred.resolveWith( elem, [ animation ] ); + return false; + }, + animation = deferred.promise( { + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + } ), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length; index++ ) { + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + if ( isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + result.stop.bind( result ); + } + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + // Attach callbacks from options + animation + .progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + } ) + ); + + return animation; +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] + }, + + tweener: function( props, callback ) { + if ( isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.match( rnothtmlwhite ); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length; index++ ) { + prop = props[ index ]; + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); + } + }, + + prefilters: [ defaultPrefilter ], + + prefilter: function( callback, prepend ) { + if ( prepend ) { + Animation.prefilters.unshift( callback ); + } else { + Animation.prefilters.push( callback ); + } + } +} ); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !isFunction( easing ) && easing + }; + + // Go to the end state if fx are off + if ( jQuery.fx.off ) { + opt.duration = 0; + + } else { + if ( typeof opt.duration !== "number" ) { + if ( opt.duration in jQuery.fx.speeds ) { + opt.duration = jQuery.fx.speeds[ opt.duration ]; + + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend( { + fadeTo: function( speed, to, easing, callback ) { + + // Show any hidden elements after setting opacity to 0 + return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() + + // Animate to the value specified + .end().animate( { opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || dataPriv.get( this, "finish" ) ) { + anim.stop( true ); + } + }; + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue && type !== false ) { + this.queue( type || "fx", [] ); + } + + return this.each( function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { + + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + } ); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each( function() { + var index, + data = dataPriv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; + } ); + } +} ); + +jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +} ); + +// Generate shortcuts for custom animations +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +} ); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = Date.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + + // Run the timer and safely remove it when done (allowing for external removal) + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + jQuery.fx.start(); +}; + +jQuery.fx.interval = 13; +jQuery.fx.start = function() { + if ( inProgress ) { + return; + } + + inProgress = true; + schedule(); +}; + +jQuery.fx.stop = function() { + inProgress = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = window.setTimeout( next, time ); + hooks.stop = function() { + window.clearTimeout( timeout ); + }; + } ); +}; + + +( function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); + + input.type = "checkbox"; + + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +} )(); + + +var boolHook, + attrHandle = jQuery.expr.attrHandle; + +jQuery.fn.extend( { + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each( function() { + jQuery.removeAttr( this, name ); + } ); + } +} ); + +jQuery.extend( { + attr: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + // Attribute hooks are determined by the lowercase version + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + hooks = jQuery.attrHooks[ name.toLowerCase() ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); + } + + if ( value !== undefined ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + } + + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + elem.setAttribute( name, value + "" ); + return value; + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + removeAttr: function( elem, value ) { + var name, + i = 0, + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match( rnothtmlwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( ( name = attrNames[ i++ ] ) ) { + elem.removeAttribute( name ); + } + } + } +} ); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; + +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = function( elem, name, isXML ) { + var ret, handle, + lowercaseName = name.toLowerCase(); + + if ( !isXML ) { + + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ lowercaseName ]; + attrHandle[ lowercaseName ] = ret; + ret = getter( elem, name, isXML ) != null ? + lowercaseName : + null; + attrHandle[ lowercaseName ] = handle; + } + return ret; + }; +} ); + + + + +var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend( { + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + return this.each( function() { + delete this[ jQuery.propFix[ name ] || name ]; + } ); + } +} ); + +jQuery.extend( { + prop: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + return ( elem[ name ] = value ); + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + return elem[ name ]; + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + + // Support: IE <=9 - 11 only + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + if ( tabindex ) { + return parseInt( tabindex, 10 ); + } + + if ( + rfocusable.test( elem.nodeName ) || + rclickable.test( elem.nodeName ) && + elem.href + ) { + return 0; + } + + return -1; + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + } +} ); + +// Support: IE <=11 only +// Accessing the selectedIndex property +// forces the browser to respect setting selected +// on the option +// The getter ensures a default option is selected +// when in an optgroup +// eslint rule "no-unused-expressions" is disabled for this code +// since it considers such accessions noop +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }; +} + +jQuery.each( [ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +} ); + + + + + // Strip and collapse whitespace according to HTML spec + // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace + function stripAndCollapse( value ) { + var tokens = value.match( rnothtmlwhite ) || []; + return tokens.join( " " ); + } + + +function getClass( elem ) { + return elem.getAttribute && elem.getAttribute( "class" ) || ""; +} + +function classesToArray( value ) { + if ( Array.isArray( value ) ) { + return value; + } + if ( typeof value === "string" ) { + return value.match( rnothtmlwhite ) || []; + } + return []; +} + +jQuery.fn.extend( { + addClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( !arguments.length ) { + return this.attr( "class", "" ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) > -1 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isValidValue = type === "string" || Array.isArray( value ); + + if ( typeof stateVal === "boolean" && isValidValue ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( isFunction( value ) ) { + return this.each( function( i ) { + jQuery( this ).toggleClass( + value.call( this, i, getClass( this ), stateVal ), + stateVal + ); + } ); + } + + return this.each( function() { + var className, i, self, classNames; + + if ( isValidValue ) { + + // Toggle individual class names + i = 0; + self = jQuery( this ); + classNames = classesToArray( value ); + + while ( ( className = classNames[ i++ ] ) ) { + + // Check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( value === undefined || type === "boolean" ) { + className = getClass( this ); + if ( className ) { + + // Store className if set + dataPriv.set( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || value === false ? + "" : + dataPriv.get( this, "__className__" ) || "" + ); + } + } + } ); + }, + + hasClass: function( selector ) { + var className, elem, + i = 0; + + className = " " + selector + " "; + while ( ( elem = this[ i++ ] ) ) { + if ( elem.nodeType === 1 && + ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { + return true; + } + } + + return false; + } +} ); + + + + +var rreturn = /\r/g; + +jQuery.fn.extend( { + val: function( value ) { + var hooks, ret, valueIsFunction, + elem = this[ 0 ]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || + jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && + "get" in hooks && + ( ret = hooks.get( elem, "value" ) ) !== undefined + ) { + return ret; + } + + ret = elem.value; + + // Handle most common string cases + if ( typeof ret === "string" ) { + return ret.replace( rreturn, "" ); + } + + // Handle cases where value is null/undef or number + return ret == null ? "" : ret; + } + + return; + } + + valueIsFunction = isFunction( value ); + + return this.each( function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( valueIsFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + + } else if ( typeof val === "number" ) { + val += ""; + + } else if ( Array.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + } ); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + } ); + } +} ); + +jQuery.extend( { + valHooks: { + option: { + get: function( elem ) { + + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + + // Support: IE <=10 - 11 only + // option.text throws exceptions (#14686, #14858) + // Strip and collapse whitespace + // https://html.spec.whatwg.org/#strip-and-collapse-whitespace + stripAndCollapse( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, i, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one", + values = one ? null : [], + max = one ? index + 1 : options.length; + + if ( index < 0 ) { + i = max; + + } else { + i = one ? index : 0; + } + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Support: IE <=9 only + // IE8-9 doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + + // Don't return options that are disabled or in a disabled optgroup + !option.disabled && + ( !option.parentNode.disabled || + !nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + /* eslint-disable no-cond-assign */ + + if ( option.selected = + jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 + ) { + optionSet = true; + } + + /* eslint-enable no-cond-assign */ + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + } +} ); + +// Radios and checkboxes getter/setter +jQuery.each( [ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( Array.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + return elem.getAttribute( "value" ) === null ? "on" : elem.value; + }; + } +} ); + + + + +// Return jQuery for attributes-only inclusion + + +support.focusin = "onfocusin" in window; + + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + stopPropagationCallback = function( e ) { + e.stopPropagation(); + }; + +jQuery.extend( jQuery.event, { + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = lastElement = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + lastElement = cur; + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] && + dataPriv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( ( !special._default || + special._default.apply( eventPath.pop(), data ) === false ) && + acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + + if ( event.isPropagationStopped() ) { + lastElement.addEventListener( type, stopPropagationCallback ); + } + + elem[ type ](); + + if ( event.isPropagationStopped() ) { + lastElement.removeEventListener( type, stopPropagationCallback ); + } + + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + } + ); + + jQuery.event.trigger( e, null, elem ); + } + +} ); + +jQuery.fn.extend( { + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +// Support: Firefox <=44 +// Firefox doesn't have focus(in | out) events +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 +// +// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 +// focus(in | out) events fire after focus & blur events, +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + var doc = this.ownerDocument || this, + attaches = dataPriv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this, + attaches = dataPriv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + dataPriv.remove( doc, fix ); + + } else { + dataPriv.access( doc, fix, attaches ); + } + } + }; + } ); +} +var location = window.location; + +var nonce = Date.now(); + +var rquery = ( /\?/ ); + + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE 9 - 11 only + // IE throws on parseFromString with invalid input. + try { + xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); + } catch ( e ) { + xml = undefined; + } + + if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; +}; + + +var + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( Array.isArray( obj ) ) { + + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + + // Item is non-scalar (array or object), encode its numeric index. + buildParams( + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", + v, + traditional, + add + ); + } + } ); + + } else if ( !traditional && toType( obj ) === "object" ) { + + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, valueOrFunction ) { + + // If value is a function, invoke it and use its return value + var value = isFunction( valueOrFunction ) ? + valueOrFunction() : + valueOrFunction; + + s[ s.length ] = encodeURIComponent( key ) + "=" + + encodeURIComponent( value == null ? "" : value ); + }; + + if ( a == null ) { + return ""; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + } ); + + } else { + + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ); +}; + +jQuery.fn.extend( { + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map( function() { + + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + } ) + .filter( function() { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + } ) + .map( function( i, elem ) { + var val = jQuery( this ).val(); + + if ( val == null ) { + return null; + } + + if ( Array.isArray( val ) ) { + return jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ); + } + + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ).get(); + } +} ); + + +var + r20 = /%20/g, + rhash = /#.*$/, + rantiCache = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat( "*" ), + + // Anchor tag for parsing the document origin + originAnchor = document.createElement( "a" ); + originAnchor.href = location.href; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; + + if ( isFunction( func ) ) { + + // For each dataType in the dataTypeExpression + while ( ( dataType = dataTypes[ i++ ] ) ) { + + // Prepend if requested + if ( dataType[ 0 ] === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); + + // Otherwise append + } else { + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && + !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + } ); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s.throws ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend( { + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: location.href, + type: "GET", + isLocal: rlocalProtocol.test( location.protocol ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": JSON.parse, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + + // URL without anti-cache param + cacheURL, + + // Response headers + responseHeadersString, + responseHeaders, + + // timeout handle + timeoutTimer, + + // Url cleanup var + urlAnchor, + + // Request state (becomes false upon send and true upon completion) + completed, + + // To know if global events are to be dispatched + fireGlobals, + + // Loop variable + i, + + // uncached part of the url + uncached, + + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + + // Callbacks context + callbackContext = s.context || s, + + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && + ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + + // Status-dependent callbacks + statusCode = s.statusCode || {}, + + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + + // Default abort message + strAbort = "canceled", + + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( completed ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[ 1 ].toLowerCase() + " " ] = + ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) + .concat( match[ 2 ] ); + } + } + match = responseHeaders[ key.toLowerCase() + " " ]; + } + return match == null ? null : match.join( ", " ); + }, + + // Raw string + getAllResponseHeaders: function() { + return completed ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( completed == null ) { + name = requestHeadersNames[ name.toLowerCase() ] = + requestHeadersNames[ name.toLowerCase() ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( completed == null ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( completed ) { + + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for ( code in map ) { + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ); + + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || location.href ) + "" ) + .replace( rprotocol, location.protocol + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; + + // A cross-domain request is in order when the origin doesn't match the current origin. + if ( s.crossDomain == null ) { + urlAnchor = document.createElement( "a" ); + + // Support: IE <=8 - 11, Edge 12 - 15 + // IE throws exception on accessing the href property if url is malformed, + // e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE <=8 - 11 only + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== + urlAnchor.protocol + "//" + urlAnchor.host; + } catch ( e ) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( completed ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + // Remove hash to simplify url manipulation + cacheURL = s.url.replace( rhash, "" ); + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // Remember the hash so we can put it back + uncached = s.url.slice( cacheURL.length ); + + // If data is available and should be processed, append data to url + if ( s.data && ( s.processData || typeof s.data === "string" ) ) { + cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; + + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add or update anti-cache param if needed + if ( s.cache === false ) { + cacheURL = cacheURL.replace( rantiCache, "$1" ); + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached; + } + + // Put hash and anti-cache on the URL that will be requested (gh-1732) + s.url = cacheURL + uncached; + + // Change '%20' to '+' if this is encoded form body content (gh-2658) + } else if ( s.data && s.processData && + ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { + s.data = s.data.replace( r20, "+" ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? + s.accepts[ s.dataTypes[ 0 ] ] + + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { + + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + completeDeferred.add( s.complete ); + jqXHR.done( s.success ); + jqXHR.fail( s.error ); + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + + // If request was aborted inside ajaxSend, stop there + if ( completed ) { + return jqXHR; + } + + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = window.setTimeout( function() { + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + completed = false; + transport.send( requestHeaders, done ); + } catch ( e ) { + + // Rethrow post-completion exceptions + if ( completed ) { + throw e; + } + + // Propagate others as results + done( -1, e ); + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Ignore repeat invocations + if ( completed ) { + return; + } + + completed = true; + + // Clear timeout if it exists + if ( timeoutTimer ) { + window.clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader( "Last-Modified" ); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader( "etag" ); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + + // Extract error from statusText and normalize for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +} ); + +jQuery.each( [ "get", "post" ], function( i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + + // Shift arguments if data argument was omitted + if ( isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + // The url can be an options object (which then must have .url) + return jQuery.ajax( jQuery.extend( { + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject( url ) && url ) ); + }; +} ); + + +jQuery._evalUrl = function( url, options ) { + return jQuery.ajax( { + url: url, + + // Make this explicit, since user can override this through ajaxSetup (#11264) + type: "GET", + dataType: "script", + cache: true, + async: false, + global: false, + + // Only evaluate the response if it is successful (gh-4126) + // dataFilter is not invoked for failure responses, so using it instead + // of the default converter is kludgy but it works. + converters: { + "text script": function() {} + }, + dataFilter: function( response ) { + jQuery.globalEval( response, options ); + } + } ); +}; + + +jQuery.fn.extend( { + wrapAll: function( html ) { + var wrap; + + if ( this[ 0 ] ) { + if ( isFunction( html ) ) { + html = html.call( this[ 0 ] ); + } + + // The elements to wrap the target around + wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + + if ( this[ 0 ].parentNode ) { + wrap.insertBefore( this[ 0 ] ); + } + + wrap.map( function() { + var elem = this; + + while ( elem.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + } ).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( isFunction( html ) ) { + return this.each( function( i ) { + jQuery( this ).wrapInner( html.call( this, i ) ); + } ); + } + + return this.each( function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + } ); + }, + + wrap: function( html ) { + var htmlIsFunction = isFunction( html ); + + return this.each( function( i ) { + jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); + } ); + }, + + unwrap: function( selector ) { + this.parent( selector ).not( "body" ).each( function() { + jQuery( this ).replaceWith( this.childNodes ); + } ); + return this; + } +} ); + + +jQuery.expr.pseudos.hidden = function( elem ) { + return !jQuery.expr.pseudos.visible( elem ); +}; +jQuery.expr.pseudos.visible = function( elem ) { + return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); +}; + + + + +jQuery.ajaxSettings.xhr = function() { + try { + return new window.XMLHttpRequest(); + } catch ( e ) {} +}; + +var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 + 0: 200, + + // Support: IE <=9 only + // #1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +support.ajax = xhrSupported = !!xhrSupported; + +jQuery.ajaxTransport( function( options ) { + var callback, errorCallback; + + // Cross domain only allowed if supported through XMLHttpRequest + if ( support.cors || xhrSupported && !options.crossDomain ) { + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + callback = errorCallback = xhr.onload = + xhr.onerror = xhr.onabort = xhr.ontimeout = + xhr.onreadystatechange = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + + // Support: IE <=9 only + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if ( typeof xhr.status !== "number" ) { + complete( 0, "error" ); + } else { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + + // Support: IE <=9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) !== "text" || + typeof xhr.responseText !== "string" ? + { binary: xhr.response } : + { text: xhr.responseText }, + xhr.getAllResponseHeaders() + ); + } + } + }; + }; + + // Listen to events + xhr.onload = callback(); + errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); + + // Support: IE 9 only + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if ( xhr.onabort !== undefined ) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function() { + + // Check readyState before timeout as it changes + if ( xhr.readyState === 4 ) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout( function() { + if ( callback ) { + errorCallback(); + } + } ); + } + }; + } + + // Create the abort callback + callback = callback( "abort" ); + + try { + + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { + + // #14683: Only rethrow if this hasn't been notified as an error yet + if ( callback ) { + throw e; + } + } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) +jQuery.ajaxPrefilter( function( s ) { + if ( s.crossDomain ) { + s.contents.script = false; + } +} ); + +// Install script dataType +jQuery.ajaxSetup( { + accepts: { + script: "text/javascript, application/javascript, " + + "application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /\b(?:java|ecma)script\b/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +} ); + +// Handle cache's special case and crossDomain +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + } +} ); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function( s ) { + + // This transport only deals with cross domain or forced-by-attrs requests + if ( s.crossDomain || s.scriptAttrs ) { + var script, callback; + return { + send: function( _, complete ) { + script = jQuery( " -{% include 'autocomplete_light/static.html' %} {% endblock %} {% block branding %} diff --git a/mamweb/templates/base.html b/mamweb/templates/base.html index f74e03bc..52911bcc 100644 --- a/mamweb/templates/base.html +++ b/mamweb/templates/base.html @@ -1,20 +1,22 @@ {% load staticfiles sekizai_tags %} +{% load sitetree %} {% block title %}{% block nadpis1a %}{% endblock %} – Korespondenční seminář M&M{% endblock title %} - - {% render_block "css" %} + + {% render_block css %} + {% block custom_css %}{% endblock %} - {% include 'autocomplete_light/static.html' %} + - - + + {# nastavení MathJaxu, aby nahrazoval i matiku obalenou jednoduchými $ #} - + {# Případné skripty widgetů formulářů #} + {% if form %} + {{form.media}} + {% endif %} {# script specifický pro stránku #} {% block script %}{% endblock %} - {% if user.is_staff %} - - {% endif %} -
    -
    -
    + {% if user.is_staff %} + + {% endif %} + +
    + -
    -
    - {# ========= MOBILE MENU ========== #} - - {# ============= MENU ============== #} - - {# ======== KONEC MENU =============#} -
    -
    -
    -
    - {% block submenu %} - {% endblock %} -
    -
    -
    -
    + + +{# ========= MENU ========== #} + + {% sitetree_menu from "main_menu" include "trunk" template "menu.html" %} + +{# ========= MENU MOBILE ========== #} + + + + + + +{# ========= END MENU ========== #} + + +
    + {% block content %} {% endblock content %} -
    -
    -
    -
    +
    + + +
    + + + -
    -
    +

    Korespondenční seminář M&M organizují převážně studenti MFF UK. Organizaci semináře a vydávání časopisu podporuje Jednota českých matematiků a fyziků. S obsahem webu M&M je možné nakládat dle licence Creative Commons Attribution 3.0.

    + +
    + + @@ -125,50 +131,48 @@ $("a[rel^='gallery-image']").prettyPhoto(prettyparams); }); - {% if april == 2021 %} - - {% endif %} + {% if april == 2021 %} + + {% endif %} + {% render_block "js" %} - diff --git a/mamweb/templates/flatpages/default.html b/mamweb/templates/flatpages/default.html index b5d2d24d..0a26ca27 100644 --- a/mamweb/templates/flatpages/default.html +++ b/mamweb/templates/flatpages/default.html @@ -8,106 +8,4 @@
    {{ flatpage.content }}
    -{% endblock content %} - -{# nahraj spravne submenu #} -{% block submenu %} - {# co-je-MaM #} - {% if "/co-je-MaM/" in flatpage.url %} - {% if "/uvod/" in flatpage.url %} - {% with "uvod" as selected %} - {% include "seminar/cojemam/submenu.html" %} - {% endwith %} - {% elif "jak-resit" in flatpage.url %} - {% with "jak-resit" as selected %} - {% include "seminar/cojemam/submenu.html" %} - {% endwith %} - {% elif "odmeny" in flatpage.url %} - {% with "odmeny" as selected %} - {% include "seminar/cojemam/submenu.html" %} - {% endwith %} - {% elif "FAQ" in flatpage.url %} - {% with "FAQ" as selected %} - {% include "seminar/cojemam/submenu.html" %} - {% endwith %} - {% elif "kontakt" in flatpage.url %} - {% else %} - {% include "seminar/cojemam/submenu.html" %} - {% endif %} - {% endif %} - {# soustredeni #} - {% if "/soustredeni/" in flatpage.url %} - {% if "/pripravujeme/" in flatpage.url %} - {% with "pripravujeme" as selected %} - {% include "seminar/soustredeni/submenu.html" %} - {% endwith %} - {% else %} - {% with "uvod" as selected %} - {% include "seminar/soustredeni/submenu.html" %} - {% endwith %} - {% endif %} - {% endif %} - {# zadani #} - {% if "/zadani/" in flatpage.url %} - {% if "/aktualni-cislo/" in flatpage.url %} - {% with "aktualni-cislo" as selected %} - {% include "seminar/zadani/submenu.html" %} - {% endwith %} - {% elif "/vysledkova-listina/" in flatpage.url %} - {% with "vysledkova-listina" as selected %} - {% include "seminar/zadani/submenu.html" %} - {% endwith %} - {% else %} - {% include "seminar/zadani/submenu.html" %} - {% endif %} - {% endif %} - {# clanky #} - {% if "/clanky/" in flatpage.url %} - {% if "/uvod/" in flatpage.url %} - {% with "uvod" as selected %} - {% include "seminar/clanky/submenu.html" %} - {% endwith %} - {% elif "/org/" in flatpage.url %} - {% with "org" as selected %} - {% include "seminar/clanky/submenu.html" %} - {% endwith %} - {% elif "/resitel/" in flatpage.url %} - {% with "resitel" as selected %} - {% include "seminar/clanky/submenu.html" %} - {% endwith %} - {% elif "/jak-psat-vedecky-clanek/" in flatpage.url %} - {% with "jak-psat-vedecky-clanek" as selected %} - {% include "seminar/clanky/submenu.html" %} - {% endwith %} - {% else %} - {% include "seminar/clanky/submenu.html" %} - {% endif %} - {% endif %} - {# archiv #} - {% if "/archiv/" in flatpage.url %} - {% if "/ulohy/" in flatpage.url %} - {% with "ulohy" as selected %} - {% include "seminar/archiv/submenu.html" %} - {% endwith %} - {% elif "/vysledky/" in flatpage.url %} - {% with "vysledky" as selected %} - {% include "seminar/archiv/submenu.html" %} - {% endwith %} - {% else %} - {% include "seminar/archiv/submenu.html" %} - {% endif %} - {% endif %} -{% endblock %} - -{# zvirazneni menu #} -{% block menu_uvod %}{% if not "/kontakt/" in flatpage.url %}{% if "/co-je-MaM/" in flatpage.url %}selected{% endif %}{% endif %}{% endblock %} -{% block menu_soustredeni %}{% if "/soustredeni/" in flatpage.url %}selected{% endif %}{% endblock %} -{% block menu_zadani %}{% if "/zadani/" in flatpage.url %}selected{% endif %}{% endblock %} -{% block menu_clanky %}{% if "/clanky/" in flatpage.url %}selected{% endif %}{% endblock %} -{% block menu_archiv %}{% if "/archiv/" in flatpage.url %}selected{% endif %}{% endblock %} -{% block menu_odevzdat %}{% if "/kontakt/" in flatpage.url %}selected{% endif %}{% endblock %} - -{# zmena titulniho obrazku #} -{% block header %}{% if "/co-je-MaM/" in flatpage.url %}cojemam{% elif "/soustredeni/" in flatpage.url %}soustredeni{% elif "/zadani/" in flatpage.url %}zadani{% elif "/clanky/" in flatpage.url %}clanky{% elif "/archiv/" in flatpage.url %}archiv{% else %}odeslat{% endif %}{% endblock header %} - -{# TODO zvirazneni submenu #} +{% endblock content %} \ No newline at end of file diff --git a/mamweb/templates/graph.svg b/mamweb/templates/graph.svg new file mode 100644 index 00000000..0d38f0f5 --- /dev/null +++ b/mamweb/templates/graph.svg @@ -0,0 +1,732 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + Strategické + + + + + + + Běhací + + + + + + Adrenalinové + + + + + + Jídlo + + + + + + Přednášky + + + + + + Soustředění + + + + + + Konfery + + + + + + Výlet + + + + + + Legenda + + + + + + M&M + + + + + + Časopis + + + + + + Články + + + + + + Matematika + + + + + + Fyzika + + + + + + Informatika + + + + + + Témata + + + + + + Dort + + + + + + Ceny pro vítěze + + + + + + + + + + + + + + + + + + + + + + + Hry + + + Hry + + + + diff --git a/mamweb/templates/logo.html b/mamweb/templates/logo.html new file mode 100644 index 00000000..c5113d0c --- /dev/null +++ b/mamweb/templates/logo.html @@ -0,0 +1,26 @@ +{% load staticfiles %} + \ No newline at end of file diff --git a/mamweb/templates/menu.html b/mamweb/templates/menu.html new file mode 100644 index 00000000..760d9959 --- /dev/null +++ b/mamweb/templates/menu.html @@ -0,0 +1,26 @@ +{% load sitetree %} +{% spaceless %} +{% autoescape off %} + +{% endautoescape %} +{% endspaceless %} diff --git a/mamweb/templates/menu_mobile.html b/mamweb/templates/menu_mobile.html new file mode 100644 index 00000000..aed04cd5 --- /dev/null +++ b/mamweb/templates/menu_mobile.html @@ -0,0 +1,21 @@ +{% load sitetree %} +{% spaceless %} +{% autoescape off %} + +{% endautoescape %} +{% endspaceless %} diff --git a/mamweb/templates/menu_mobile_dropdown.html b/mamweb/templates/menu_mobile_dropdown.html new file mode 100644 index 00000000..2bd722c5 --- /dev/null +++ b/mamweb/templates/menu_mobile_dropdown.html @@ -0,0 +1,8 @@ +{% load sitetree %} + diff --git a/mamweb/templates/submenu.html b/mamweb/templates/submenu.html new file mode 100644 index 00000000..05a33863 --- /dev/null +++ b/mamweb/templates/submenu.html @@ -0,0 +1,8 @@ +{% load sitetree %} + diff --git a/mamweb/templates/universal.html b/mamweb/templates/universal.html new file mode 100644 index 00000000..065dcf5a --- /dev/null +++ b/mamweb/templates/universal.html @@ -0,0 +1,19 @@ +{% extends 'base.html' %} + +{# Tohle je univerzální template pro potřebu zobrazovat triviální hlášky generované v kódu. __Není__ určen pro sofistikované použití ani pro zneužívání! #} + +{% block nadpis1a %}{% block nadpis1b %} +{{ title }} +{% endblock %}{% endblock %} + +{% block content %} +{% if error %} +

    {{ error }}

    +{% endif %} +{% if text %} +

    {{ text }}

    +{% endif %} +{% if raw_html %} +{{ raw_html | safe }} +{% endif %} +{% endblock %} diff --git a/mamweb/urls.py b/mamweb/urls.py index 4d4df748..2f5aeea9 100644 --- a/mamweb/urls.py +++ b/mamweb/urls.py @@ -1,37 +1,43 @@ -from django.conf.urls import * # NOQA -from django.conf.urls.i18n import i18n_patterns +from django.urls import path, include from django.contrib.staticfiles.urls import staticfiles_urlpatterns from django.contrib import admin from django.conf import settings from django.views.generic.base import TemplateView from django import views +from django.urls import path # As per docs. + +from .routers import router urlpatterns = [ - # Admin a nastroje - url(r'^admin/', include(admin.site.urls)), # NOQA - url(r'^ckeditor/', include('ckeditor_uploader.urls')), - url(r'^autocomplete/', include('autocomplete_light.urls')), + # Admin a nastroje + path('admin/', admin.site.urls), # NOQA + path('ckeditor/', include('ckeditor_uploader.urls')), + + # Seminarova aplikace (ma vlastni podadresare) + path('', include('seminar.urls')), + + # Korekturovaci aplikace (ma vlastni podadresare) + path('', include('korektury.urls')), + + # Prednaskova aplikace (ma vlastni podadresare) + path('', include('prednasky.urls')), - # Seminarova aplikace (ma vlastni podadresare) - url(r'^', include('seminar.urls')), - - # Korekturovaci aplikace (ma vlastni podadresare) - url(r'^', include('korektury.urls')), - - # Prednaskova aplikace (ma vlastni podadresare) - url(r'^', include('prednasky.urls')), + # Comments (interni i verejne) + path('comments_dj/', include('django_comments.urls')), + path('comments_fl/', include('fluent_comments.urls')), - # Comments (interni i verejne) - url(r'^comments_dj/', include('django_comments.urls')), - url(r'^comments_fl/', include('fluent_comments.urls')), + # REST API + path('api/', include(router.urls)), ] # This is only needed when using runserver. if settings.DEBUG: - urlpatterns += [ - url(r'^media/(?P.*)$', views.static.serve, # NOQA - {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}), - ] - urlpatterns += staticfiles_urlpatterns() + import debug_toolbar + urlpatterns += [ + path('media/', views.static.serve, # NOQA + {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}), + path('__debug__/', include(debug_toolbar.urls)), + ] + urlpatterns += staticfiles_urlpatterns() diff --git a/mamweb/wsgi.py b/mamweb/wsgi.py index fa13a197..ddb7f25c 100644 --- a/mamweb/wsgi.py +++ b/mamweb/wsgi.py @@ -4,25 +4,14 @@ WSGI config for mamweb project. It exposes the WSGI callable as a module-level variable named ``application``. For more information on this file, see -https://docs.djangoproject.com/en/1.7/howto/deployment/wsgi/ +https://docs.djangoproject.com/en/2.2/howto/deployment/wsgi/ """ -import sys, os, os.path, traceback, time, signal -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mamweb.settings") - -sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) -sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'lib', 'python2.7', 'site-packages'))) +import os +from django.core.wsgi import get_wsgi_application -try: - from django.core.wsgi import get_wsgi_application - application = get_wsgi_application() +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mamweb.settings") -except Exception: - print 'handling WSGI exception' - # Error loading applications - if 'mod_wsgi' in sys.modules: - traceback.print_exc() - os.kill(os.getpid(), signal.SIGINT) - time.sleep(2) +application = get_wsgi_application() diff --git a/mamweb_prod.ini b/mamweb_prod.ini index c841cdd7..8816064f 100644 --- a/mamweb_prod.ini +++ b/mamweb_prod.ini @@ -5,7 +5,8 @@ chdir = /akce/mam/www/mamweb-prod/ home = /akce/mam/www/mamweb-prod/ module = mamweb.wsgi -plugin = python +plugin = python3 +virtualenv = env master = True vacuum = True chmod-socket = 666 diff --git a/mamweb_test.ini b/mamweb_test.ini index 87ad98b5..ddd6e55c 100644 --- a/mamweb_test.ini +++ b/mamweb_test.ini @@ -5,7 +5,8 @@ chdir = /akce/mam/www/mamweb-test/ home = /akce/mam/www/mamweb-test/ module = mamweb.wsgi -plugin = python +plugin = python3 +virtualenv = env master = True vacuum = True chmod-socket = 666 diff --git a/manage.py b/manage.py index ccdb032b..24eeef69 100755 --- a/manage.py +++ b/manage.py @@ -1,4 +1,4 @@ -#!bin/python +#!/usr/bin/env python import os import sys diff --git a/obalky/lisak.eps b/obalky/lisak.eps deleted file mode 100644 index 3a136212..00000000 --- a/obalky/lisak.eps +++ /dev/null @@ -1,1603 +0,0 @@ -%%BeginDocument: ./Eps/lisak.eps -%!PS-Adobe-3.0 EPSF-3.0 -%%BoundingBox: -191 -97 769 946 -%%Creator: CorelDRAW 8 -%%Title: L:\Prace\MaM\Obrazky\Lisak.eps -%%CreationDate: Tue May 11 17:28:49 1999 -%%For: Halef -%%DocumentProcessColors: Black -%%DocumentSuppliedResources: (atend) -%%EndComments -%%BeginProlog -/AutoFlatness false def -/AutoSteps 0 def -/CMYKMarks true def -/UseLevel 1 def -%Color profile: PROFILES.CCM - Obecn profil tiskrny CMYK - d. -%%BeginResource: procset wCorel8Dict 8.0 0 -/wCorel8Dict 300 dict def wCorel8Dict begin -% Copyright (c)1992-97 Corel Corporation -% All rights reserved. v8.0 r0.7 -/bd{bind def}bind def/ld{load def}bd/xd{exch def}bd/_ null def/rp{{pop}repeat} -bd/@cp/closepath ld/@gs/gsave ld/@gr/grestore ld/@np/newpath ld/Tl/translate ld -/$sv 0 def/@sv{/$sv save def}bd/@rs{$sv restore}bd/spg/showpage ld/showpage{} -bd currentscreen/@dsp xd/$dsp/@dsp def/$dsa xd/$dsf xd/$sdf false def/$SDF -false def/$Scra 0 def/SetScr/setscreen ld/setscreen{pop pop pop}bd/@ss{2 index -0 eq{$dsf 3 1 roll 4 -1 roll pop}if exch $Scra add exch load SetScr}bd -/SepMode_5 where{pop}{/SepMode_5 0 def}ifelse/CurrentInkName_5 where{pop} -{/CurrentInkName_5(Composite)def}ifelse/$ink_5 where{pop}{/$ink_5 -1 def} -ifelse/$c 0 def/$m 0 def/$y 0 def/$k 0 def/$t 1 def/$n _ def/$o 0 def/$fil 0 -def/$C 0 def/$M 0 def/$Y 0 def/$K 0 def/$T 1 def/$N _ def/$O 0 def/$PF false -def/s1c 0 def/s1m 0 def/s1y 0 def/s1k 0 def/s1t 0 def/s1n _ def/$bkg false def -/SK 0 def/SM 0 def/SY 0 def/SC 0 def/$op false def matrix currentmatrix/$ctm xd -/$ptm matrix def/$ttm matrix def/$stm matrix def/$ffpnt true def -/CorelDrawReencodeVect[16#0/grave 16#5/breve 16#6/dotaccent 16#8/ring -16#A/hungarumlaut 16#B/ogonek 16#C/caron 16#D/dotlessi 16#27/quotesingle -16#60/grave 16#7C/bar -16#82/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl -16#88/circumflex/perthousand/Scaron/guilsinglleft/OE -16#91/quoteleft/quoteright/quotedblleft/quotedblright/bullet/endash/emdash -16#98/tilde/trademark/scaron/guilsinglright/oe 16#9F/Ydieresis -16#A1/exclamdown/cent/sterling/currency/yen/brokenbar/section -16#a8/dieresis/copyright/ordfeminine/guillemotleft/logicalnot/minus/registered/macron -16#b0/degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered -16#b8/cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown -16#c0/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla -16#c8/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis -16#d0/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply -16#d8/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls -16#e0/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla -16#e8/egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis -16#f0/eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide -16#f8/oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]def -/L2?/languagelevel where{pop languagelevel 2 ge}{false}ifelse def -/@BeginSysCorelDict{systemdict/Corel30Dict known{systemdict/Corel30Dict get -exec}if systemdict/CorelLexDict known{1 systemdict/CorelLexDict get exec}if}bd -/@EndSysCorelDict{systemdict/Corel30Dict known{end}if/EndCorelLexDict where -{pop EndCorelLexDict}if}bd AutoFlatness{/@ifl{dup currentflat exch sub 10 gt{ -([Error: PathTooComplex; OffendingCommand: AnyPaintingOperator]\n)print flush -@np exit}{currentflat 2 add setflat}ifelse}bd/@fill/fill ld/fill{currentflat{ -{@fill}stopped{@ifl}{exit}ifelse}bind loop setflat}bd/@eofill/eofill ld/eofill -{currentflat{{@eofill}stopped{@ifl}{exit}ifelse}bind loop setflat}bd/@clip -/clip ld/clip{currentflat{{@clip}stopped{@ifl}{exit}ifelse}bind loop setflat} -bd/@eoclip/eoclip ld/eoclip{currentflat{{@eoclip}stopped{@ifl}{exit}ifelse} -bind loop setflat}bd/@stroke/stroke ld/stroke{currentflat{{@stroke}stopped -{@ifl}{exit}ifelse}bind loop setflat}bd}if L2?{/@ssa{true setstrokeadjust}bd}{ -/@ssa{}bd}ifelse/d/setdash ld/j/setlinejoin ld/J/setlinecap ld/M/setmiterlimit -ld/w/setlinewidth ld/O{/$o xd}bd/R{/$O xd}bd/W/eoclip ld/c/curveto ld/C/c ld/l -/lineto ld/L/l ld/rl/rlineto ld/m/moveto ld/n/newpath ld/N/newpath ld/P{11 rp} -bd/u{}bd/U{}bd/A{pop}bd/q/@gs ld/Q/@gr ld/&{}bd/@j{@sv @np}bd/@J{@rs}bd/g{1 -exch sub/$k xd/$c 0 def/$m 0 def/$y 0 def/$t 1 def/$n _ def/$fil 0 def}bd/G{1 -sub neg/$K xd _ 1 0 0 0/$C xd/$M xd/$Y xd/$T xd/$N xd}bd/k{1 index type -/stringtype eq{/$t xd/$n xd}{/$t 0 def/$n _ def}ifelse/$k xd/$y xd/$m xd/$c xd -/$fil 0 def}bd/K{1 index type/stringtype eq{/$T xd/$N xd}{/$T 0 def/$N _ def} -ifelse/$K xd/$Y xd/$M xd/$C xd}bd/x/k ld/X/K ld/sf{1 index type/stringtype eq{ -/s1t xd/s1n xd}{/s1t 0 def/s1n _ def}ifelse/s1k xd/s1y xd/s1m xd/s1c xd}bd/i{ -dup 0 ne{setflat}{pop}ifelse}bd/v{4 -2 roll 2 copy 6 -2 roll c}bd/V/v ld/y{2 -copy c}bd/Y/y ld/@w{matrix rotate/$ptm xd matrix scale $ptm dup concatmatrix -/$ptm xd 1 eq{$ptm exch dup concatmatrix/$ptm xd}if 1 w}bd/@g{1 eq dup/$sdf xd -{/$scp xd/$sca xd/$scf xd}if}bd/@G{1 eq dup/$SDF xd{/$SCP xd/$SCA xd/$SCF xd} -if}bd/@D{2 index 0 eq{$dsf 3 1 roll 4 -1 roll pop}if 3 copy exch $Scra add exch -load SetScr/$dsp xd/$dsa xd/$dsf xd}bd/$ngx{$SDF{$SCF SepMode_5 0 eq{$SCA} -{$dsa}ifelse $SCP @ss}if}bd/p{/$pm xd 7 rp/$pyf xd/$pxf xd/$pn xd/$fil 1 def} -bd/@MN{2 copy le{pop}{exch pop}ifelse}bd/@MX{2 copy ge{pop}{exch pop}ifelse}bd -/InRange{3 -1 roll @MN @MX}bd/@sqr{dup 0 rl dup 0 exch rl neg 0 rl @cp}bd -/currentscale{1 0 dtransform matrix defaultmatrix idtransform dup mul exch dup -mul add sqrt 0 1 dtransform matrix defaultmatrix idtransform dup mul exch dup -mul add sqrt}bd/@unscale{}bd/wDstChck{2 1 roll dup 3 -1 roll eq{1 add}if}bd -/@dot{dup mul exch dup mul add 1 exch sub}bd/@lin{exch pop abs 1 exch sub}bd -/cmyk2rgb{3{dup 5 -1 roll add 1 exch sub dup 0 lt{pop 0}if exch}repeat pop}bd -/rgb2cmyk{3{1 exch sub 3 1 roll}repeat 3 copy @MN @MN 3{dup 5 -1 roll sub neg -exch}repeat}bd/rgb2g{2 index .299 mul 2 index .587 mul add 1 index .114 mul add -4 1 roll pop pop pop}bd/WaldoColor_5 where{pop}{/SetRgb/setrgbcolor ld/GetRgb -/currentrgbcolor ld/SetGry/setgray ld/GetGry/currentgray ld/SetRgb2 systemdict -/setrgbcolor get def/GetRgb2 systemdict/currentrgbcolor get def/SetHsb -systemdict/sethsbcolor get def/GetHsb systemdict/currenthsbcolor get def -/rgb2hsb{SetRgb2 GetHsb}bd/hsb2rgb{3 -1 roll dup floor sub 3 1 roll SetHsb -GetRgb2}bd/setcmykcolor where{pop/SetCmyk_5/setcmykcolor ld}{/SetCmyk_5{ -cmyk2rgb SetRgb}bd}ifelse/currentcmykcolor where{pop/GetCmyk/currentcmykcolor -ld}{/GetCmyk{GetRgb rgb2cmyk}bd}ifelse/setoverprint where{pop}{/setoverprint{ -/$op xd}bd}ifelse/currentoverprint where{pop}{/currentoverprint{$op}bd}ifelse -/@tc_5{5 -1 roll dup 1 ge{pop}{4{dup 6 -1 roll mul exch}repeat pop}ifelse}bd -/@trp{exch pop 5 1 roll @tc_5}bd/setprocesscolor_5{SepMode_5 0 eq{SetCmyk_5}{0 -4 $ink_5 sub index exch pop 5 1 roll pop pop pop pop SepsColor true eq{$ink_5 3 -gt{1 sub neg SetGry}{0 0 0 4 $ink_5 roll SetCmyk_5}ifelse}{1 sub neg SetGry} -ifelse}ifelse}bd/findcmykcustomcolor where{pop}{/findcmykcustomcolor{5 array -astore}bd}ifelse/setcustomcolor where{pop}{/setcustomcolor{exch aload pop -SepMode_5 0 eq{pop @tc_5 setprocesscolor_5}{CurrentInkName_5 eq{4 index}{0} -ifelse 6 1 roll 5 rp 1 sub neg SetGry}ifelse}bd}ifelse/@scc_5{dup type -/booleantype eq{setoverprint}{1 eq setoverprint}ifelse dup _ eq{pop -setprocesscolor_5 pop}{findcmykcustomcolor exch setcustomcolor}ifelse SepMode_5 -0 eq{true}{GetGry 1 eq currentoverprint and not}ifelse}bd/colorimage where{pop -/ColorImage{colorimage}def}{/ColorImage{/ncolors xd pop/dataaq xd{dataaq -ncolors dup 3 eq{/$dat xd 0 1 $dat length 3 div 1 sub{dup 3 mul $dat 1 index -get 255 div $dat 2 index 1 add get 255 div $dat 3 index 2 add get 255 div rgb2g -255 mul cvi exch pop $dat 3 1 roll put}for $dat 0 $dat length 3 idiv -getinterval pop}{4 eq{/$dat xd 0 1 $dat length 4 div 1 sub{dup 4 mul $dat 1 -index get 255 div $dat 2 index 1 add get 255 div $dat 3 index 2 add get 255 div -$dat 4 index 3 add get 255 div cmyk2rgb rgb2g 255 mul cvi exch pop $dat 3 1 -roll put}for $dat 0 $dat length ncolors idiv getinterval}if}ifelse}image}bd -}ifelse/setcmykcolor{1 5 1 roll _ currentoverprint @scc_5/$ffpnt xd}bd -/currentcmykcolor{0 0 0 0}bd/setrgbcolor{rgb2cmyk setcmykcolor}bd -/currentrgbcolor{currentcmykcolor cmyk2rgb}bd/sethsbcolor{hsb2rgb setrgbcolor} -bd/currenthsbcolor{currentrgbcolor rgb2hsb}bd/setgray{dup dup setrgbcolor}bd -/currentgray{currentrgbcolor rgb2g}bd/InsideDCS false def/IMAGE systemdict -/image get def/image{InsideDCS{IMAGE}{/EPSDict where{pop SepMode_5 0 eq{IMAGE} -{dup type/dicttype eq{dup/ImageType get 1 ne{IMAGE}{dup dup/BitsPerComponent -get 8 eq exch/BitsPerComponent get 1 eq or currentcolorspace 0 get/DeviceGray -eq and{CurrentInkName_5(Black)eq{IMAGE}{dup/DataSource get/TCC xd/Height get -abs{TCC pop}repeat}ifelse}{IMAGE}ifelse}ifelse}{2 index 1 ne{CurrentInkName_5 -(Black)eq{IMAGE}{/TCC xd pop pop exch pop abs{TCC pop}repeat}ifelse}{IMAGE} -ifelse}ifelse}ifelse}{IMAGE}ifelse}ifelse}bd}ifelse/WaldoColor_5 true def/@sft -{$tllx $pxf add dup $tllx gt{$pwid sub}if/$tx xd $tury $pyf sub dup $tury lt -{$phei add}if/$ty xd}bd/@stb{pathbbox/$ury xd/$urx xd/$lly xd/$llx xd}bd/@ep{{ -cvx exec}forall}bd/@tp{@sv/$in true def 2 copy dup $lly le{/$in false def}if -$phei sub $ury ge{/$in false def}if dup $urx ge{/$in false def}if $pwid add -$llx le{/$in false def}if $in{@np 2 copy m $pwid 0 rl 0 $phei neg rl $pwid neg -0 rl 0 $phei rl clip @np $pn cvlit load aload pop 7 -1 roll 5 index sub 7 -1 -roll 3 index sub Tl matrix currentmatrix/$ctm xd @ep pop pop pop pop}{pop pop -}ifelse @rs}bd/@th{@sft 0 1 $tly 1 sub{dup $psx mul $tx add{dup $llx gt{$pwid -sub}{exit}ifelse}loop exch $phei mul $ty exch sub 0 1 $tlx 1 sub{$pwid mul 3 -copy 3 -1 roll add exch @tp pop}for pop pop}for}bd/@tv{@sft 0 1 $tlx 1 sub{dup -$pwid mul $tx add exch $psy mul $ty exch sub{dup $ury lt{$phei add}{exit} -ifelse}loop 0 1 $tly 1 sub{$phei mul 3 copy sub @tp pop}for pop pop}for}bd/$fm -0 def/wfill{1 $fm eq{fill}{eofill}ifelse}bd/wclip{1 $fm eq{clip}{eoclip}ifelse -}bd/@pf{@gs $ctm setmatrix $pm concat @stb wclip @sv Bburx Bbury $pm itransform -/$tury xd/$turx xd Bbllx Bblly $pm itransform/$tlly xd/$tllx xd newpath $tllx -$tlly m $tllx $tury l $turx $tury l $turx $tlly l $tllx $tlly m @cp pathbbox -@rs/$tury xd/$turx xd/$tlly xd/$tllx xd/$wid $turx $tllx sub def/$hei $tury -$tlly sub def @gs $vectpat{1 0 0 0 0 _ $o @scc_5{wfill}if}{$t $c $m $y $k $n $o -@scc_5{SepMode_5 0 eq $pfrg or{$tllx $tlly Tl $wid $hei scale <00> 8 1 false[8 -0 0 1 0 0]{}imagemask}{/$bkg true def}ifelse}if}ifelse @gr $wid 0 gt $hei 0 gt -and{$pn cvlit load aload pop/$pd xd 3 -1 roll sub/$phei xd exch sub/$pwid xd -$wid $pwid div ceiling 1 add/$tlx xd $hei $phei div ceiling 1 add/$tly xd $psx -0 eq{@tv}{@th}ifelse}if @gr @np/$bkg false def}bd/@Pf{@sv SepMode_5 0 eq $Psc 0 -ne or $ink_5 3 eq or{0 J 0 j[]0 d $t $c $m $y $k $n $o @scc_5 pop $ctm -setmatrix 72 1000 div dup matrix scale dup concat dup Bburx exch Bbury exch -itransform ceiling cvi/Bbury xd ceiling cvi/Bburx xd Bbllx exch Bblly exch -itransform floor cvi/Bblly xd floor cvi/Bbllx xd $Prm aload pop $Psn load exec -}{1 SetGry wfill}ifelse @rs @np}bd/F{matrix currentmatrix $sdf{$scf $sca $scp -@ss}if $fil 1 eq{@pf}{$fil 2 eq{@ff}{$fil 3 eq{@Pf}{$t $c $m $y $k $n $o @scc_5 -{wfill}{@np}ifelse}ifelse}ifelse}ifelse $sdf{$dsf $dsa $dsp @ss}if setmatrix} -bd/f{@cp F}bd/S{matrix currentmatrix $ctm setmatrix $SDF{$SCF $SCA $SCP @ss}if -$T $C $M $Y $K $N $O @scc_5{matrix currentmatrix $ptm concat stroke setmatrix} -{@np}ifelse $SDF{$dsf $dsa $dsp @ss}if setmatrix}bd/s{@cp S}bd/B{@gs F @gr S} -bd/b{@cp B}bd/_E{5 array astore exch cvlit xd}bd/@cc{currentfile $dat -readhexstring pop}bd/@sm{/$ctm $ctm currentmatrix def}bd/@E{/Bbury xd/Bburx xd -/Bblly xd/Bbllx xd}bd/@c{@cp}bd/@p{/$fil 1 def 1 eq dup/$vectpat xd{/$pfrg true -def}{@gs $t $c $m $y $k $n $o @scc_5/$pfrg xd @gr}ifelse/$pm xd/$psy xd/$psx xd -/$pyf xd/$pxf xd/$pn xd}bd/@P{/$fil 3 def/$Psn xd/$Psc xd array astore/$Prm xd -}bd/@ii{concat 3 index 3 index m 3 index 1 index l 2 copy l 1 index 3 index l 3 -index 3 index l clip pop pop pop pop}bd/tcc{@cc}def/@i{@sm @gs @ii 6 index 1 ne -{/$frg true def pop pop}{1 eq{s1t s1c s1m s1y s1k s1n $O @scc_5/$frg xd}{/$frg -false def}ifelse 1 eq{@gs $ctm setmatrix F @gr}if}ifelse @np/$ury xd/$urx xd -/$lly xd/$llx xd/$bts xd/$hei xd/$wid xd/$dat $wid $bts mul 8 div ceiling cvi -string def $bkg $frg or{$SDF{$SCF $SCA $SCP @ss}if $llx $lly Tl $urx $llx sub -$ury $lly sub scale $bkg{$t $c $m $y $k $n $o @scc_5 pop}if $wid $hei abs $bts -1 eq{$bkg}{$bts}ifelse[$wid 0 0 $hei neg 0 $hei 0 gt{$hei}{0}ifelse]/tcc load -$bts 1 eq{imagemask}{image}ifelse $SDF{$dsf $dsa $dsp @ss}if}{$hei abs{tcc pop} -repeat}ifelse @gr $ctm setmatrix}bd/@I{@sm @gs @ii @np/$ury xd/$urx xd/$lly xd -/$llx xd/$ncl xd/$bts xd/$hei xd/$wid xd/$dat $wid $bts mul $ncl mul 8 div -ceiling cvi string def $ngx $llx $lly Tl $urx $llx sub $ury $lly sub scale $wid -$hei abs $bts[$wid 0 0 $hei neg 0 $hei 0 gt{$hei}{0}ifelse]/@cc load false $ncl -ColorImage $SDF{$dsf $dsa $dsp @ss}if @gr $ctm setmatrix}bd/COMP 0 def -/MaskedImage false def L2?{/@I_2{@sm @gs @ii @np/$ury xd/$urx xd/$lly xd/$llx -xd/$ncl xd/$bts xd/$hei xd/$wid xd/$dat $wid $bts mul $ncl mul 8 div ceiling -cvi string def $ngx $ncl 1 eq{/DeviceGray}{$ncl 3 eq{/DeviceRGB}{/DeviceCMYK} -ifelse}ifelse setcolorspace $llx $lly Tl $urx $llx sub $ury $lly sub scale 8 -dict begin/ImageType 1 def/Width $wid def/Height $hei abs def/BitsPerComponent -$bts def/Decode $ncl 1 eq{[0 1]}{$ncl 3 eq{[0 1 0 1 0 1]}{[0 1 0 1 0 1 0 1]} -ifelse}ifelse def/ImageMatrix[$wid 0 0 $hei neg 0 $hei 0 gt{$hei}{0}ifelse]def -/DataSource currentfile/ASCII85Decode filter COMP 1 eq{/DCTDecode filter}{COMP -2 eq{/RunLengthDecode filter}if}ifelse def currentdict end image $SDF{$dsf $dsa -$dsp @ss}if @gr $ctm setmatrix}bd}{/@I_2{}bd}ifelse/@I_3{@sm @gs @ii @np/$ury -xd/$urx xd/$lly xd/$llx xd/$ncl xd/$bts xd/$hei xd/$wid xd/$dat $wid $bts mul -$ncl mul 8 div ceiling cvi string def $ngx $ncl 1 eq{/DeviceGray}{$ncl 3 eq -{/DeviceRGB}{/DeviceCMYK}ifelse}ifelse setcolorspace $llx $lly Tl $urx $llx sub -$ury $lly sub scale/ImageDataDict 8 dict def ImageDataDict begin/ImageType 1 -def/Width $wid def/Height $hei abs def/BitsPerComponent $bts def/Decode $ncl 1 -eq{[0 1]}{$ncl 3 eq{[0 1 0 1 0 1]}{[0 1 0 1 0 1 0 1]}ifelse}ifelse def -/ImageMatrix[$wid 0 0 $hei neg 0 $hei 0 gt{$hei}{0}ifelse]def/DataSource -currentfile/ASCII85Decode filter COMP 1 eq{/DCTDecode filter}{COMP 2 eq{ -/RunLengthDecode filter}if}ifelse def end/MaskedImageDict 7 dict def -MaskedImageDict begin/ImageType 3 def/InterleaveType 3 def/MaskDict -ImageMaskDict def/DataDict ImageDataDict def end MaskedImageDict image $SDF -{$dsf $dsa $dsp @ss}if @gr $ctm setmatrix}bd/@SetMask{/$mbts xd/$mhei xd/$mwid -xd/ImageMaskDict 8 dict def ImageMaskDict begin/ImageType 1 def/Width $mwid def -/Height $mhei abs def/BitsPerComponent $mbts def/DataSource maskstream def -/ImageMatrix[$mwid 0 0 $mhei neg 0 $mhei 0 gt{$mhei}{0}ifelse]def/Decode[1 0] -def end}bd/@B{@gs S @gr F}bd/@b{@cp @B}bd/@sep{CurrentInkName_5(Composite)eq -{/$ink_5 -1 def}{CurrentInkName_5(Cyan)eq{/$ink_5 0 def}{CurrentInkName_5 -(Magenta)eq{/$ink_5 1 def}{CurrentInkName_5(Yellow)eq{/$ink_5 2 def}{ -CurrentInkName_5(Black)eq{/$ink_5 3 def}{/$ink_5 4 def}ifelse}ifelse}ifelse} -ifelse}ifelse}bd/@whi{@gs -72000 dup m -72000 72000 l 72000 dup l 72000 -72000 -l @cp 1 SetGry fill @gr}bd/@neg{[{1 exch sub}/exec cvx currenttransfer/exec -cvx]cvx settransfer @whi}bd/deflevel 0 def/@sax{/deflevel deflevel 1 add def} -bd/@eax{/deflevel deflevel dup 0 gt{1 sub}if def deflevel 0 gt{/eax load}{eax} -ifelse}bd/eax{{exec}forall}bd/@rax{deflevel 0 eq{@rs @sv}if}bd/@daq{dup type -/arraytype eq{{}forall}if}bd/@BMP{/@cc xd UseLevel 3 eq MaskedImage true eq and -{7 -2 roll pop pop @I_3}{12 index 1 gt UseLevel 2 eq UseLevel 3 eq or and{7 -2 -roll pop pop @I_2}{11 index 1 eq{12 -1 roll pop @i}{7 -2 roll pop pop @I} -ifelse}ifelse}ifelse}bd systemdict/pdfmark known not{/pdfmark/cleartomark ld} -if -end -%%EndResource -%%EndProlog -%%BeginSetup -wCorel8Dict begin -@BeginSysCorelDict -2.6131 setmiterlimit -1.00 setflat -/$fst 128 def -%%EndSetup - -%%Page: 1 1 -%LogicalPage: 1 -%%BeginPageSetup -@sv -@sm -@sv -%%EndPageSetup -@rax %Note: Object -482.82180 -96.51912 768.51780 183.48888 @E - 1 O 0 @g -0.00 0.00 0.00 1.00 k -/$fm 0 def -614.79780 -96.51912 m -610.54980 -96.23112 606.30180 -96.01512 602.05380 -95.79912 C -594.49380 -90.75912 581.53380 -79.52712 580.23780 -71.31912 C -573.54180 -72.90312 569.86980 -76.71912 564.46980 -80.75112 C -552.15780 -82.69512 539.12580 -86.94312 527.60580 -86.36712 C -523.57380 -78.30312 530.26980 -71.10312 536.96580 -68.29512 C -538.76580 -62.10312 543.30180 -61.16712 548.62980 -57.71112 C -548.05380 -50.00712 537.32580 -44.82312 535.88580 -36.61512 C -535.38180 -36.61512 534.87780 -36.61512 534.37380 -36.61512 C -532.50180 -26.82312 531.70980 -26.10312 531.34980 -23.79912 C -533.65380 -22.64712 533.65380 -22.64712 534.37380 -20.77512 C -547.33380 -17.96712 552.58980 -17.03112 564.82980 -26.10312 C -565.04580 -28.04712 576.56580 -35.39112 580.23780 -35.89512 C -582.54180 -11.48712 580.59780 7.59288 565.98180 27.10488 C -565.18980 27.24888 564.39780 27.39288 563.67780 27.46488 C -562.23780 18.17688 557.84580 10.32888 552.01380 2.55288 C -540.92580 -2.05512 538.54980 13.64088 536.60580 19.90488 C -535.81380 19.90488 535.09380 19.90488 534.37380 19.90488 C -529.40580 9.89688 520.69380 -0.83112 508.81380 -0.83112 C -494.26980 8.88888 501.90180 18.60888 506.94180 32.00088 C -510.03780 38.04888 513.13380 44.09688 516.30180 50.07288 C -502.62180 47.69688 487.28580 43.37688 482.82180 60.58488 C -482.82180 75.92088 495.99780 80.81688 508.81380 83.62488 C -509.17380 86.21688 509.17380 86.21688 507.66180 90.03288 C -511.62180 108.96888 509.53380 106.66488 525.73380 108.82488 C -525.80580 109.83288 525.94980 110.84088 526.09380 111.84888 C -531.06180 111.56088 536.31780 105.94488 538.11780 100.54488 C -543.08580 102.27288 544.45380 108.17688 546.75780 112.64088 C -552.80580 120.12888 556.18980 122.79288 556.90980 124.66488 C -559.21380 123.58488 559.21380 123.58488 561.80580 123.94488 C -562.16580 125.09688 562.52580 126.24888 562.95780 127.32888 C -566.34180 126.68088 572.67780 117.10488 574.54980 113.36088 C -574.54980 105.87288 573.68580 99.60888 571.95780 91.54488 C -577.50180 91.83288 580.09380 94.92888 587.00580 94.92888 C -589.95780 92.91288 592.98180 90.89688 596.00580 88.88088 C -606.15780 73.32888 587.65380 57.34488 575.70180 48.20088 C -568.93380 45.17688 568.93380 45.17688 565.54980 42.51288 C -565.40580 41.28888 565.26180 40.06488 565.18980 38.76888 C -565.69380 38.76888 566.19780 38.76888 566.70180 38.76888 C -575.12580 25.16088 585.85380 9.10488 587.72580 -7.95912 C -592.83780 -6.08712 598.74180 27.75288 600.90180 34.23288 C -603.99780 38.76888 605.72580 44.45688 606.87780 49.28088 C -618.97380 73.40088 624.94980 83.19288 625.30980 85.49688 C -605.86980 84.77688 614.79780 105.15288 618.18180 116.38488 C -622.42980 122.72088 625.74180 126.39288 631.35780 131.14488 C -631.21380 151.08888 626.38980 166.28088 648.63780 171.39288 C -648.34980 172.40088 648.13380 173.40888 647.91780 174.41688 C -658.42980 174.05688 660.15780 170.45688 661.45380 158.57688 C -667.93380 160.16088 680.46180 184.42488 687.01380 177.87288 C -688.74180 178.37688 690.46980 178.88088 692.26980 179.38488 C -692.62980 181.25688 692.62980 181.25688 691.47780 183.48888 C -700.90980 182.98488 702.42180 175.13688 702.42180 166.13688 C -697.09380 155.62488 697.09380 155.62488 696.73380 153.32088 C -709.47780 152.88888 712.14180 142.30488 712.14180 129.99288 C -706.95780 120.63288 695.50980 108.96888 684.70980 106.95288 C -681.90180 104.57688 680.74980 103.35288 677.22180 102.84888 C -677.72580 90.24888 664.33380 71.67288 652.38180 67.06488 C -639.49380 70.16088 648.34980 87.36888 644.17380 94.92888 C -643.38180 95.07288 642.58980 95.21688 641.86980 95.28888 C -641.14980 93.41688 637.76580 90.75288 625.66980 72.68088 C -611.91780 47.40888 601.26180 22.64088 597.51780 -6.44712 C -612.63780 -1.04712 612.49380 24.29688 632.07780 22.92888 C -632.07780 22.42488 632.07780 21.92088 632.07780 21.41688 C -632.58180 21.41688 633.08580 21.41688 633.58980 21.41688 C -635.10180 12.99288 632.29380 6.72888 629.84580 -1.98312 C -638.62980 3.99288 643.23780 15.36888 654.68580 18.03288 C -660.01380 23.64888 665.41380 25.95288 672.32580 29.69688 C -673.26180 48.12888 680.02980 58.78488 697.09380 66.63288 C -695.43780 84.92088 694.28580 92.19288 710.26980 103.20888 C -714.08580 103.20888 714.80580 102.48888 721.21380 102.84888 C -721.71780 103.85688 722.22180 104.86488 722.72580 105.87288 C -723.58980 106.01688 724.45380 106.16088 725.31780 106.23288 C -729.06180 102.48888 731.94180 99.75288 732.87780 93.05688 C -740.29380 95.21688 745.04580 103.20888 753.90180 103.20888 C -754.69380 102.48888 754.69380 102.48888 757.64580 102.48888 C -762.03780 106.88088 763.98180 104.50488 768.51780 100.54488 C -767.65380 91.25688 763.33380 83.84088 757.64580 76.06488 C -753.32580 75.05688 749.07780 67.13688 747.92580 62.88888 C -749.36580 62.67288 750.87780 62.38488 752.38980 62.09688 C -754.47780 57.05688 758.79780 53.60088 758.79780 46.25688 C -751.30980 29.62488 738.06180 20.26488 720.06180 20.26488 C -715.45380 15.00888 703.64580 1.47288 695.65380 6.36888 C -691.11780 13.13688 694.57380 20.84088 695.29380 27.46488 C -675.78180 25.01688 656.34180 16.16088 642.66180 2.19288 C -640.35780 -1.55112 638.48580 -2.70312 638.12580 -5.00712 C -643.38180 -5.36712 643.38180 -5.36712 645.25380 -6.44712 C -645.25380 -20.84712 643.74180 -31.14312 637.76580 -44.89512 C -636.25380 -46.40712 636.25380 -46.40712 635.89380 -48.71112 C -648.99780 -49.07112 665.12580 -49.79112 678.73380 -51.73512 C -678.73380 -52.23912 678.73380 -52.74312 678.73380 -53.24712 C -663.39780 -63.61512 643.09380 -80.31912 623.86980 -81.11112 C -625.81380 -93.99912 627.97380 -95.00712 614.79780 -96.51912 C -@c -F - -@rax %Note: Object -587.00580 -92.77512 618.15345 -70.52712 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -613.28580 -92.77512 m -609.68580 -86.58312 600.61380 -91.40712 596.79780 -82.62312 C -596.29380 -82.62312 595.78980 -82.62312 595.28580 -82.62312 C -591.61380 -77.36712 589.16580 -75.85512 587.00580 -70.52712 C -594.49380 -70.88712 598.88580 -71.03112 603.92580 -78.08712 C -609.54180 -80.75112 609.54180 -80.75112 617.10180 -82.62312 C -618.39780 -87.15912 619.69380 -92.77512 613.28580 -92.77512 C -@c -F - -@rax %Note: Object -534.37380 -79.95912 573.46980 -64.09020 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -535.88580 -79.95912 m -535.38180 -79.81512 534.87780 -79.67112 534.37380 -79.59912 C -539.77380 -60.80712 558.34980 -63.54312 573.46980 -65.27112 C -567.13380 -78.01512 550.14180 -74.19912 539.62980 -78.44712 C -538.11780 -79.95912 538.11780 -79.95912 535.88580 -79.95912 C -@c -F - -@rax %Note: Object -612.20580 -75.42312 656.91780 -55.75946 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -620.05380 -75.42312 m -616.88580 -74.63112 612.63780 -68.79912 612.20580 -66.06312 C -630.34980 -54.75912 634.95780 -54.03912 656.91780 -57.71112 C -651.44580 -68.15112 631.64580 -75.42312 620.05380 -75.42312 C -@c -F - -@rax %Note: Object --104.09528 -70.16712 339.97380 514.40088 @E - 1 O 0 @g -0.00 0.00 0.00 1.00 k -/$fm 0 def -226.14180 -70.16712 m -220.81380 -64.83912 220.23780 -58.86312 212.60580 -56.99112 C -211.66980 -58.21512 210.80580 -59.43912 209.94180 -60.73512 C -201.08580 -61.02312 198.63780 -59.36712 198.63780 -50.94312 C -196.04580 -47.41512 195.90180 -47.19912 197.55780 -44.17512 C -195.54180 -44.17512 193.52580 -44.17512 191.50980 -44.17512 C -185.82180 -54.83112 185.96580 -59.22312 174.22980 -61.09512 C -169.18980 -57.71112 169.62180 -56.55912 168.61380 -51.73512 C -167.67780 -51.59112 166.81380 -51.44712 165.94980 -51.30312 C -153.34980 -67.43112 148.02180 -71.17512 140.38980 -51.73512 C -133.62180 -54.32712 133.62180 -54.32712 127.64580 -58.07112 C -116.48580 -58.07112 114.75780 -54.18312 114.10980 -44.89512 C -106.04580 -45.47112 99.63780 -55.19112 92.29380 -59.58312 C -89.26980 -59.58312 86.24580 -59.58312 83.29380 -59.58312 C -78.46980 -54.75912 78.32580 -52.81512 78.75780 -47.19912 C -72.06180 -48.49512 70.47780 -55.11912 62.19780 -55.11912 C -57.66180 -49.35912 58.38180 -47.05512 57.73380 -40.43112 C -53.91780 -41.51112 53.91780 -41.51112 47.94180 -44.53512 C -24.54180 -44.53512 29.36580 -27.11112 40.45380 -14.36712 C -48.66180 -9.83112 47.79780 -10.62312 56.94180 -10.62312 C -77.24580 9.68088 33.90180 36.53688 22.38180 45.17688 C -2.36580 55.18488 -17.72220 68.07288 -33.99420 82.11288 C --37.66620 83.91288 -45.44220 89.60088 -47.53020 90.03288 C --47.53020 90.53688 -47.53020 91.04088 -47.53020 91.54488 C --60.56220 102.63288 -68.84220 110.04888 -77.98620 122.43288 C --79.49820 126.96888 -82.52220 130.71288 -91.52220 146.55288 C --107.50620 182.40888 -113.69820 219.12888 -77.62620 243.46488 C --59.26620 249.65688 -50.26620 247.64088 -30.25020 244.90488 C --29.31420 243.96888 -8.21820 236.12088 -4.69020 235.47288 C --4.47420 234.89688 -4.25820 234.24888 -3.97020 233.60088 C -4.23780 232.23288 8.19780 227.40888 16.33380 224.96088 C -16.33380 224.45688 16.33380 223.95288 16.33380 223.44888 C -19.06980 221.93688 21.80580 220.42488 24.61380 218.91288 C -24.61380 218.40888 24.61380 217.90488 24.61380 217.40088 C -34.26180 213.44088 44.84580 189.68088 49.45380 178.95288 C -57.08580 182.84088 50.60580 193.78488 52.04580 201.56088 C -52.04580 207.82488 50.82180 221.00088 54.27780 226.47288 C -51.61380 269.67288 66.66180 315.53688 81.34980 355.35288 C -84.37380 359.09688 84.37380 359.09688 93.37380 377.96088 C -109.71780 400.35288 123.39780 430.23288 135.49380 454.85688 C -141.97380 473.57688 150.68580 493.88088 154.28580 512.88888 C -155.43780 514.04088 155.43780 514.04088 159.97380 514.40088 C -154.71780 483.22488 139.81380 451.47288 126.13380 422.81688 C -125.62980 422.74488 125.12580 422.60088 124.62180 422.45688 C -120.37380 404.38488 103.74180 389.55288 97.90980 371.91288 C -95.10180 366.44088 92.36580 360.89688 89.62980 355.35288 C -85.74180 353.91288 78.18180 327.84888 76.88580 320.64888 C -67.23780 302.07288 65.14980 271.11288 61.04580 249.80088 C -61.04580 236.98488 58.81380 218.91288 58.09380 200.84088 C -60.32580 164.62488 60.32580 164.62488 60.32580 155.62488 C -58.74180 153.96888 56.79780 151.88088 54.70980 151.44888 C -51.18180 157.92888 51.54180 163.25688 47.50980 168.44088 C -36.99780 191.04888 34.04580 195.51288 32.53380 199.32888 C -8.77380 229.06488 -34.28220 244.61688 -70.85820 238.92888 C --76.76220 236.55288 -83.81820 233.74488 -86.26620 227.19288 C --102.17820 211.28088 -97.06620 190.32888 -93.82620 169.95288 C --88.28220 156.12888 -74.09820 119.55288 -59.55420 113.36088 C --56.60220 108.10488 -39.97020 91.18488 -32.48220 90.03288 C --32.48220 89.52888 -32.48220 89.02488 -32.48220 88.52088 C --29.38620 86.79288 -26.29020 84.99288 -23.12220 83.19288 C --23.05020 82.76088 -22.90620 82.25688 -22.76220 81.75288 C --12.17820 77.00088 -1.16220 63.75288 10.35780 61.01688 C -12.51780 58.85688 23.53380 52.52088 27.63780 51.58488 C -30.73380 43.16088 45.27780 42.15288 49.45380 32.72088 C -57.15780 29.98488 64.71780 19.11288 67.81380 10.83288 C -67.81380 2.33688 69.61380 -5.36712 63.70980 -12.85512 C -51.18180 -16.23912 38.50980 -18.90312 38.50980 -34.38312 C -40.02180 -35.89512 40.02180 -35.89512 40.45380 -37.40712 C -44.70180 -36.75912 48.94980 -36.11112 53.19780 -35.46312 C -55.71780 -31.14312 61.33380 -27.83112 66.37380 -28.33512 C -66.37380 -34.31112 64.93380 -40.14312 65.22180 -47.19912 C -77.38980 -43.45512 72.70980 -30.92712 84.80580 -29.84712 C -85.23780 -36.90312 83.86980 -43.88712 85.52580 -51.73512 C -98.26980 -50.72712 104.67780 -40.64712 115.62180 -34.74312 C -119.43780 -25.23912 121.30980 -18.18312 132.90180 -16.31112 C -132.90180 -17.03112 132.90180 -17.75112 132.90180 -18.54312 C -145.64580 -14.65512 139.59780 -8.46312 143.77380 0.32088 C -143.77380 10.11288 143.77380 19.90488 143.77380 29.69688 C -140.89380 49.49688 138.66180 68.86488 134.77380 87.72888 C -134.77380 126.68088 107.70180 164.26488 107.70180 203.07288 C -106.18980 206.88888 103.16580 233.24088 102.44580 233.96088 C -96.32580 258.51288 101.07780 285.94488 102.44580 310.13688 C -103.16580 313.16088 104.67780 314.67288 105.10980 319.20888 C -106.69380 318.99288 108.27780 318.70488 109.93380 318.41688 C -107.70180 289.76088 107.70180 289.76088 106.90980 289.04088 C -106.90980 256.85688 110.65380 226.04088 114.46980 193.28088 C -117.99780 181.11288 123.18180 165.92088 124.98180 152.60088 C -132.97380 144.60888 141.75780 91.54488 143.77380 80.96088 C -145.28580 64.40088 146.79780 59.07288 150.54180 24.44088 C -150.25380 12.63288 150.03780 0.82488 149.82180 -10.98312 C -142.69380 -25.31112 131.67780 -18.75912 123.46980 -31.35912 C -122.31780 -36.47112 119.14980 -44.46312 122.38980 -49.79112 C -132.46980 -55.04712 136.21380 -39.35112 146.43780 -38.48712 C -146.94180 -45.25512 146.07780 -50.58312 150.18180 -56.55912 C -153.20580 -56.55912 153.20580 -56.55912 158.02980 -54.75912 C -161.05380 -47.91912 167.10180 -38.12712 169.76580 -32.43912 C -171.49380 -32.58312 173.22180 -32.72712 175.02180 -32.87112 C -175.38180 -47.19912 175.38180 -47.19912 176.53380 -52.09512 C -185.67780 -52.09512 184.38180 -46.40712 187.40580 -38.91912 C -188.91780 -21.71112 190.71780 -3.85512 184.38180 12.34488 C -183.22980 23.36088 182.43780 30.12888 184.02180 40.28088 C -183.51780 40.28088 183.01380 40.28088 182.50980 40.28088 C -182.07780 54.39288 183.30180 68.14488 184.38180 81.75288 C -180.13380 90.10488 179.41380 99.39288 177.97380 107.74488 C -177.46980 107.88888 176.96580 108.03288 176.53380 108.10488 C -175.38180 114.87288 176.10180 115.66488 175.02180 124.66488 C -165.66180 122.50488 166.02180 122.57688 163.35780 131.50488 C -163.35780 140.50488 164.07780 141.29688 164.79780 148.06488 C -164.07780 148.78488 164.79780 167.64888 164.07780 193.28088 C -163.06980 201.63288 162.06180 209.91288 161.05380 218.19288 C -155.72580 218.62488 156.51780 215.52888 151.33380 219.70488 C -145.57380 239.93688 152.98980 260.88888 153.92580 280.76088 C -151.69380 280.40088 149.46180 278.09688 147.94980 278.09688 C -138.22980 287.81688 162.34980 335.91288 163.71780 344.84088 C -157.59780 344.26488 152.19780 327.63288 146.79780 332.74488 C -146.79780 337.28088 148.30980 340.30488 149.02980 344.04888 C -154.21380 353.62488 179.55780 393.36888 177.97380 404.02488 C -177.18180 404.02488 176.46180 404.02488 175.74180 404.02488 C -172.50180 400.13688 170.77380 397.18488 165.94980 397.18488 C -161.48580 401.64888 168.97380 410.14488 171.56580 414.17688 C -179.26980 431.45688 190.14180 449.60088 194.17380 467.67288 C -198.34980 473.50488 197.91780 485.24088 205.04580 486.53688 C -205.90980 467.38488 189.92580 438.80088 181.35780 421.66488 C -178.83780 419.14488 179.19780 419.72088 178.76580 415.68888 C -181.71780 416.33688 184.74180 416.98488 187.76580 417.56088 C -188.48580 417.05688 189.20580 416.55288 189.99780 416.04888 C -191.29380 396.46488 165.15780 373.42488 160.69380 352.32888 C -165.30180 354.99288 168.03780 359.52888 173.50980 359.52888 C -175.02180 358.01688 175.02180 358.01688 175.38180 356.14488 C -166.45380 336.92088 159.68580 321.44088 155.43780 300.34488 C -160.90980 303.08088 156.58980 308.91288 165.58980 307.83288 C -165.58980 305.60088 165.58980 303.36888 165.58980 301.06488 C -159.75780 280.61688 156.73380 260.09688 156.22980 238.49688 C -158.60580 239.36088 158.53380 240.94488 159.18180 243.03288 C -161.41380 243.03288 163.64580 243.03288 165.94980 243.03288 C -167.53380 211.42488 170.62980 179.60088 171.99780 147.27288 C -172.57380 147.56088 173.22180 147.84888 173.86980 148.06488 C -175.38180 156.34488 175.38180 156.34488 177.97380 163.11288 C -179.70180 163.11288 181.50180 163.11288 183.30180 163.11288 C -183.44580 155.55288 183.22980 150.65688 181.35780 142.80888 C -182.14980 125.45688 182.86980 124.66488 182.50980 114.87288 C -183.01380 114.87288 183.51780 114.87288 184.02180 114.87288 C -183.58980 104.00088 184.02180 99.75288 188.55780 89.24088 C -194.53380 90.68088 208.35780 129.05688 211.45380 136.76088 C -212.17380 144.03288 211.81380 152.16888 219.73380 145.76088 C -220.30980 140.50488 220.95780 135.24888 221.60580 129.99288 C -222.46980 130.28088 223.33380 130.49688 224.19780 130.71288 C -227.22180 138.27288 230.24580 143.52888 236.22180 160.08888 C -240.54180 168.58488 241.83780 180.75288 248.31780 187.23288 C -248.17380 189.75288 248.02980 192.27288 247.95780 194.79288 C -251.70180 195.15288 251.70180 195.15288 254.72580 194.07288 C -257.02980 188.81688 259.40580 183.56088 261.78180 178.23288 C -262.42980 178.16088 263.07780 178.01688 263.72580 177.87288 C -270.13380 197.96088 269.34180 223.44888 269.34180 243.82488 C -270.85380 247.56888 270.85380 252.10488 272.00580 253.97688 C -279.99780 252.46488 282.73380 238.78488 284.74980 231.00888 C -286.62180 231.72888 286.62180 231.72888 287.41380 233.24088 C -288.34980 262.04088 284.53380 290.98488 285.90180 319.20888 C -287.41380 320.64888 287.41380 320.64888 289.28580 321.08088 C -292.52580 318.48888 296.05380 311.43288 300.51780 310.49688 C -301.95780 318.27288 294.10980 335.98488 291.87780 343.32888 C -288.85380 349.44888 278.77380 368.96088 282.08580 374.21688 C -287.12580 374.57688 290.29380 369.39288 294.90180 370.40088 C -292.66980 377.96088 292.66980 377.96088 289.64580 384.72888 C -280.64580 397.54488 267.10980 413.38488 266.74980 414.89688 C -246.51780 429.87288 232.18980 452.55288 221.24580 473.72088 C -218.22180 477.03288 215.19780 480.27288 212.17380 483.51288 C -210.66180 488.76888 210.66180 488.76888 209.22180 490.28088 C -211.09380 510.51288 215.34180 492.22488 219.73380 488.76888 C -221.10180 480.63288 230.31780 470.04888 233.98980 460.90488 C -249.03780 440.52888 249.03780 440.52888 258.03780 430.73688 C -260.98980 429.65688 276.03780 412.37688 276.46980 410.36088 C -276.97380 410.36088 277.47780 410.36088 277.98180 410.36088 C -277.98180 409.85688 277.98180 409.35288 277.98180 408.84888 C -278.48580 408.84888 278.98980 408.84888 279.49380 408.84888 C -279.56580 408.12888 279.70980 407.40888 279.85380 406.61688 C -290.94180 394.23288 299.29380 382.49688 303.54180 365.14488 C -304.04580 365.14488 304.54980 365.14488 305.05380 365.14488 C -307.21380 360.82488 305.41380 356.50488 300.51780 356.50488 C -297.78180 360.10488 295.26180 362.26488 291.51780 362.91288 C -295.04580 340.80888 308.43780 322.30488 308.43780 297.32088 C -307.93380 296.60088 307.42980 295.88088 306.92580 295.08888 C -306.06180 295.01688 305.19780 294.87288 304.33380 294.72888 C -300.15780 298.83288 297.13380 307.11288 292.30980 307.83288 C -291.87780 298.04088 294.18180 258.08088 294.18180 236.98488 C -293.82180 231.08088 295.76580 212.72088 287.77380 210.99288 C -285.10980 215.16888 285.10980 215.16888 283.23780 220.42488 C -283.81380 220.71288 284.46180 220.92888 285.10980 221.14488 C -284.96580 221.79288 284.82180 222.44088 284.74980 223.08888 C -279.20580 225.39288 278.91780 232.88088 277.98180 237.77688 C -277.18980 237.77688 276.46980 237.77688 275.74980 237.77688 C -274.95780 215.02488 274.38180 188.52888 268.54980 165.41688 C -265.88580 162.60888 265.59780 162.39288 262.21380 162.39288 C -261.78180 165.92088 261.42180 169.44888 261.06180 172.90488 C -255.37380 175.56888 255.80580 176.93688 253.93380 181.61688 C -252.92580 181.76088 251.91780 181.90488 250.90980 181.97688 C -241.54980 157.85688 233.91780 137.69688 230.24580 111.84888 C -224.41380 90.17688 215.55780 70.01688 207.70980 48.56088 C -204.68580 32.00088 204.68580 32.00088 198.63780 6.36888 C -198.34980 -8.96712 198.06180 -23.22312 199.42980 -38.91912 C -202.45380 -46.40712 202.45380 -46.40712 203.53380 -51.30312 C -204.75780 -51.30312 206.05380 -51.30312 207.34980 -51.30312 C -210.44580 -47.48712 209.86980 -46.40712 209.58180 -41.94312 C -212.67780 -39.99912 212.38980 -39.99912 216.70980 -40.43112 C -220.02180 -46.98312 220.45380 -54.18312 225.34980 -61.88712 C -226.42980 -61.74312 227.58180 -61.59912 228.73380 -61.52712 C -231.54180 -54.68712 230.46180 -45.90312 230.60580 -38.91912 C -239.53380 -41.51112 238.95780 -53.60712 247.16580 -53.60712 C -255.94980 -42.66312 244.14180 -32.29512 236.22180 -26.10312 C -229.30980 -11.55912 231.68580 13.49688 240.75780 25.16088 C -253.06980 55.32888 270.13380 81.17688 285.90180 108.82488 C -309.94980 168.44088 309.94980 168.44088 314.41380 181.97688 C -323.34180 215.45688 327.30180 248.64888 330.97380 282.27288 C -335.36580 286.23288 330.39780 325.25688 334.35780 332.38488 C -343.35780 332.38488 338.10180 314.16888 339.97380 306.39288 C -337.02180 261.89688 337.02180 261.89688 334.71780 245.26488 C -329.67780 231.72888 328.23780 216.46488 326.50980 201.56088 C -318.51780 172.68888 307.14180 144.53688 296.41380 116.38488 C -281.36580 88.52088 278.34180 84.70488 269.70180 67.78488 C -269.19780 67.71288 268.69380 67.56888 268.18980 67.42488 C -253.06980 37.47288 235.93380 15.65688 240.75780 -18.54312 C -245.22180 -24.23112 254.14980 -28.83912 256.16580 -37.40712 C -257.89380 -37.26312 259.62180 -37.11912 261.42180 -36.97512 C -264.94980 -41.15112 275.67780 -57.85512 284.38980 -56.19912 C -284.24580 -52.88712 284.10180 -49.64712 284.02980 -46.40712 C -289.57380 -47.41512 293.53380 -48.35112 294.54180 -55.47912 C -295.04580 -55.47912 295.54980 -55.47912 296.05380 -55.47912 C -293.74980 -61.59912 290.86980 -64.04712 285.54180 -68.65512 C -274.09380 -65.34312 266.67780 -52.81512 254.72580 -52.81512 C -250.18980 -60.66312 250.33380 -63.03912 241.18980 -60.73512 C -241.18980 -60.23112 241.18980 -59.72712 241.18980 -59.22312 C -239.67780 -58.71912 238.16580 -58.21512 236.65380 -57.71112 C -234.27780 -63.32712 233.34180 -70.16712 226.14180 -70.16712 C -@c -F - -@rax %Note: Object -298.07433 -67.14312 601.62180 853.66488 @E - 1 O 0 @g -0.00 0.00 0.00 1.00 k -/$fm 0 def -303.54180 -67.14312 m -302.02980 -66.63912 300.51780 -66.13512 299.07780 -65.63112 C -297.92580 -63.03912 297.92580 -63.03912 298.28580 -58.86312 C -300.01380 -58.86312 301.74180 -58.86312 303.54180 -58.86312 C -307.50180 -54.90312 306.70980 -44.53512 306.20580 -39.63912 C -311.10180 -39.27912 311.10180 -39.27912 314.05380 -40.43112 C -320.82180 -51.30312 322.69380 -52.45512 323.84580 -55.11912 C -327.30180 -54.97512 330.82980 -54.83112 334.35780 -54.75912 C -334.35780 -53.75112 334.35780 -52.74312 334.35780 -51.73512 C -334.86180 -51.73512 335.36580 -51.73512 335.86980 -51.73512 C -337.02180 -47.19912 337.02180 -47.19912 337.02180 -44.17512 C -327.80580 -25.67112 327.44580 -15.66312 330.25380 3.34488 C -332.34180 8.96088 337.16580 16.08888 338.17380 21.41688 C -338.74980 21.70488 339.32580 21.92088 339.97380 22.13688 C -346.38180 37.68888 373.66980 51.36888 389.29380 57.20088 C -406.57380 69.87288 430.47780 82.11288 444.51780 98.31288 C -454.38180 105.65688 464.31780 113.14488 470.43780 123.94488 C -483.39780 133.95288 486.99780 162.24888 488.86980 178.23288 C -482.38980 195.80088 481.30980 201.92088 463.66980 206.52888 C -442.64580 206.52888 442.64580 206.52888 441.92580 205.73688 C -427.74180 200.55288 413.19780 196.66488 399.80580 190.68888 C -390.22980 183.20088 380.72580 175.64088 371.22180 168.08088 C -364.52580 159.51288 354.22980 131.28888 347.89380 130.35288 C -345.30180 132.94488 346.23780 134.60088 346.02180 137.48088 C -354.87780 167.43288 364.52580 198.24888 369.34980 228.70488 C -381.44580 270.10488 388.86180 308.91288 390.37380 351.60888 C -388.86180 373.42488 388.86180 373.42488 384.39780 409.64088 C -383.60580 411.15288 382.88580 417.92088 381.37380 420.94488 C -380.58180 425.48088 379.86180 426.20088 373.81380 456.36888 C -370.86180 464.64888 364.81380 475.95288 358.83780 489.56088 C -357.03780 501.72888 349.69380 514.11288 345.66180 524.98488 C -344.65380 524.98488 343.64580 524.98488 342.63780 524.98488 C -342.27780 528.00888 340.76580 529.52088 339.25380 533.26488 C -338.60580 536.79288 337.95780 540.32088 337.38180 543.84888 C -336.87780 543.84888 336.37380 543.84888 335.86980 543.84888 C -332.77380 559.97688 327.80580 575.81688 324.99780 591.29688 C -321.32580 630.10488 322.76580 667.40088 323.48580 705.92088 C -327.94980 740.55288 327.94980 740.55288 329.46180 744.36888 C -331.33380 745.16088 333.20580 745.88088 335.14980 746.60088 C -336.44580 742.85688 334.28580 731.98488 332.48580 728.52888 C -328.95780 684.89688 327.44580 639.46488 331.76580 595.11288 C -335.36580 576.75288 339.75780 557.74488 345.66180 539.31288 C -346.23780 539.09688 346.88580 538.80888 347.53380 538.52088 C -349.40580 530.09688 353.86980 523.11288 357.32580 514.40088 C -358.18980 514.18488 359.05380 513.96888 359.91780 513.68088 C -365.89380 545.43288 375.18180 574.88088 382.88580 605.62488 C -401.53380 651.27288 424.42980 692.74488 448.26180 736.01688 C -458.12580 763.37688 472.38180 786.70488 476.84580 815.93688 C -476.84580 828.60888 479.58180 841.92888 482.46180 853.66488 C -484.47780 853.66488 486.49380 853.66488 488.50980 853.66488 C -488.43780 834.94488 486.13380 815.36088 490.38180 796.35288 C -493.26180 789.72888 496.14180 783.10488 499.02180 776.40888 C -507.44580 777.41688 514.14180 809.96088 526.09380 807.29688 C -527.24580 805.42488 527.24580 805.42488 528.68580 798.58488 C -528.25380 776.55288 526.81380 759.12888 533.65380 737.52888 C -534.58980 737.67288 535.59780 737.81688 536.60580 737.96088 C -542.22180 746.60088 542.22180 746.60088 552.80580 766.18488 C -555.39780 767.33688 555.39780 767.33688 558.42180 767.33688 C -560.29380 765.46488 560.43780 756.53688 558.78180 753.36888 C -560.14980 737.67288 562.88580 723.27288 565.98180 707.43288 C -566.41380 707.43288 566.91780 707.43288 567.42180 707.43288 C -567.78180 704.40888 568.57380 703.61688 572.31780 692.31288 C -577.57380 664.44888 579.08580 660.63288 582.10980 642.56088 C -585.13380 631.25688 588.08580 615.41688 589.59780 611.67288 C -596.79780 564.80088 599.96580 516.05688 601.62180 467.67288 C -598.74180 428.57688 594.06180 394.52088 585.85380 356.14488 C -581.31780 341.81688 579.87780 340.30488 573.82980 321.44088 C -555.82980 286.30488 540.78180 254.48088 516.66180 222.65688 C -508.52580 217.97688 501.32580 198.68088 493.04580 196.30488 C -492.61380 194.28888 492.25380 192.27288 491.89380 190.25688 C -492.90180 188.02488 493.90980 185.79288 494.91780 183.48888 C -496.28580 148.49688 481.45380 117.60888 452.43780 96.44088 C -426.80580 70.80888 395.05380 55.11288 364.81380 36.46488 C -364.45380 35.88888 364.09380 35.24088 363.73380 34.59288 C -342.70980 24.87288 336.66180 4.78488 335.50980 -17.03112 C -341.55780 -32.94312 352.06980 -51.66312 333.63780 -64.11912 C -322.83780 -64.11912 320.60580 -52.88712 314.05380 -51.73512 C -313.26180 -57.99912 312.10980 -67.14312 303.54180 -67.14312 C -@c -F - -@rax %Note: Object -541.14180 -56.55912 585.85380 -26.96088 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -570.44580 -56.55912 m -563.46180 -53.24712 556.11780 -54.68712 552.44580 -47.91912 C -551.94180 -47.91912 551.43780 -47.91912 550.93380 -47.91912 C -547.26180 -39.20712 540.42180 -37.55112 541.14180 -27.18312 C -559.35780 -25.95912 558.78180 -29.70312 574.18980 -40.43112 C -577.35780 -44.96712 579.73380 -50.07912 585.49380 -52.81512 C -585.56580 -53.46312 585.70980 -54.11112 585.85380 -54.75912 C -583.26180 -55.11912 580.23780 -53.60712 574.18980 -53.96712 C -573.90180 -54.83112 573.68580 -55.69512 573.46980 -56.55912 C -572.46180 -56.55912 571.45380 -56.55912 570.44580 -56.55912 C -@c -F - -@rax %Note: Object -598.30980 -56.55912 637.40580 -21.56712 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -602.77380 -56.55912 m -601.26180 -56.41512 599.74980 -56.27112 598.30980 -56.19912 C -599.82180 -48.35112 607.95780 -48.63912 614.07780 -44.53512 C -618.90180 -36.90312 629.98980 -23.79912 637.40580 -21.56712 C -635.82180 -34.02312 633.87780 -42.37512 624.58980 -50.58312 C -612.56580 -53.60712 605.79780 -56.55912 602.77380 -56.55912 C -@c -F - -@rax %Note: Object --189.56041 -47.56365 -38.17020 169.95288 @E - 1 O 0 @g -0.00 0.00 0.00 1.00 k -/$fm 0 def --111.46620 -47.55912 m --128.09820 -39.13512 -147.17820 -16.16712 -147.17820 2.55288 C --140.19420 11.33688 -142.42620 15.65688 -129.46620 11.98488 C --126.51420 9.96888 -106.42620 -5.72712 -103.90620 -5.72712 C --103.90620 -6.44712 -103.90620 -7.16712 -103.90620 -7.95912 C --98.93820 -11.48712 -95.91420 -15.59112 -91.88220 -21.13512 C --91.01820 -20.99112 -90.15420 -20.84712 -89.29020 -20.77512 C --90.73020 17.67288 -95.98620 41.64888 -120.10620 71.88888 C --120.75420 72.17688 -121.40220 72.46488 -121.97820 72.68088 C --121.97820 73.18488 -121.97820 73.68888 -121.97820 74.19288 C --122.98620 74.19288 -123.99420 74.19288 -125.00220 74.19288 C --128.31420 62.02488 -131.12220 48.20088 -146.02620 48.20088 C --155.53020 54.17688 -156.82620 67.49688 -155.02620 77.21688 C --164.09820 76.35288 -177.56220 44.96088 -189.29820 60.58488 C --190.30620 82.25688 -189.44220 95.07288 -172.37820 109.97688 C --172.30620 110.91288 -172.16220 111.77688 -172.01820 112.64088 C --188.43420 129.48888 -190.16220 134.16888 -186.63420 157.13688 C --185.91420 157.49688 -185.19420 157.85688 -184.40220 158.21688 C --179.79420 172.11288 -168.70620 168.87288 -158.05020 163.54488 C --157.33020 161.60088 -150.92220 156.34488 -150.56220 154.83288 C --149.55420 154.97688 -148.54620 155.12088 -147.53820 155.26488 C --142.85820 161.88888 -136.01820 162.17688 -133.28220 169.95288 C --112.76220 169.01688 -117.44220 150.00888 -120.89820 135.24888 C --120.75420 133.73688 -120.61020 132.22488 -120.46620 130.71288 C --87.05820 139.13688 -95.77020 106.80888 -106.57020 87.72888 C --110.53020 84.27288 -112.69020 83.26488 -117.44220 81.75288 C --115.42620 71.88888 -107.36220 66.48888 -102.39420 56.84088 C --92.89020 53.31288 -84.17820 2.62488 -82.52220 -6.44712 C --81.65820 -6.51912 -80.79420 -6.66312 -79.85820 -6.80712 C --69.99420 3.05688 -64.23420 16.66488 -52.06620 24.80088 C --42.34620 34.52088 -41.98620 32.50488 -38.17020 19.90488 C --38.17020 -14.36712 -48.53820 -36.83112 -85.11420 -42.30312 C --95.12220 -47.91912 -100.81020 -47.55912 -111.46620 -47.55912 C -@c -F - -@rax %Note: Object -588.87780 -47.55912 627.61380 15.36888 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -590.74980 -47.55912 m -590.10180 -47.12712 589.45380 -46.76712 588.87780 -46.40712 C -588.87780 -37.62312 595.42980 -24.01512 599.38980 -17.03112 C -599.53380 -16.81512 619.54980 13.92888 627.61380 15.36888 C -626.38980 4.42488 602.70180 -47.55912 590.74980 -47.55912 C -@c -F - -@rax %Note: Object --139.86539 -40.79112 -93.03420 6.00888 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def --106.21020 -40.79112 m --121.61820 -36.83112 -128.67420 -23.43912 -137.38620 -11.77512 C --138.68220 -4.14312 -143.29020 0.39288 -135.51420 6.00888 C --126.94620 6.00888 -99.94620 -15.08712 -98.65020 -24.59112 C --93.82620 -27.83112 -94.40220 -31.28712 -93.03420 -37.40712 C --94.18620 -38.48712 -99.44220 -39.99912 -106.21020 -40.79112 C -@c -F - -@rax %Note: Object --81.37020 -33.23112 -44.62016 20.62488 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def --77.62620 -33.23112 m --78.92220 -32.72712 -80.14620 -32.22312 -81.37020 -31.71912 C --83.60220 -18.25512 -57.89820 18.39288 -45.29820 20.62488 C --41.84220 -1.04712 -51.41820 -33.23112 -77.62620 -33.23112 C -@c -F - -@rax %Note: Object -629.12580 -17.39112 637.40580 -7.95912 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -630.63780 -17.39112 m -629.48580 -16.31112 629.48580 -16.31112 629.12580 -14.00712 C -632.94180 -12.56712 632.79780 -8.75112 637.40580 -7.95912 C -635.38980 -11.99112 633.80580 -14.22312 630.63780 -17.39112 C -@c -F - -@rax %Note: Object -506.97326 6.00888 539.26980 55.32888 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -509.53380 6.00888 m -498.73380 12.70488 521.55780 53.60088 533.65380 55.32888 C -534.73380 50.79288 536.31780 48.56088 539.26980 44.02488 C -537.68580 32.57688 522.99780 6.00888 509.53380 6.00888 C -@c -F - -@rax %Note: Object -543.60794 8.96088 557.79506 45.17688 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -547.18980 8.96088 m -543.80580 18.10488 540.78180 38.04888 547.90980 45.17688 C -549.49380 45.03288 551.14980 44.88888 552.80580 44.74488 C -552.87780 44.31288 553.02180 43.80888 553.16580 43.30488 C -554.17380 43.08888 555.18180 42.80088 556.18980 42.51288 C -560.22180 31.20888 556.26180 18.68088 549.42180 8.96088 C -548.62980 8.96088 547.90980 8.96088 547.18980 8.96088 C -@c -F - -@rax %Note: Object -188.91780 12.34488 223.83780 123.15288 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -191.50980 12.34488 m -189.42180 32.00088 188.91780 50.28888 188.91780 69.65688 C -193.81380 75.56088 193.81380 77.28888 194.89380 84.70488 C -201.37380 96.80088 206.41380 110.98488 212.96580 122.43288 C -213.82980 122.72088 214.69380 122.93688 215.62980 123.15288 C -216.42180 121.06488 216.49380 121.35288 219.37380 120.12888 C -218.22180 117.89688 218.22180 117.89688 218.22180 113.36088 C -220.09380 111.48888 220.38180 110.76888 223.83780 110.33688 C -214.26180 85.35288 203.24580 59.36088 198.63780 32.72088 C -195.39780 29.48088 195.68580 21.27288 195.68580 16.16088 C -195.03780 15.94488 194.38980 15.65688 193.81380 15.36888 C -193.52580 14.50488 193.23780 13.64088 193.02180 12.77688 C -192.51780 12.63288 192.01380 12.48888 191.50980 12.34488 C -@c -F - -@rax %Note: Object -699.67219 12.77688 716.67780 40.64088 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -700.54980 12.77688 m -697.38180 15.72888 703.35780 27.96888 704.65380 32.00088 C -708.39780 36.17688 709.83780 39.92088 715.59780 40.64088 C -715.95780 35.52888 716.31780 30.34488 716.67780 25.16088 C -711.78180 20.55288 706.95780 14.14488 700.54980 12.77688 C -@c -F - -@rax %Note: Object -724.59780 27.82488 753.30454 57.27969 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -728.34180 27.82488 m -727.04580 28.25688 725.82180 28.61688 724.59780 28.97688 C -727.18980 37.97688 727.98180 38.76888 728.34180 41.79288 C -727.69380 42.08088 727.04580 42.29688 726.46980 42.51288 C -726.46980 43.30488 726.46980 44.02488 726.46980 44.74488 C -736.69380 52.23288 737.55780 60.94488 753.18180 55.76088 C -755.55780 42.58488 740.72580 27.82488 728.34180 27.82488 C -@c -F - -@rax %Note: Object -678.83386 34.59288 711.42180 59.81074 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -680.24580 34.59288 m -674.98980 39.84888 685.14180 50.14488 687.73380 54.24888 C -699.68580 60.94488 699.03780 62.02488 711.42180 55.32888 C -711.42180 42.51288 689.67780 34.59288 680.24580 34.59288 C -@c -F - -@rax %Note: Object -719.07591 48.20088 727.83128 59.07288 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -719.34180 48.20088 m -718.90980 53.81688 718.90980 53.81688 720.06180 59.07288 C -727.62180 58.71288 730.28580 58.92888 725.31780 51.22488 C -720.85380 48.20088 720.85380 48.20088 719.34180 48.20088 C -@c -F - -@rax %Note: Object -557.36759 50.79288 593.94898 88.52088 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -558.42180 50.79288 m -555.54180 56.62488 559.35780 65.84088 560.29380 71.16888 C -570.22980 81.10488 576.06180 89.38488 591.54180 88.52088 C -601.98180 73.76088 578.36580 56.62488 565.98180 51.22488 C -563.46180 51.08088 560.94180 50.93688 558.42180 50.79288 C -@c -F - -@rax %Note: Object -540.92665 51.58488 551.95087 69.33402 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -541.86180 51.58488 m -540.78180 56.84088 540.78180 56.84088 541.14180 59.50488 C -541.71780 59.86488 542.36580 60.22488 543.01380 60.58488 C -543.22980 62.88888 543.44580 65.19288 543.73380 67.42488 C -555.61380 76.28088 554.38980 52.73688 541.86180 51.58488 C -@c -F - -@rax %Note: Object -488.86980 54.24888 525.73380 75.31569 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -496.78980 54.24888 m -492.75780 56.12088 490.81380 56.98488 488.86980 59.86488 C -488.86980 72.96888 502.11780 78.15288 513.34980 73.83288 C -517.16580 68.93688 519.25380 65.33688 525.73380 62.88888 C -524.94180 58.71288 501.68580 54.24888 496.78980 54.24888 C -@c -F - -@rax %Note: Object --148.92803 55.76088 -131.77020 92.92195 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def --145.30620 55.76088 m --145.81020 55.90488 -146.31420 56.04888 -146.81820 56.12088 C --150.41820 68.28888 -149.05020 78.72888 -145.66620 90.03288 C --141.63420 92.55288 -138.03420 95.72088 -137.02620 88.52088 C --136.52220 88.52088 -136.01820 88.52088 -135.51420 88.52088 C --130.25820 81.03288 -129.53820 60.58488 -139.25820 55.76088 C --141.27420 55.76088 -143.29020 55.76088 -145.30620 55.76088 C -@c -F - -@rax %Note: Object --184.04220 63.24888 -154.66620 105.08088 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def --182.89020 63.24888 m --183.32220 63.89688 -183.68220 64.54488 -184.04220 65.12088 C --184.04220 83.04888 -181.16220 106.30488 -158.48220 105.08088 C --157.69020 100.54488 -156.17820 98.31288 -154.66620 90.03288 C --160.06620 82.11288 -173.89020 63.24888 -182.89020 63.24888 C -@c -F - -@rax %Note: Object -726.10980 64.04088 761.46180 97.16088 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -731.36580 64.04088 m -729.85380 65.55288 729.85380 65.55288 726.10980 66.63288 C -734.53380 86.00088 738.70980 95.00088 761.46180 97.16088 C -762.39780 85.92888 740.36580 64.04088 731.36580 64.04088 C -@c -F - -@rax %Note: Object -701.93367 66.63288 726.32353 97.52088 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -714.80580 66.63288 m -714.80580 67.13688 714.80580 67.64088 714.80580 68.14488 C -711.99780 68.07288 709.26180 67.92888 706.52580 67.78488 C -694.86180 84.92088 706.81380 98.45688 724.95780 97.52088 C -728.12580 89.81688 725.74980 83.26488 719.70180 77.21688 C -718.98180 73.68888 718.62180 68.28888 714.80580 66.63288 C -@c -F - -@rax %Note: Object -514.93266 70.01688 535.14000 103.06035 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -533.65380 70.01688 m -516.73380 80.31288 510.75780 83.19288 517.81380 102.05688 C -521.55780 103.20888 521.55780 103.20888 530.19780 102.84888 C -536.10180 92.40888 535.38180 82.97688 534.73380 70.37688 C -534.37380 70.30488 534.01380 70.16088 533.65380 70.01688 C -@c -F - -@rax %Note: Object -651.61899 74.55288 671.53380 110.33688 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -654.68580 74.55288 m -653.67780 74.69688 652.66980 74.84088 651.66180 74.91288 C -651.51780 89.88888 651.30180 97.80888 658.42980 110.33688 C -659.65380 110.33688 660.87780 110.33688 662.17380 110.33688 C -662.46180 105.51288 666.63780 104.36088 671.53380 102.05688 C -670.45380 89.31288 664.69380 84.77688 656.19780 74.55288 C -655.69380 74.55288 655.18980 74.55288 654.68580 74.55288 C -@c -F - -@rax %Note: Object -544.45153 76.85688 568.13386 119.04888 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -550.14180 76.85688 m -549.63780 77.36088 549.13380 77.86488 548.62980 78.36888 C -547.33380 78.22488 546.10980 78.08088 544.88580 77.93688 C -543.08580 96.22488 546.10980 107.31288 561.44580 119.04888 C -562.45380 119.04888 563.46180 119.04888 564.46980 119.04888 C -574.54980 108.96888 561.87780 76.85688 550.14180 76.85688 C -@c -F - -@rax %Note: Object --133.33408 89.67288 -102.20400 126.60888 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def --119.74620 89.67288 m --134.07420 91.25688 -135.15420 102.99288 -131.77020 115.30488 C --122.12220 122.14488 -117.80220 126.60888 -105.41820 126.60888 C --97.57020 116.16888 -105.56220 101.26488 -110.31420 90.75288 C --113.69820 89.67288 -113.69820 89.67288 -119.74620 89.67288 C -@c -F - -@rax %Note: Object -580.23780 90.75288 584.77380 93.05688 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -580.23780 90.75288 m -580.23780 91.54488 580.23780 92.33688 580.23780 93.05688 C -581.74980 92.98488 583.26180 92.84088 584.77380 92.69688 C -583.26180 92.04888 581.74980 91.40088 580.23780 90.75288 C -@c -F - -@rax %Note: Object -619.22239 92.69688 651.30180 125.09688 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -620.84580 92.69688 m -614.72580 102.56088 626.24580 119.33688 633.58980 125.09688 C -638.84580 125.09688 639.63780 124.30488 650.94180 123.94488 C -650.50980 117.17688 651.30180 115.66488 651.30180 113.36088 C -642.87780 105.65688 632.00580 94.06488 620.84580 92.69688 C -@c -F - -@rax %Note: Object --152.07420 97.95288 -138.89820 120.81515 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def --148.25820 97.95288 m --149.05020 98.31288 -149.84220 98.67288 -150.56220 99.03288 C --150.56220 99.53688 -150.56220 100.04088 -150.56220 100.54488 C --151.06620 100.54488 -151.57020 100.54488 -152.07420 100.54488 C --152.00220 106.01688 -150.41820 129.41688 -138.89820 117.89688 C --138.89820 111.84888 -139.97820 97.95288 -148.25820 97.95288 C -@c -F - -@rax %Note: Object -668.58180 110.76888 708.03780 145.07943 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -672.68580 110.76888 m -671.31780 111.63288 669.94980 112.49688 668.58180 113.36088 C -668.58180 118.54488 672.10980 120.41688 675.34980 123.94488 C -678.15780 136.40088 691.04580 146.55288 704.29380 145.04088 C -705.08580 142.66488 704.86980 142.16088 708.03780 140.50488 C -704.50980 120.41688 691.98180 113.93688 672.68580 110.76888 C -@c -F - -@rax %Note: Object --183.02854 116.81688 -152.93820 161.29474 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def --167.12220 116.81688 m --180.44220 127.32888 -186.49020 138.92088 -181.01820 154.83288 C --174.03420 163.47288 -170.21820 162.17688 -160.35420 158.57688 C --160.35420 158.14488 -160.35420 157.64088 -160.35420 157.13688 C --148.83420 149.00088 -153.73020 135.89688 -155.45820 123.15288 C --159.77820 119.69688 -161.72220 116.81688 -167.12220 116.81688 C -@c -F - -@rax %Note: Object -659.14980 119.04888 668.26687 128.48088 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -659.14980 119.04888 m -658.64580 125.24088 662.82180 127.54488 668.22180 128.48088 C -668.43780 124.23288 667.93380 123.72888 665.55780 119.40888 C -663.39780 119.33688 661.23780 119.19288 659.14980 119.04888 C -@c -F - -@rax %Note: Object --144.71291 122.79288 -122.98989 162.75288 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def --134.72220 122.79288 m --138.10620 125.60088 -140.62620 127.25688 -144.51420 126.17688 C --144.15420 144.39288 -147.97020 150.65688 -134.00220 162.75288 C --114.05820 162.75288 -126.08220 134.38488 -130.97820 123.58488 C --132.49020 122.79288 -132.49020 122.79288 -134.72220 122.79288 C -@c -F - -@rax %Note: Object -665.14394 133.73688 696.37380 175.20888 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -665.91780 133.73688 m -665.48580 143.16888 662.89380 150.65688 670.09380 157.85688 C -671.31780 163.11288 683.91780 172.11288 688.52580 174.84888 C -690.97380 174.99288 693.49380 175.13688 696.01380 175.20888 C -696.08580 172.47288 696.22980 169.73688 696.37380 166.92888 C -692.62980 159.36888 674.98980 135.96888 665.91780 133.73688 C -@c -F - -@rax %Note: Object -636.69175 135.60888 655.88287 167.28888 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -638.84580 135.60888 m -634.02180 140.43288 638.41380 156.77688 640.35780 162.39288 C -644.96580 164.04888 645.25380 167.28888 652.38180 167.28888 C -656.91780 162.75288 657.06180 142.59288 652.74180 135.96888 C -648.06180 135.89688 643.45380 135.75288 638.84580 135.60888 C -@c -F - -@rax %Note: Object -694.14180 147.70488 699.03780 151.80888 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -694.50180 147.70488 m -694.35780 148.85688 694.21380 150.00888 694.14180 151.08888 C -695.22180 151.37688 696.37380 151.59288 697.52580 151.80888 C -697.52580 151.30488 697.52580 150.80088 697.52580 150.29688 C -698.02980 150.29688 698.53380 150.29688 699.03780 150.29688 C -698.74980 149.72088 698.46180 149.07288 698.24580 148.42488 C -696.94980 148.20888 695.72580 147.99288 694.50180 147.70488 C -@c -F - -@rax %Note: Object -363.73380 173.69688 594.13380 799.37688 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -363.73380 173.69688 m -364.81380 180.46488 370.86180 203.07288 376.83780 231.00888 C -377.62980 231.72888 380.58180 242.31288 381.37380 243.03288 C -388.42980 277.59288 394.98180 310.78488 397.93380 345.56088 C -397.93380 357.65688 397.14180 359.09688 397.14180 367.44888 C -391.16580 413.38488 391.16580 413.38488 390.37380 414.17688 C -387.27780 428.14488 383.38980 442.18488 381.73380 455.64888 C -381.22980 455.64888 380.72580 455.64888 380.22180 455.64888 C -379.06980 462.41688 376.11780 469.18488 372.73380 482.79288 C -372.22980 482.79288 371.72580 482.79288 371.22180 482.79288 C -369.78180 488.33688 368.41380 493.88088 367.04580 499.35288 C -365.74980 522.24888 371.22180 547.44888 378.70980 568.32888 C -379.28580 568.25688 379.93380 568.11288 380.58180 567.96888 C -382.52580 555.94488 384.25380 532.25688 398.29380 526.85688 C -416.29380 526.85688 428.74980 537.72888 443.36580 547.95288 C -444.37380 548.09688 445.38180 548.24088 446.38980 548.31288 C -446.74980 547.59288 447.10980 546.87288 447.54180 546.08088 C -448.18980 527.43288 444.30180 464.28888 473.46180 464.28888 C -484.40580 472.35288 489.80580 482.21688 499.02180 491.43288 C -499.88580 491.36088 500.74980 491.21688 501.68580 491.07288 C -501.68580 479.26488 501.68580 467.45688 501.68580 455.64888 C -503.62980 446.21688 505.14180 430.52088 514.78980 424.32888 C -533.72580 424.32888 535.09380 444.48888 550.14180 446.57688 C -552.80580 426.20088 552.80580 426.20088 553.52580 412.66488 C -558.06180 400.20888 568.28580 389.19288 582.10980 399.84888 C -582.10980 405.60888 575.12580 403.44888 571.23780 403.59288 C -570.80580 404.38488 570.44580 405.17688 570.08580 405.89688 C -567.70980 406.18488 565.33380 406.40088 562.95780 406.61688 C -558.42180 421.08888 558.13380 435.20088 556.54980 449.60088 C -553.88580 452.98488 552.44580 453.34488 552.44580 454.85688 C -541.35780 452.62488 536.46180 446.28888 529.47780 438.29688 C -525.51780 435.27288 521.77380 431.16888 517.09380 431.16888 C -501.97380 449.96088 511.54980 482.93688 506.58180 504.60888 C -489.51780 503.96088 486.27780 471.84888 466.69380 471.84888 C -457.62180 480.92088 455.89380 512.24088 455.02980 523.47288 C -455.02980 533.26488 455.24580 549.03288 451.64580 557.38488 C -450.13380 557.52888 448.62180 557.67288 447.18180 557.74488 C -433.71780 551.33688 410.60580 528.22488 396.78180 535.13688 C -386.98980 553.20888 386.62980 568.25688 386.62980 588.27288 C -398.36580 638.45688 425.07780 681.44088 449.77380 726.22488 C -452.00580 732.27288 455.02980 736.80888 467.05380 762.44088 C -471.44580 774.75288 475.83780 787.06488 480.22980 799.37688 C -480.94980 799.37688 481.66980 799.37688 482.46180 799.37688 C -491.10180 775.97688 491.10180 775.97688 495.63780 766.18488 C -496.78980 765.10488 496.78980 765.10488 500.17380 765.46488 C -506.50980 775.54488 514.35780 784.90488 519.32580 795.63288 C -520.33380 795.63288 521.34180 795.63288 522.34980 795.63288 C -522.27780 785.91288 517.59780 728.88888 536.60580 728.88888 C -539.62980 731.91288 539.62980 731.91288 549.42180 748.47288 C -550.28580 748.40088 551.14980 748.25688 552.01380 748.11288 C -552.80580 746.60088 552.80580 746.60088 554.24580 728.52888 C -562.09380 698.00088 570.66180 668.62488 576.06180 636.51288 C -588.37380 596.69688 589.59780 550.11288 594.13380 508.35288 C -593.34180 506.12088 593.34180 506.12088 594.13380 462.41688 C -589.16580 405.24888 584.19780 356.21688 557.26980 304.88088 C -549.56580 283.92888 537.10980 267.87288 527.24580 247.56888 C -526.30980 247.06488 525.44580 246.56088 524.58180 246.05688 C -523.93380 236.48088 501.54180 217.68888 494.55780 206.52888 C -493.54980 206.16888 492.54180 205.80888 491.53380 205.37688 C -491.24580 204.29688 490.95780 203.14488 490.74180 201.99288 C -489.22980 201.20088 489.22980 201.20088 485.48580 201.56088 C -473.38980 217.90488 461.94180 215.45688 443.36580 214.01688 C -434.29380 211.42488 427.88580 209.69688 420.10980 205.01688 C -396.27780 205.01688 384.46980 179.60088 363.73380 173.69688 C -@c -F - -@rax %Note: Object --27.22620 483.15288 195.36180 602.63660 @E - 1 O 0 @g -0.00 0.00 0.00 1.00 k -/$fm 0 def -41.17380 483.15288 m -28.42980 484.80888 15.75780 488.33688 5.46180 494.81688 C -5.17380 497.26488 -3.32220 500.57688 -5.41020 502.01688 C --8.14620 507.20088 -12.17820 508.56888 -13.69020 512.88888 C --14.69820 513.32088 -15.70620 513.68088 -16.71420 514.04088 C --18.51420 521.31288 -28.16220 522.68088 -27.22620 533.62488 C --24.27420 535.92888 -24.27420 535.92888 -22.76220 535.92888 C --19.09020 532.25688 -16.64220 520.80888 -9.94620 518.93688 C --7.42620 513.68088 5.60580 506.04888 6.61380 502.37688 C -11.86980 499.71288 11.86980 499.71288 22.38180 496.32888 C -22.38180 495.82488 22.38180 495.32088 22.38180 494.81688 C -42.68580 491.43288 42.68580 491.43288 49.45380 491.43288 C -50.96580 492.22488 69.75780 494.45688 93.80580 498.99288 C -97.04580 501.29688 100.28580 503.52888 103.59780 505.76088 C -113.24580 507.41688 132.90180 522.96888 137.79780 530.24088 C -149.24580 539.38488 155.79780 556.44888 160.33380 569.48088 C -160.18980 575.24088 160.04580 581.00088 159.97380 586.76088 C -160.54980 587.04888 161.19780 587.33688 161.84580 587.55288 C -161.91780 588.56088 162.06180 589.56888 162.20580 590.57688 C -161.41380 590.57688 160.69380 590.57688 159.97380 590.57688 C -158.31780 595.32888 157.09380 597.41688 158.02980 601.88088 C -159.18180 602.02488 160.33380 602.16888 161.48580 602.24088 C -171.63780 596.26488 182.58180 604.47288 194.53380 602.24088 C -195.61380 599.57688 195.54180 598.56888 194.89380 595.11288 C -185.24580 594.03288 175.38180 593.67288 166.74180 590.57688 C -167.17380 560.98488 161.62980 547.16088 141.54180 523.47288 C -141.39780 522.75288 141.25380 521.96088 141.18180 521.16888 C -157.23780 523.47288 169.69380 532.11288 180.99780 543.48888 C -183.01380 543.63288 185.02980 543.77688 187.04580 543.84888 C -187.04580 543.34488 187.04580 542.84088 187.04580 542.33688 C -187.54980 542.33688 188.05380 542.33688 188.55780 542.33688 C -186.97380 530.81688 155.58180 517.78488 146.43780 513.32088 C -143.98980 513.46488 141.61380 513.60888 139.23780 513.68088 C -138.87780 515.48088 138.51780 517.20888 138.15780 518.93688 C -130.59780 516.70488 129.37380 509.86488 121.59780 507.27288 C -98.70180 490.35288 68.89380 483.15288 41.17380 483.15288 C -@c -F - -@rax %Note: Object --72.73020 540.46488 248.32205 910.38784 @E - 1 O 0 @g -0.00 0.00 0.00 1.00 k -/$fm 0 def --45.29820 540.46488 m --47.60220 540.96888 -49.83420 541.47288 -52.06620 541.97688 C --66.61020 549.10488 -69.77820 554.50488 -72.73020 569.48088 C --69.85020 596.98488 -42.77820 613.40088 -26.14620 585.24888 C --25.06620 582.00888 -23.91420 578.76888 -22.76220 575.45688 C --8.65020 576.46488 6.90180 589.35288 18.63780 596.98488 C -30.87780 608.64888 58.81380 634.71288 58.81380 653.14488 C -56.50980 655.95288 54.27780 658.68888 52.04580 661.42488 C -50.24580 677.76888 50.96580 688.49688 54.27780 703.61688 C -57.01380 707.72088 57.94980 708.87288 56.22180 712.68888 C -55.71780 712.68888 55.21380 712.68888 54.70980 712.68888 C -53.34180 720.75288 49.66980 727.52088 55.42980 733.42488 C -56.94180 733.06488 58.45380 732.70488 59.96580 732.27288 C -61.62180 739.47288 62.12580 740.26488 67.81380 744.36888 C -66.66180 752.07288 62.62980 751.85688 58.45380 756.03288 C -54.78180 761.14488 53.12580 763.73688 48.66180 766.61688 C -33.32580 785.33688 13.45380 808.37688 5.46180 830.26488 C -3.94980 838.54488 3.15780 850.64088 0.20580 866.48088 C -1.28580 881.31288 6.03780 894.99288 7.69380 908.67288 C -11.29380 912.27288 14.38980 909.39288 18.63780 907.59288 C -29.94180 905.79288 40.16580 903.63288 51.68580 900.03288 C -52.69380 897.00888 74.43780 889.37688 79.54980 888.29688 C -79.54980 887.79288 79.54980 887.28888 79.54980 886.78488 C -80.26980 886.78488 80.98980 886.78488 81.78180 886.78488 C -81.78180 886.28088 81.78180 885.77688 81.78180 885.27288 C -84.66180 884.19288 90.70980 879.08088 90.06180 874.40088 C -84.01380 875.40888 84.08580 878.79288 80.26980 881.16888 C -68.74980 882.60888 58.74180 890.02488 47.94180 892.83288 C -47.94180 893.33688 47.94180 893.84088 47.94180 894.34488 C -36.27780 897.15288 25.04580 900.46488 13.74180 899.60088 C -12.22980 894.34488 11.43780 893.62488 11.07780 891.32088 C -17.70180 889.08888 31.38180 881.74488 33.68580 873.96888 C -34.54980 873.75288 35.41380 873.53688 36.27780 873.24888 C -36.34980 871.95288 43.47780 862.30488 46.06980 861.15288 C -46.14180 860.43288 46.28580 859.71288 46.42980 858.92088 C -47.00580 858.70488 47.65380 858.48888 48.30180 858.20088 C -62.19780 838.76088 69.10980 816.51288 78.03780 793.76088 C -78.54180 793.61688 79.04580 793.47288 79.54980 793.32888 C -83.00580 809.38488 85.45380 817.01688 93.37380 831.05688 C -100.93380 840.05688 100.93380 840.05688 101.29380 841.56888 C -87.39780 840.92088 80.62980 835.59288 80.62980 850.64088 C -92.65380 864.96888 92.65380 864.96888 98.70180 870.94488 C -113.60580 881.96088 125.12580 885.63288 143.41380 889.08888 C -143.41380 889.88088 143.41380 890.60088 143.41380 891.32088 C -142.62180 891.32088 141.90180 891.32088 141.18180 891.32088 C -141.18180 891.82488 141.18180 892.32888 141.18180 892.83288 C -140.53380 893.12088 139.88580 893.40888 139.23780 893.62488 C -139.45380 894.92088 139.74180 896.14488 140.02980 897.36888 C -166.59780 907.08888 193.88580 913.92888 222.39780 905.28888 C -229.09380 899.24088 229.09380 899.24088 230.60580 898.88088 C -231.82980 895.92888 231.68580 894.34488 235.14180 892.47288 C -235.50180 890.60088 235.86180 888.72888 236.22180 886.78488 C -236.86980 886.56888 237.51780 886.35288 238.16580 886.06488 C -238.02180 884.55288 237.87780 883.04088 237.73380 881.52888 C -247.59780 848.48088 253.78980 819.03288 241.54980 784.25688 C -234.56580 771.51288 237.44580 776.26488 226.86180 777.48888 C -225.56580 769.06488 213.10980 758.26488 206.55780 753.00888 C -193.38180 753.00888 195.25380 765.24888 194.53380 774.46488 C -182.36580 773.60088 175.66980 746.67288 159.97380 743.21688 C -157.95780 744.72888 155.94180 746.24088 153.92580 747.75288 C -152.70180 757.76088 153.99780 764.96088 155.43780 774.46488 C -142.26180 769.78488 132.03780 733.78488 115.62180 744.72888 C -108.13380 761.00088 114.46980 783.39288 119.36580 799.37688 C -105.97380 797.21688 99.27780 777.84888 83.29380 776.76888 C -82.93380 773.52888 82.42980 770.43288 78.03780 769.64088 C -75.08580 772.44888 76.09380 773.38488 72.78180 774.46488 C -73.14180 769.20888 78.32580 766.25688 79.90980 760.13688 C -79.40580 759.41688 78.90180 758.69688 78.39780 757.90488 C -76.95780 757.68888 75.58980 757.47288 74.22180 757.18488 C -74.43780 754.95288 74.72580 752.64888 75.01380 750.34488 C -76.23780 750.12888 77.46180 749.91288 78.75780 749.62488 C -80.12580 745.95288 84.22980 748.25688 83.29380 742.49688 C -81.78180 741.70488 81.78180 741.70488 69.75780 742.85688 C -69.82980 741.34488 69.97380 739.83288 70.11780 738.32088 C -65.07780 733.28088 68.24580 727.37688 69.75780 720.96888 C -74.94180 720.53688 79.47780 721.90488 85.52580 720.60888 C -88.62180 733.92888 91.42980 749.84088 92.29380 763.16088 C -92.79780 763.16088 93.30180 763.16088 93.80580 763.16088 C -93.80580 760.71288 93.80580 758.19288 93.80580 755.67288 C -94.52580 755.31288 95.24580 754.95288 96.03780 754.52088 C -96.10980 748.40088 96.25380 742.20888 96.39780 736.01688 C -90.85380 716.64888 92.72580 698.21688 88.90980 677.98488 C -86.24580 671.28888 76.81380 653.28888 69.75780 651.63288 C -67.16580 642.99288 66.51780 646.52088 61.47780 641.48088 C -51.46980 613.97688 24.75780 593.45688 1.35780 577.40088 C --6.13020 573.58488 -12.89820 567.75288 -21.25020 567.17688 C --24.85020 552.56088 -28.52220 540.46488 -45.29820 540.46488 C -@c -F - -@rax %Note: Object --53.21820 559.25688 -38.27197 582.29688 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def --46.01820 559.25688 m --49.83420 562.28088 -49.83420 562.28088 -51.27420 562.64088 C --51.27420 563.64888 -51.27420 564.65688 -51.27420 565.66488 C --51.92220 565.95288 -52.57020 566.24088 -53.21820 566.45688 C --53.21820 576.96888 -53.21820 576.96888 -52.06620 579.63288 C --50.19420 580.78488 -50.19420 580.78488 -49.83420 582.29688 C --36.73020 581.86488 -35.14620 568.97688 -43.06620 559.25688 C --44.07420 559.25688 -45.08220 559.25688 -46.01820 559.25688 C -@c -F - -@rax %Note: Object -147.81487 656.52888 195.99846 740.98488 @E - 1 O 0 @g -0.00 0.00 0.00 1.00 k -/$fm 0 def -156.94980 656.52888 m -150.18180 661.06488 150.18180 661.06488 149.02980 662.93688 C -147.08580 679.35288 146.14980 700.08888 156.58980 713.40888 C -156.66180 714.92088 156.80580 716.43288 156.94980 717.94488 C -160.26180 718.59288 161.91780 718.80888 164.43780 721.32888 C -179.77380 725.14488 180.20580 727.73688 187.76580 740.98488 C -189.34980 740.84088 191.00580 740.69688 192.66180 740.55288 C -192.66180 732.27288 182.86980 724.28088 184.02180 719.09688 C -184.52580 719.09688 185.02980 719.09688 185.53380 719.09688 C -188.12580 722.55288 191.07780 726.72888 195.32580 727.37688 C -198.42180 721.97688 190.50180 712.47288 185.89380 708.87288 C -185.89380 699.36888 184.45380 671.50488 172.71780 668.19288 C -171.42180 662.86488 161.98980 657.75288 156.94980 656.52888 C -@c -F - -@rax %Note: Object -56.77965 660.27288 85.64995 708.51288 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -61.47780 660.27288 m -52.33380 671.64888 56.79780 704.91288 71.98980 708.51288 C -85.16580 708.51288 86.10180 707.14488 85.52580 692.74488 C -85.02180 692.74488 84.51780 692.74488 84.01380 692.74488 C -80.70180 697.71288 78.25380 697.13688 73.50180 698.72088 C -55.71780 692.38488 60.54180 675.96888 62.98980 661.06488 C -62.48580 660.84888 61.98180 660.56088 61.47780 660.27288 C -@c -F - -@rax %Note: Object -153.92580 682.52088 180.26476 710.53682 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -153.92580 682.52088 m -155.79780 698.57688 159.03780 718.66488 178.76580 707.43288 C -179.55780 702.89688 181.50180 699.36888 179.12580 694.61688 C -175.02180 700.44888 173.65380 700.23288 167.46180 700.23288 C -163.86180 696.27288 157.30980 684.03288 153.92580 682.52088 C -@c -F - -@rax %Note: Object -86.24580 748.83288 242.26980 902.10132 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -120.08580 748.83288 m -114.46980 772.44888 126.13380 790.95288 129.51780 812.19288 C -122.10180 819.60888 98.62980 786.20088 86.24580 785.04888 C -86.60580 791.60088 86.96580 798.15288 87.39780 804.63288 C -95.67780 826.16088 102.30180 835.16088 120.87780 847.97688 C -122.24580 850.20888 123.61380 851.72088 123.10980 854.02488 C -120.08580 854.81688 120.08580 854.81688 115.62180 854.02488 C -106.40580 849.41688 96.82980 847.32888 87.03780 846.82488 C -92.65380 870.44088 128.00580 880.59288 148.66980 883.40088 C -157.66980 883.68888 166.66980 883.97688 175.74180 884.19288 C -177.97380 886.42488 178.69380 886.92888 179.12580 889.80888 C -175.52580 893.40888 159.32580 892.68888 153.20580 893.62488 C -153.20580 894.41688 153.20580 895.13688 153.20580 895.85688 C -175.88580 901.47288 197.26980 905.21688 220.88580 898.52088 C -227.22180 892.83288 227.22180 892.83288 230.96580 887.57688 C -230.96580 878.28888 233.98980 863.02488 238.88580 854.02488 C -239.38980 853.95288 239.89380 853.80888 240.39780 853.66488 C -238.88580 843.72888 241.83780 828.96888 242.26980 817.44888 C -241.54980 809.16888 241.54980 809.16888 235.86180 785.40888 C -234.85380 785.33688 233.84580 785.19288 232.90980 785.04888 C -232.47780 791.81688 232.62180 791.96088 227.65380 793.32888 C -224.12580 784.40088 213.90180 759.27288 202.09380 760.92888 C -201.80580 770.72088 201.51780 780.51288 201.30180 790.30488 C -199.50180 790.30488 197.77380 790.30488 196.04580 790.30488 C -190.57380 781.66488 169.62180 752.14488 159.97380 751.13688 C -159.46980 764.45688 161.77380 774.24888 165.58980 786.56088 C -165.44580 789.00888 165.30180 791.38488 165.22980 793.76088 C -149.89380 793.76088 138.58980 751.42488 120.08580 748.83288 C -@c -F - -@rax %Note: Object -252.06180 759.77688 393.39780 945.96888 @E - 1 O 0 @g -0.00 0.00 0.00 1.00 k -/$fm 0 def -332.12580 759.77688 m -331.33380 759.92088 330.61380 760.06488 329.89380 760.13688 C -329.60580 762.65688 329.31780 765.17688 329.10180 767.69688 C -333.42180 768.34488 338.02980 768.27288 338.89380 773.74488 C -350.91780 778.85688 365.10180 789.36888 373.81380 799.37688 C -395.05380 838.90488 384.97380 892.04088 376.47780 933.51288 C -369.42180 930.99288 368.70180 928.83288 367.04580 922.20888 C -344.43780 914.79288 332.77380 895.06488 319.74180 876.27288 C -308.58180 858.20088 288.92580 830.12088 292.30980 806.93688 C -303.61380 812.55288 310.09380 821.84088 320.10180 829.90488 C -322.33380 830.04888 324.56580 830.19288 326.86980 830.26488 C -326.50980 823.06488 319.45380 813.56088 315.92580 806.93688 C -315.27780 802.18488 314.62980 797.43288 314.05380 792.60888 C -322.40580 793.04088 323.26980 798.29688 334.35780 795.63288 C -336.73380 790.52088 337.30980 778.20888 333.99780 772.95288 C -333.13380 772.88088 332.26980 772.73688 331.40580 772.59288 C -328.23780 775.76088 329.89380 785.55288 329.89380 789.58488 C -327.37380 789.22488 324.85380 788.86488 322.33380 788.43288 C -300.15780 777.12888 307.21380 792.75288 310.30980 809.88888 C -301.52580 809.31288 299.22180 798.22488 289.28580 798.22488 C -280.71780 811.32888 286.90980 824.07288 291.15780 837.82488 C -303.18180 861.15288 303.18180 861.15288 315.20580 880.80888 C -320.24580 887.14488 330.18180 898.37688 332.91780 905.64888 C -307.64580 899.67288 288.27780 875.33688 265.23780 864.17688 C -262.64580 859.13688 259.54980 855.53688 253.93380 855.53688 C -251.70180 857.76888 252.27780 858.70488 252.06180 861.15288 C -257.24580 863.52888 258.46980 864.75288 261.78180 869.50488 C -288.27780 887.79288 315.70980 905.07288 344.14980 920.40888 C -355.52580 927.89688 369.56580 934.80888 377.98980 945.96888 C -385.83780 945.96888 383.31780 942.00888 383.60580 933.51288 C -386.05380 923.21688 390.44580 908.24088 389.29380 897.36888 C -389.79780 897.36888 390.30180 897.36888 390.80580 897.36888 C -392.60580 872.45688 393.39780 870.94488 393.39780 855.89688 C -390.44580 849.92088 390.73380 829.47288 390.37380 825.00888 C -384.75780 798.51288 374.89380 788.43288 351.27780 772.95288 C -347.60580 766.25688 339.68580 759.77688 332.12580 759.77688 C -@c -F - -@rax %Note: Object -6.60359 765.82488 72.78180 884.91288 @E - 1 O 0 @g -0.00 0.00 0.00 0.00 k -/$fm 0 def -62.19780 765.82488 m -57.30180 769.56888 50.67780 774.96888 47.94180 779.79288 C -47.43780 779.79288 46.93380 779.79288 46.42980 779.79288 C -34.33380 794.33688 21.66180 812.19288 13.74180 828.03288 C -9.63780 842.14488 2.36580 872.38488 9.56580 884.91288 C -18.56580 883.32888 33.54180 869.57688 37.42980 860.43288 C -37.93380 860.43288 38.43780 860.43288 38.94180 860.43288 C -44.19780 852.51288 44.19780 852.51288 46.06980 851.36088 C -53.05380 838.90488 74.94180 795.41688 72.78180 785.40888 C -70.47780 785.40888 68.96580 786.20088 64.50180 786.20088 C -63.34980 785.04888 63.34980 785.04888 62.98980 781.30488 C -63.56580 781.08888 64.21380 780.80088 64.86180 780.51288 C -64.86180 779.00088 64.06980 778.28088 63.70980 772.95288 C -66.51780 771.65688 67.23780 771.00888 66.73380 767.33688 C -64.50180 765.82488 64.50180 765.82488 62.19780 765.82488 C -@c -F - -%%PageTrailer -@rs -@rs -%%Trailer -@EndSysCorelDict -end -%%DocumentSuppliedResources: procset wCorel8Dict -%%EOF - -%%EndDocument - diff --git a/obalky/obalky-template.tex b/obalky/obalky-template.tex deleted file mode 100644 index db2b7c3c..00000000 --- a/obalky/obalky-template.tex +++ /dev/null @@ -1,78 +0,0 @@ -\input czech.sty -\input epsf -\special{landscape} -\nopagenumbers -\hoffset=-1in -\voffset=-1in -\advance\voffset by 0.9cm -%nove pridano, aby to fungovalo... -\advance\hoffset by 6.5cm -\hsize=22cm -\vsize=16cm - -\font\adrfonta=csssbx10 at 14pt -\font\adrfontb=csssbx10 at 12pt -\font\adrfontc=csss12 -\font\tofont=csr12 at 16pt - -\newdimen\fromskip -\newdimen\toskip -\fromskip=4.35cm -\toskip=13.2cm - -\def\first{\relax} - -\catcode`_=13 -%\catcode`_=12 - -\def_{$\_$} - -\advance\voffset by 2.5cm - - -\def\obalka#1#2#3#4#5#6#7{ - -\def\jmeno{#1} -\def\prijm{#2} -\def\skola{#3} -\def\popis{} -\def\first{} -\def\ulice{#4} -\def\PSC{#5} -\def\mesto{#6} -\def\stat{#7} -\vskip-4mm\vbox to 0pt{\hbox to 0pt{\hskip1.4cm\epsfysize=2.55cm\epsfbox{lisak.eps}\hss}\vss} - -\baselineskip=13pt -\parindent=\fromskip -\line{\indent\adrfonta Časopis M\&M,\hfil} -\vskip3pt -\line{\indent\adrfontb OPMK UK MFF\hfil} -\vskip3pt -\line{\indent\adrfontc Ke Karlovu 3, 121 16 Praha 2\hfil} -\line{\indent\adrfontc Tel.: +420 221 911 235\hss} -\line{\indent\adrfontc mam@atrey.karlin.mff.cuni.cz\hfil} - -\vskip6.15cm -\vbox to 0pt{\parindent=1.4cm\hsize=\toskip\advance\hsize by -1cm -\vbox to 60pt{\vfil} \popis\vss} -\parindent=\toskip -\baselineskip=18pt -\line{\indent\tofont\first\hfil} -\line{\indent\tofont\jmeno\ \prijm\hfil} -\ifx \skola \empty -{} -\else -\line{\indent\tofont\skola\hfil} -\fi -\line{\indent\tofont\ulice\hfil} -\line{\tofont\item{\PSC} \mesto\hfil} -\vskip5pt -\line{\indent\tofont\stat\hfil} - -\vfil\eject -} - -%\obalka{Lenka}{Kopfová}{Leknínová 10}{746 01}{Opava} - - diff --git a/obalky/obalky.py b/obalky/obalky.py deleted file mode 100755 index 27257e19..00000000 --- a/obalky/obalky.py +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/python -#coding: utf-8 - -import psycopg2 -import sys -import subprocess -import re - -dbname="mam-prod" -user="mam" - -conn = psycopg2.connect("dbname={0} user={1}".format(dbname,user)) -cur = conn.cursor() - -names = [] - -with open("obalky.sql") as qfile, open("obalky-template.tex") as texheader, open("obalky.tex","w") as texout : - texout.write(texheader.read()) - cur.execute(qfile.read()) - for row in cur.fetchall(): - (muz,jmeno,prijmeni,skola,ulice,mesto,psc,stat)=row - if (stat=='CZ'): - stat = "" - elif (stat=='SK'): - stat = "Slovenská republika" - else: - print("Neznamy stat: {}\n".format(stat)) - if (skola==None): - skola="" - psc = psc.replace(" ","") - psc = psc[0:3]+" "+psc[3:] - - texout.write("\\obalka{{{0}}}{{{1}}}{{{2}}}{{{3}}}{{{4}}}{{{5}}}{{{6}}}\n".format(jmeno,prijmeni,skola,ulice,psc,mesto,stat)) - names.append((jmeno,prijmeni)) - texout.write("\\bye\n") - -cur.close() -conn.close() - -print("Spoustim csplain ...") -output = subprocess.check_output(["csplain","obalky.tex"],stderr=subprocess.STDOUT) -page = 0 -for line in output.decode("utf-8").splitlines(): - pmatch = re.search("\[([0-9]+)\]",line) - if pmatch: - page = int(pmatch.group(1)) - errmatch = re.match("Overfull",line) - if errmatch: - print("Preteceni na strane",page,"u osoby",names[page][0],names[page][1]) - -print("Spoustim dvipdf ...") -subprocess.call(["dvipdf","obalky.dvi"]) -print("Hotovo.") diff --git a/obalky/obalky.sql b/obalky/obalky.sql deleted file mode 100644 index 930dd640..00000000 --- a/obalky/obalky.sql +++ /dev/null @@ -1,26 +0,0 @@ -WITH akt_rocnik AS ( - SELECT rocnik FROM seminar_rocniky - WHERE id=(SELECT aktualni_rocnik_id FROM seminar_nastaveni) -), id_rocniku AS ( - SELECT id,prvni_rok FROM seminar_rocniky - WHERE rocnik=(SELECT * FROM akt_rocnik) OR rocnik=(SELECT * FROM akt_rocnik)-1 -), id_cisel AS ( - SELECT seminar_cisla.id FROM seminar_cisla - INNER JOIN id_rocniku ON rocnik_id=id_rocniku.id -), problemy AS ( - SELECT seminar_problemy.id FROM seminar_problemy - INNER JOIN id_cisel ON cislo_zadani_id = id_cisel.id -), resitele AS( - SELECT DISTINCT resitel_id FROM seminar_reseni - INNER JOIN problemy ON problem_id=problemy.id -) -SELECT pohlavi_muz,jmeno,prijmeni,NULL AS skola,ulice,mesto,psc,stat FROM seminar_resitele -INNER JOIN resitele ON seminar_resitele.id=resitel_id -WHERE zasilat='domu' AND rok_maturity > (SELECT MAX(prvni_rok) FROM id_rocniku) -UNION -SELECT res.pohlavi_muz,res.jmeno,res.prijmeni,sk.nazev,sk.ulice,sk.mesto,sk.psc,sk.stat -FROM seminar_resitele AS res -INNER JOIN resitele ON res.id=resitel_id -INNER JOIN seminar_skoly AS sk ON sk.id=skola_id -WHERE zasilat='do_skoly' AND rok_maturity > (SELECT MAX(prvni_rok) FROM id_rocniku) -ORDER BY prijmeni ASC, jmeno ASC diff --git a/prednasky/admin.py b/prednasky/admin.py index a9b94ee0..2688fffc 100644 --- a/prednasky/admin.py +++ b/prednasky/admin.py @@ -5,96 +5,96 @@ from reversion.admin import VersionAdmin from django.utils.safestring import mark_safe from django.utils.html import escape -from models import Prednaska, Seznam, STAV_NAVRH +from .models import Prednaska, Seznam, STAV_NAVRH from seminar.models import Soustredeni class Seznam_PrednaskaInline(admin.TabularInline): - model = Prednaska.seznamy.through - extra = 0 - - def prednaska__nazev(self, obj): - return mark_safe( - u"{}".format( - obj.prednaska.id, - escape(obj.prednaska.nazev) - ) - ) - - def prednaska__popis(self, obj): - return mark_safe( - u"
    {}
    ".format( - escape(obj.prednaska.popis) - ) - ) - - def prednaska__anotace(self, obj): - return obj.prednaska.anotace - - def prednaska__org(self, obj): - return obj.prednaska.org - - def prednaska__obor(self, obj): - return obj.prednaska.obor - - prednaska__nazev.short_description = u'Přednáška' - prednaska__popis.short_description = u'Popis pro orgy' - prednaska__anotace.short_description = u'Anotace' - prednaska__org.short_description = u'Org' - prednaska__obor.short_description = u'Obor' - - readonly_fields = [ - 'prednaska__nazev', - 'prednaska__obor', - 'prednaska__org', - 'prednaska__popis', - 'prednaska__anotace', - ] - exclude = ['prednaska'] - - def has_add_permission(self, req): return False + model = Prednaska.seznamy.through + extra = 0 + + def prednaska__nazev(self, obj): + return mark_safe( + u"{}".format( + obj.prednaska.id, + escape(obj.prednaska.nazev) + ) + ) + + def prednaska__popis(self, obj): + return mark_safe( + u"
    {}
    ".format( + escape(obj.prednaska.popis) + ) + ) + + def prednaska__anotace(self, obj): + return obj.prednaska.anotace + + def prednaska__org(self, obj): + return obj.prednaska.org + + def prednaska__obor(self, obj): + return obj.prednaska.obor + + prednaska__nazev.short_description = u'Přednáška' + prednaska__popis.short_description = u'Popis pro orgy' + prednaska__anotace.short_description = u'Anotace' + prednaska__org.short_description = u'Org' + prednaska__obor.short_description = u'Obor' + + readonly_fields = [ + 'prednaska__nazev', + 'prednaska__obor', + 'prednaska__org', + 'prednaska__popis', + 'prednaska__anotace', + ] + exclude = ['prednaska'] + + def has_add_permission(self, req): return False class SeznamAdmin(VersionAdmin): - list_display = ['soustredeni', 'stav'] - inlines = [Seznam_PrednaskaInline] + list_display = ['soustredeni', 'stav'] + inlines = [Seznam_PrednaskaInline] admin.site.register(Seznam, SeznamAdmin) class PrednaskaAdmin(VersionAdmin): - list_display = ['nazev', 'org', 'obor'] - list_filter = ['org', 'obor'] - search_fields = [] - filter_horizontal = ('seznamy', ) - - actions = ['move_to_soustredeni'] - - def move_to_soustredeni(self, request, queryset): - sous = Soustredeni.objects.first() - seznam = Seznam.objects.filter(soustredeni=sous, stav=STAV_NAVRH) - if len(seznam) == 0: - self.message_user( - request, - u"Není definován seznam pro aktuální soustředění, " - u"nic se neprovedlo", - messages.ERROR - ) - return - seznam = seznam[0] - for prednaska in queryset: - prednaska.seznamy.add(seznam) - prednaska.save() - - self.message_user( - request, - u"Vybrané přednášky ({}) přidány jako návrhy na nejbližší " - u"soustředění".format(len(queryset)) - ) - - move_to_soustredeni.short_description = ( - u"Přidat přednášky do návrhu na nejbližší soustředění" - ) + list_display = ['nazev', 'org', 'obor'] + list_filter = ['org', 'obor'] + search_fields = [] + filter_horizontal = ('seznamy', ) + + actions = ['move_to_soustredeni'] + + def move_to_soustredeni(self, request, queryset): + sous = Soustredeni.objects.first() + seznam = Seznam.objects.filter(soustredeni=sous, stav=STAV_NAVRH) + if len(seznam) == 0: + self.message_user( + request, + u"Není definován seznam pro aktuální soustředění, " + u"nic se neprovedlo", + messages.ERROR + ) + return + seznam = seznam[0] + for prednaska in queryset: + prednaska.seznamy.add(seznam) + prednaska.save() + + self.message_user( + request, + u"Vybrané přednášky ({}) přidány jako návrhy na nejbližší " + u"soustředění".format(len(queryset)) + ) + + move_to_soustredeni.short_description = ( + u"Přidat přednášky do návrhu na nejbližší soustředění" + ) admin.site.register(Prednaska, PrednaskaAdmin) diff --git a/prednasky/forms.py b/prednasky/forms.py index 969232e3..071d068e 100644 --- a/prednasky/forms.py +++ b/prednasky/forms.py @@ -2,7 +2,7 @@ from django import forms class NewPrednaskyForm(forms.Form): - ucastnik = forms.CharField(label = 'Tvoje jméno', max_length = 100) + ucastnik = forms.CharField(label = 'Tvoje jméno', max_length = 100) diff --git a/prednasky/migrations/0001_initial.py b/prednasky/migrations/0001_initial.py index c3510548..07da4a4e 100644 --- a/prednasky/migrations/0001_initial.py +++ b/prednasky/migrations/0001_initial.py @@ -28,7 +28,7 @@ class Migration(migrations.Migration): ('obtiznost', models.IntegerField(verbose_name=b'Obt\xc3\xad\xc5\xbenost', choices=[(1, b'Lehk\xc3\xa1'), (2, b'St\xc5\x99edn\xc3\xad'), (3, b'T\xc4\x9b\xc5\xbek\xc3\xa1')])), ('obor', models.CharField(max_length=5, verbose_name=b'Obor')), ('klicova', models.CharField(max_length=200, null=True, verbose_name=b'Kl\xc3\xad\xc4\x8dov\xc3\xa1 slova', blank=True)), - ('org', models.ForeignKey(to='seminar.Organizator')), + ('org', models.ForeignKey(to='seminar.Organizator', on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -40,6 +40,6 @@ class Migration(migrations.Migration): migrations.AddField( model_name='hlasovani', name='prednaska', - field=models.ForeignKey(to='prednasky.Prednaska'), + field=models.ForeignKey(to='prednasky.Prednaska', on_delete=models.CASCADE), ), ] diff --git a/prednasky/migrations/0002_auto_20160417_2347.py b/prednasky/migrations/0002_auto_20160417_2347.py index f3527e75..aa09d465 100644 --- a/prednasky/migrations/0002_auto_20160417_2347.py +++ b/prednasky/migrations/0002_auto_20160417_2347.py @@ -14,7 +14,7 @@ class Migration(migrations.Migration): migrations.AddField( model_name='prednaska', name='seznam', - field=models.ForeignKey(default=None, blank=True, to='prednasky.Seznam'), + field=models.ForeignKey(default=None, blank=True, to='prednasky.Seznam', on_delete=models.CASCADE), ), migrations.AlterField( model_name='hlasovani', diff --git a/prednasky/migrations/0003_auto_20160929_0117.py b/prednasky/migrations/0003_auto_20160929_0117.py index 9e2cfb17..606d6cf7 100644 --- a/prednasky/migrations/0003_auto_20160929_0117.py +++ b/prednasky/migrations/0003_auto_20160929_0117.py @@ -5,6 +5,7 @@ from django.db import migrations, models class Migration(migrations.Migration): + atomic = False dependencies = [ ('prednasky', '0002_auto_20160417_2347'), @@ -51,7 +52,7 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='prednaska', name='seznam', - field=models.ForeignKey(to='prednasky.Seznam_old'), + field=models.ForeignKey(to='prednasky.Seznam_old',on_delete=models.CASCADE), ), migrations.AlterModelTable( name='hlasovani', diff --git a/prednasky/migrations/0005_auto_20160929_0153.py b/prednasky/migrations/0005_auto_20160929_0153.py index 8aacd6fd..7ecff0a0 100644 --- a/prednasky/migrations/0005_auto_20160929_0153.py +++ b/prednasky/migrations/0005_auto_20160929_0153.py @@ -16,7 +16,7 @@ class Migration(migrations.Migration): name='Prednaska_Seznam', fields=[ ('id', models.AutoField(serialize=False, primary_key=True)), - ('prednaska', models.ForeignKey(to='prednasky.Prednaska')), + ('prednaska', models.ForeignKey(to='prednasky.Prednaska', on_delete=models.CASCADE)), ], options={ 'db_table': 'prednasky_prednaska_seznam', @@ -29,7 +29,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(serialize=False, primary_key=True)), ('stav', models.IntegerField(default=2, verbose_name=b'Stav', choices=[(1, b'N\xc3\xa1vrh'), (2, b'Bude')])), - ('soustredeni', models.ForeignKey(default=None, to='seminar.Soustredeni', null=True)), + ('soustredeni', models.ForeignKey(default=None, to='seminar.Soustredeni', null=True, on_delete=models.CASCADE)), ], options={ 'ordering': ['soustredeni', 'stav'], @@ -44,6 +44,6 @@ class Migration(migrations.Migration): migrations.AddField( model_name='prednaska_seznam', name='seznam', - field=models.ForeignKey(to='prednasky.Seznam'), + field=models.ForeignKey(to='prednasky.Seznam', on_delete=models.CASCADE), ), ] diff --git a/prednasky/migrations/0006_hlasovani_seznam.py b/prednasky/migrations/0006_hlasovani_seznam.py index c6c1e609..e1b7bd8f 100644 --- a/prednasky/migrations/0006_hlasovani_seznam.py +++ b/prednasky/migrations/0006_hlasovani_seznam.py @@ -14,7 +14,7 @@ class Migration(migrations.Migration): migrations.AddField( model_name='hlasovani', name='seznam', - field=models.ForeignKey(default=1, to='prednasky.Seznam'), + field=models.ForeignKey(default=1, to='prednasky.Seznam', on_delete=models.CASCADE), preserve_default=False, ), ] diff --git a/prednasky/migrations/0011_auto_20190430_2340.py b/prednasky/migrations/0011_auto_20190430_2340.py new file mode 100644 index 00000000..a01d1878 --- /dev/null +++ b/prednasky/migrations/0011_auto_20190430_2340.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-04-30 21:40 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('prednasky', '0010_auto_20160929_0508'), + ] + + operations = [ + migrations.AlterField( + model_name='hlasovani', + name='body', + field=models.IntegerField(choices=[(-1, '-1'), (0, '0'), (1, '1')], default=0, verbose_name='Body'), + ), + migrations.AlterField( + model_name='hlasovani', + name='ucastnik', + field=models.CharField(max_length=100, verbose_name='Účastník'), + ), + migrations.AlterField( + model_name='prednaska', + name='anotace', + field=models.TextField(blank=True, help_text='Veřejná anotace v hlasování', null=True, verbose_name='Anotace'), + ), + migrations.AlterField( + model_name='prednaska', + name='obtiznost', + field=models.IntegerField(choices=[(1, 'Lehká'), (2, 'Střední'), (3, 'Těžká')], verbose_name='Obtížnost'), + ), + migrations.AlterField( + model_name='seznam', + name='stav', + field=models.IntegerField(choices=[(1, 'Návrh'), (2, 'Bude')], default=1, verbose_name='Stav'), + ), + ] diff --git a/prednasky/migrations/0012_auto_20190610_2358.py b/prednasky/migrations/0012_auto_20190610_2358.py new file mode 100644 index 00000000..1ca6db83 --- /dev/null +++ b/prednasky/migrations/0012_auto_20190610_2358.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.21 on 2019-06-10 21:58 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('prednasky', '0011_auto_20190430_2340'), + ] + + operations = [ + migrations.AlterField( + model_name='hlasovani', + name='seznam', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='prednasky.Seznam'), + ), + migrations.AlterField( + model_name='prednaska', + name='org', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Organizator'), + ), + migrations.AlterField( + model_name='seznam', + name='soustredeni', + field=models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Soustredeni'), + ), + ] diff --git a/prednasky/models.py b/prednasky/models.py index d05ba76d..50c71984 100644 --- a/prednasky/models.py +++ b/prednasky/models.py @@ -1,10 +1,9 @@ # -*- coding: utf-8 -*- from django.db import models -from django.utils.encoding import python_2_unicode_compatible -from django.utils.encoding import force_unicode +from django.utils.encoding import force_text -from seminar.models import Organizator,Soustredeni +from seminar.models import Organizator, Soustredeni STAV_NAVRH = 1 STAV_BUDE = 2 @@ -16,69 +15,69 @@ STAV_CHOICES = ( ) -@python_2_unicode_compatible class Seznam(models.Model): - class Meta: - db_table = 'prednasky_seznam' - verbose_name = u'Seznam přednášek' - verbose_name_plural = u'Seznamy přednášek' - ordering = ['soustredeni', 'stav'] + class Meta: + db_table = 'prednasky_seznam' + verbose_name = 'Seznam přednášek' + verbose_name_plural = 'Seznamy přednášek' + ordering = ['soustredeni', 'stav'] - id = models.AutoField(primary_key = True) - soustredeni = models.ForeignKey(Soustredeni,null = True, default = None) - stav = models.IntegerField('Stav',choices=STAV_CHOICES,default = STAV_NAVRH) + id = models.AutoField(primary_key = True) + soustredeni = models.ForeignKey(Soustredeni,null = True, default = None, + on_delete=models.PROTECT) + stav = models.IntegerField('Stav',choices=STAV_CHOICES,default = STAV_NAVRH) - def __str__(self): - return force_unicode(u"Seznam {}přednášek na {}".format(u"návrhů " if self.stav == STAV_NAVRH else "",self.soustredeni)) + def __str__(self): + return "Seznam {}přednášek na {}".format("návrhů " + if self.stav == STAV_NAVRH else "", self.soustredeni) CHOICES_OBTIZNOST = ( -(1, 'Lehká'), -(2, 'Střední'), -(3, 'Těžká'), -) + (1, 'Lehká'), + (2, 'Střední'), + (3, 'Těžká'), + ) CHOICES_BODY = ( - (-1, '-1'), - (0, '0'), - (1, '1'), - ) + (-1, '-1'), + (0, '0'), + (1, '1'), + ) -@python_2_unicode_compatible class Prednaska(models.Model): - class Meta: - db_table = 'prednasky_prednaska' - verbose_name = u'Přednáška' - verbose_name_plural = u'Přednášky' - ordering = ['org', 'nazev'] - - id = models.AutoField(primary_key = True) - nazev = models.CharField(u'Název', max_length = 300) - org = models.ForeignKey(Organizator) - popis = models.TextField(u'Popis pro orgy',null = True, blank = True,help_text = u'Neveřejný popis pro ostatní orgy') - anotace = models.TextField('Anotace',null = True, blank = True, help_text = u'Veřejná anotace v hlasování') - obtiznost = models.IntegerField(u'Obtížnost', choices=CHOICES_OBTIZNOST) - obor = models.CharField(u'Obor', max_length = 5, help_text = u'Podmnožina MFIOB') - klicova = models.CharField(u'Klíčová slova', max_length = 200, null = True, blank = True) - seznamy = models.ManyToManyField(Seznam) - - def __str__(self): - return force_unicode(u"{} ({})".format(self.nazev,self.org)) - - -@python_2_unicode_compatible + class Meta: + db_table = 'prednasky_prednaska' + verbose_name = 'Přednáška' + verbose_name_plural = 'Přednášky' + ordering = ['org', 'nazev'] + + id = models.AutoField(primary_key = True) + nazev = models.CharField('Název', max_length = 300) + org = models.ForeignKey(Organizator, on_delete=models.PROTECT) + popis = models.TextField('Popis pro orgy',null = True, blank = True,help_text = 'Neveřejný popis pro ostatní orgy') + anotace = models.TextField('Anotace',null = True, blank = True, help_text = 'Veřejná anotace v hlasování') + obtiznost = models.IntegerField('Obtížnost', choices=CHOICES_OBTIZNOST) + obor = models.CharField('Obor', max_length = 5, help_text = 'Podmnožina MFIOB') + klicova = models.CharField('Klíčová slova', max_length = 200, null = True, blank = True) + seznamy = models.ManyToManyField(Seznam) + + def __str__(self): + return "{} ({})".format(self.nazev, self.org) + + class Hlasovani(models.Model): - class Meta: - db_table = 'prednasky_hlasovani' - verbose_name = u'Hlasování' - verbose_name_plural = u'Hlasování' - ordering = ['ucastnik', 'prednaska'] - id = models.AutoField(primary_key = True) - prednaska = models.ForeignKey(Prednaska) - body = models.IntegerField('Body', default = 0, choices = CHOICES_BODY) - ucastnik = models.CharField('Účastník', max_length = 100) - seznam = models.ForeignKey(Seznam) - - def __str__(self): - return force_unicode(u"{} dal {} bodů {} v seznamu {}".format(self.ucastnik, self.body, self.prednaska,self.seznam)) + class Meta: + db_table = 'prednasky_hlasovani' + verbose_name = 'Hlasování' + verbose_name_plural = 'Hlasování' + ordering = ['ucastnik', 'prednaska'] + id = models.AutoField(primary_key = True) + prednaska = models.ForeignKey(Prednaska, on_delete=models.CASCADE) + body = models.IntegerField('Body', default = 0, choices = CHOICES_BODY) + ucastnik = models.CharField('Účastník', max_length = 100) + seznam = models.ForeignKey(Seznam,null=True,on_delete=models.SET_NULL) + + def __str__(self): + return "{} dal {} bodů {} v seznamu {}".format(self.ucastnik, + self.body, self.prednaska, self.seznam) diff --git a/prednasky/templates/prednasky/base.html b/prednasky/templates/prednasky/base.html index e23d7355..eea79ad2 100644 --- a/prednasky/templates/prednasky/base.html +++ b/prednasky/templates/prednasky/base.html @@ -17,19 +17,17 @@ Jak moc by ses chtěl(a) zúčastnit následujících přednášek?
    {% csrf_token %} - {{form.as_table}} -
    - {% for p in prednasky.prednaska_set.all %} + {% for p, h in prednasky %} {% if p.klicova %}{% endif%} {% endfor %} diff --git a/prednasky/templates/prednasky/metaseznam_prednasek.html b/prednasky/templates/prednasky/metaseznam_prednasek.html index eab1eeef..ed25abe2 100644 --- a/prednasky/templates/prednasky/metaseznam_prednasek.html +++ b/prednasky/templates/prednasky/metaseznam_prednasek.html @@ -1,9 +1,5 @@ {% extends "prednasky/base.html" %} - -{% block header %}hlasovani{% endblock %} - - {% block content %}

    {% block nadpis1a %}{% block nadpis1b %}Hlasování o přednáškách{% endblock %}{% endblock %}

    {# Projdi vsechny seznamy #} @@ -19,6 +15,8 @@ Export {% endfor %} + + {% endblock %} diff --git a/prednasky/templates/prednasky/seznam_prednasek.html b/prednasky/templates/prednasky/seznam_prednasek.html index a019c000..9a78c0b6 100644 --- a/prednasky/templates/prednasky/seznam_prednasek.html +++ b/prednasky/templates/prednasky/seznam_prednasek.html @@ -1,9 +1,5 @@ {% extends "prednasky/base.html" %} - -{% block header %}seznam_prednasek{% endblock %} - - {% block content %}

    {% block nadpis1a %}Průběžné výsledky hlasování{% endblock %}

    @@ -15,5 +11,7 @@ {{ prednaska.body }} b) – {{ prednaska.org }} {% endfor %} + +
    {% endblock %} diff --git a/prednasky/urls.py b/prednasky/urls.py index 94fcccdb..b55de7c3 100644 --- a/prednasky/urls.py +++ b/prednasky/urls.py @@ -1,15 +1,25 @@ -from django.conf.urls import * # NOQA -from django.conf.urls import url -from django.contrib.auth.decorators import user_passes_test +from django.urls import path +from seminar.utils import org_required, resitel_required from . import views -staff_member_required = user_passes_test(lambda u: u.is_staff) - urlpatterns = [ - url(r'^prednasky/$', views.newPrednaska), - url(r'^prednasky/hotovo$', views.Prednaska_hotovo), - url(r'^prednasky/metaseznam_prednasek$', staff_member_required(views.MetaSeznamListView.as_view()), name='metaseznam-list'), - url(r'^prednasky/seznam_prednasek/(?P\d+)/$', staff_member_required(views.SeznamListView.as_view()), name='seznam-list'), - url(r'^prednasky/seznam_prednasek/(?P\d+)/export$', staff_member_required(views.SeznamExportView), name='seznam-export'), -# url(r'^korektury/help/', staff_member_required(views.KorekturyHelpView.as_view()), name='korektury-help'), + path( + 'prednasky/', + resitel_required(views.newPrednaska) + ), + path('prednasky/hotovo', views.Prednaska_hotovo), + path( + 'prednasky/metaseznam_prednasek', + org_required(views.MetaSeznamListView.as_view()), + name='metaseznam-list'), + path( + 'prednasky/seznam_prednasek//export', + org_required(views.SeznamExportView), + name='seznam-export' + ), + path( + 'prednasky/seznam_prednasek//', + org_required(views.SeznamListView.as_view()), + name='seznam-list' + ), ] diff --git a/prednasky/views.py b/prednasky/views.py index 7eee5740..2c370b7a 100644 --- a/prednasky/views.py +++ b/prednasky/views.py @@ -4,104 +4,114 @@ from django.views import generic from django.shortcuts import HttpResponseRedirect from django.core.exceptions import ObjectDoesNotExist from django.db.models import Sum +from django.forms import Form from prednasky.models import Prednaska, Hlasovani, Seznam, STAV_NAVRH -from seminar.models import Soustredeni -from prednasky.forms import NewPrednaskyForm +from seminar.models import Soustredeni, Osoba def newPrednaska(request): - # hlasovani se vztahuje k nejnovejsimu soustredeni - sous = Soustredeni.objects.first() - seznam = Seznam.objects.filter(soustredeni = sous, stav = STAV_NAVRH).first() - print seznam - # obsluha formulare - if request.method == 'POST': - form = NewPrednaskyForm(request.POST, request.FILES) - if form.is_valid(): - jmeno = form.cleaned_data['ucastnik'] - for i in request.POST: - if i[0] == 'q': - hlasovani = Hlasovani() - print("q:"+i[1:]) - hlasovani.prednaska = Prednaska.objects.filter(pk = int(i[1:]))[0] - hlasovani.body = int(request.POST[i]) - hlasovani.ucastnik = jmeno - hlasovani.seznam = seznam - hlasovani.save() - - # presmerovani na prave vzniklou galerii - return HttpResponseRedirect('./hotovo') - - else: - form = NewPrednaskyForm() - - return render( - request, - 'prednasky/base.html', - {'form': form, 'prednasky': seznam} - ) + # hlasovani se vztahuje k nejnovejsimu soustredeni + sous = Soustredeni.objects.first() + seznam = Seznam.objects.filter(soustredeni = sous, stav = STAV_NAVRH).first() + osoba = Osoba.objects.filter(user=request.user).first() + ucastnik = osoba.plne_jmeno() + ' ' + str(osoba.id) + # obsluha formulare + if request.method == 'POST': + form = Form(request.POST, request.FILES) + if form.is_valid(): + # id z důvodu duplicitních jmen (přechod z jména na objekt Osoby nějak kape na tom, + # že všechna předchozí hlasování zde mají náhodný string…) + # TODO Změnit to na Osobu + + # TODO v následujících řádcích je zbytečně mnoho dotazů na QuerySet (pokud účastník hlasoval, hlasoval u všech) + for i in request.POST: + if i[0] == 'q': + prednaska = Prednaska.objects.filter(pk=int(i[1:]))[0] + hlasovani = Hlasovani.objects.filter(ucastnik=ucastnik, prednaska=prednaska).first() + if not hlasovani: + hlasovani = Hlasovani() + hlasovani.prednaska = prednaska + hlasovani.ucastnik = ucastnik + hlasovani.seznam = seznam + hlasovani.body = int(request.POST[i]) + hlasovani.save() + + # presmerovani na prave vzniklou galerii + return HttpResponseRedirect('./hotovo') + + def prednaska_hodnoceni(prednaska): + h = Hlasovani.objects.filter(ucastnik=ucastnik, prednaska=prednaska).first() + if h: + return prednaska, h.body + else: + return prednaska, 0 + + return render( + request, + 'prednasky/base.html', + {'prednasky': map(prednaska_hodnoceni, seznam.prednaska_set.all())} + ) def Prednaska_hotovo(request): - return render(request, 'prednasky/hotovo.html') + return render(request, 'prednasky/hotovo.html') class MetaSeznamListView(generic.ListView): - model = Seznam - template_name = 'prednasky/metaseznam_prednasek.html' + model = Seznam + template_name = 'prednasky/metaseznam_prednasek.html' class SeznamListView(generic.ListView): - template_name = 'prednasky/seznam_prednasek.html' - - def get_queryset(self): - self.seznam = get_object_or_404(Seznam, id=self.kwargs["seznam"]) - prednasky = Prednaska.objects.filter(seznamy=self.seznam).order_by( - 'org__user__first_name', 'org__user__last_name' - ) - return prednasky - - # FIXME nahradit anotaci s filtrem po prechodu na Django 2.2 - def get_context_data(self,**kwargs): - context = super(SeznamListView, self).get_context_data(**kwargs) - - # hlasovani se vztahuje k nejnovejsimu soustredeni - sous = Soustredeni.objects.first() - seznam = Seznam.objects.filter(soustredeni = sous, stav = STAV_NAVRH).first() + template_name = 'prednasky/seznam_prednasek.html' + + def get_queryset(self): + self.seznam = get_object_or_404(Seznam, id=self.kwargs["seznam"]) + prednasky = Prednaska.objects.filter(seznamy=self.seznam).order_by( + 'org__user__first_name', 'org__user__last_name' + ) + return prednasky + + # FIXME nahradit anotaci s filtrem po prechodu na Django 2.2 + def get_context_data(self,**kwargs): + context = super(SeznamListView, self).get_context_data(**kwargs) + + # hlasovani se vztahuje k nejnovejsimu soustredeni + sous = Soustredeni.objects.first() + seznam = Seznam.objects.filter(soustredeni = sous, stav = STAV_NAVRH).first() - for obj in self.object_list: - hlasovani_set = obj.hlasovani_set.filter(seznam=seznam).only('body') - obj.body = sum(map(lambda x: x.body,hlasovani_set)) + for obj in self.object_list: + hlasovani_set = obj.hlasovani_set.filter(seznam=seznam).only('body') + obj.body = sum(map(lambda x: x.body,hlasovani_set)) - return context - + return context def SeznamExportView(request, seznam): - u"""Vypíše výsledky hlasování ve formátu pro prologovský optimalizátor""" - # TODO zřejmě se nepoužívá, časem vyřadit? nahradit tabulkou vhodnější pro - # lidi? - hlasovani = Hlasovani.objects.filter(seznam=seznam) - prednasky = Prednaska.objects.filter(seznamy=seznam) - orgove = set(p.org for p in prednasky) - ucastnici = set(h.ucastnik for h in hlasovani) - - for p in prednasky: - p.body = [] - for u in ucastnici: - try: - p.body.append(hlasovani.get(ucastnik=u, prednaska=p).body) - except ObjectDoesNotExist: - # účastník nehlasoval - p.body.append("?") - - for h in hlasovani: - h.ucastnik = hash(h.ucastnik) - - return render( - request, - 'prednasky/seznam_prednasek_export.txt', - {"hlasovani": hlasovani, "prednasky": prednasky, "orgove": orgove}, - content_type="text/plain; charset=utf-8" - ) + """Vypíše výsledky hlasování ve formátu pro prologovský optimalizátor""" + # TODO zřejmě se nepoužívá, časem vyřadit? nahradit tabulkou vhodnější pro + # lidi? + hlasovani = Hlasovani.objects.filter(seznam=seznam) + prednasky = Prednaska.objects.filter(seznamy=seznam) + orgove = set(p.org for p in prednasky) + ucastnici = set(h.ucastnik for h in hlasovani) + + for p in prednasky: + p.body = [] + for u in ucastnici: + try: + p.body.append(hlasovani.get(ucastnik=u, prednaska=p).body) + except ObjectDoesNotExist: + # účastník nehlasoval + p.body.append("?") + + for h in hlasovani: + h.ucastnik = hash(h.ucastnik) + + return render( + request, + 'prednasky/seznam_prednasek_export.txt', + {"hlasovani": hlasovani, "prednasky": prednasky, "orgove": orgove}, + content_type="text/plain" + ) diff --git a/requirements.txt b/requirements.txt index c8f7c8a6..3786d5a5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,41 +1,48 @@ -c constraints.txt # basic libs -psycopg2==2.7.5 -html5lib==1.0.1 -ipython==5.8.0 -Pillow==5.2.0 -pytz==2018.5 -six==1.10.0 -pexpect==4.6.0 -traitlets==4.3.2 -Unidecode==1.0.22 +psycopg2<2.9 # Kvůli djangu 2.2, odstranit při přechodu na 3. +html5lib +ipython +Pillow +pytz +six +pexpect +traitlets +Unidecode # Django and modules -Django<1.12 +Django<2.3 #django-bootstrap-sass -django-mptt==0.9.1 -django-reversion==2.0.13 -django-sekizai==0.10.0 -django-countries==5.3.1 -django-solo==1.1.3 -django-ckeditor==5.6.1 -django-taggit==0.23.0 -django-autocomplete-light==2.3.6 -django-crispy-forms==1.7.2 -django-imagekit==4.0.2 +django-mptt +django-reversion +django-sekizai +django-countries +django-solo +django-ckeditor +django-flat-theme +django-taggit +django-autocomplete-light +django-crispy-forms +django-imagekit +django-polymorphic +django-sitetree +django_reverse_admin +django-rest-framework +django-webpack-loader +django-rest-polymorphic # Comments akismet==1.0.1 -django-fluent-comments==2.0.2 +django-fluent-comments==2.1 django-threadedcomments==1.2 django-contrib-comments==1.9.0 # debug tools/extensions -django-debug-toolbar==1.9.1 -django-extensions==2.1.0 +django-debug-toolbar==1.11 +django-extensions==2.1.9 sqlparse==0.2.4 Werkzeug==0.14.1 @@ -49,3 +56,7 @@ Werkzeug==0.14.1 # uWSGI uWSGI==2.0.17.1 + +# Potřeba pro test data + +lorem diff --git a/seminar/admin.py b/seminar/admin.py index 6b583bc3..d208bb18 100644 --- a/seminar/admin.py +++ b/seminar/admin.py @@ -1,671 +1,336 @@ -# -*- coding: utf-8 -*- - from django.contrib import admin -from django import forms -from django.forms import widgets +from django.contrib.auth.models import Group +from django.db import models +from django.forms import widgets, ModelForm +from django.core.exceptions import ValidationError + +from polymorphic.admin import PolymorphicParentModelAdmin, PolymorphicChildModelAdmin, PolymorphicChildModelFilter from reversion.admin import VersionAdmin +from django_reverse_admin import ReverseModelAdmin from solo.admin import SingletonModelAdmin -from ckeditor_uploader.widgets import CKEditorUploadingWidget -from django.db.models import Count -from django.db import models from django.utils.safestring import mark_safe -from django.core.urlresolvers import reverse - -from django.contrib.auth.models import User - -from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Nastaveni, Soustredeni, Soustredeni_Ucastnici, Soustredeni_Organizatori, Novinky, Organizator, Prispevek, Pohadka, Konfera -from autocomplete_light import shortcuts as autocomplete_light - - -class UserModelChoiceField(forms.ModelChoiceField): - u"""Vlastní ModelChoiceField pro uživatele. Zobrazí kromě loginu i jméno. - """ - def label_from_instance(self, obj): - return u"{} ({})".format(obj.get_full_name(), obj.username) - -def get_form_predvypln_autora(self, request, obj=None, *args, **kwargs): - u"""get_form fce pro Adminy. Předvyplňí přihlášeného uživatele jako autora. - """ - form = super(self.__class__, self).get_form(request, *args, **kwargs) - form.base_fields['autor'].initial = request.user.id - return form - -def make_set_action(atribut, hodnota, nazev): - u""" - Pomocnik pro rychle vytvareni hromadnych admin akci ktere jen nastavuji - atribut (dany jako string) na danou hodnotu. - nazev je krátký popis akce pro admin rozhraní.""" - def action_f(modeladmin, request, queryset): - for obj in queryset: - assert atribut in obj.__dict__ - obj.__setattr__(atribut, hodnota) - obj.save() - action_f.short_description = nazev - # Trik: je potřeba, aby se funkce různě (ale libovolně) jmenovaly, - # jinak je Django v seznamu akcí splácne do jedné - action_f.__name__ = 'action_f_%d_%d_%d' % (id(atribut), id(hodnota), id(nazev), ) - return action_f - - -### Globální nastavení - -admin.site.register(Nastaveni, SingletonModelAdmin) - - -### UTILS (pro verbose_name a help_text) - -def field_labels(model, fieldname): - f = [i for i in model._meta.fields if i.name == fieldname][0] - return {'label': f.verbose_name.capitalize(), 'help_text': f.help_text, } - -def create_modeladmin(modeladmin, model, name = None, verbose_name = None, verbose_name_plural = None): - - class Meta: - proxy = True - app_label = model._meta.app_label - Meta.verbose_name = verbose_name - Meta.verbose_name_plural = verbose_name_plural - - attrs = {'__module__': '', 'Meta': Meta} - newmodel = type(name, (model,), attrs) - admin.site.register(newmodel, modeladmin) - return modeladmin - -### INLINES +from seminar.views.vysledkovka import hlavni_problem +# TODO Přesunout do utils + + +# Todo: reversion + +import seminar.models as m +import seminar.treelib as tl + +admin.site.register(m.Skola) +admin.site.register(m.Prijemce) +admin.site.register(m.Rocnik) + +class CisloForm(ModelForm): + class Meta: + model = m.Cislo + fields = '__all__' + + def clean(self): + if self.cleaned_data.get('verejne_db') == False: + return self.cleaned_data + # cn = m.CisloNode.objects.get(cislo=self.instance) + # errors = [] + # for ch in tl.all_children(cn): + # if isinstance(ch, m.TemaVCisleNode): + # if ch.tema.stav not in \ + # (m.Problem.STAV_ZADANY, m.Problem.STAV_VYRESENY): + # errors.append(ValidationError('Téma %(tema)s není zadané ani vyřešené', params={'tema':ch.tema})) + # + # if isinstance(ch, m.UlohaZadaniNode) or isinstance(ch, m.UlohaVzorakNode): + # if ch.uloha.stav not in \ + # (m.Problem.STAV_ZADANY, m.Problem.STAV_VYRESENY): + # errors.append(ValidationError('Úloha %(uloha)s není zadaná ani vyřešená', params={'uloha':ch.uloha})) + # if isinstance(ch, m.ReseniNode): + # for problem in ch.reseni.problem_set: + # if problem not in \ + # (m.Problem.STAV_ZADANY, m.Problem.STAV_VYRESENY): + # errors.append(ValidationError('Problém %s není zadaný ani vyřešený', code=problem)) + # if errors: + # errors.append(ValidationError(mark_safe('Pokud chceš učinit všechny problémy, co nejsou zadané ani vyřešené, zadanými a číslo zveřejnit, můžeš to udělat pomocí akce v seznamu čísel'))) + # raise ValidationError(errors) + + errors = [] + for ch in m.Uloha.objects.filter(cislo_zadani=self.instance): + if ch.stav not in (m.Problem.STAV_ZADANY, m.Problem.STAV_VYRESENY): + errors.append( + ValidationError('Úloha %(uloha)s není zadaná ani vyřešená', params={'uloha': ch})) + if errors: + errors.append(ValidationError(mark_safe( + 'Pokud chceš učinit všechny problémy, co nejsou zadané ani vyřešené, zadanými a číslo zveřejnit, můžeš to udělat pomocí akce v seznamu čísel'))) + raise ValidationError(errors) + + return self.cleaned_data + + +@admin.register(m.Cislo) +class CisloAdmin(admin.ModelAdmin): + form = CisloForm + actions = ['force_publish'] + + def force_publish(self,request,queryset): + for cislo in queryset: + # cn = m.CisloNode.objects.get(cislo=cislo) + # for ch in tl.all_children(cn): + # if isinstance(ch, m.TemaVCisleNode): + # if ch.tema.stav not in (m.Problem.STAV_ZADANY, m.Problem.STAV_VYRESENY): + # ch.tema.stav = m.Problem.STAV_ZADANY + # ch.tema.save() + # + # if isinstance(ch, m.UlohaZadaniNode) or isinstance(ch, m.UlohaVzorakNode): + # if ch.uloha.stav not in (m.Problem.STAV_ZADANY, m.Problem.STAV_VYRESENY): + # ch.uloha.stav = m.Problem.STAV_ZADANY + # ch.uloha.save() + # if isinstance(ch, m.ReseniNode): + # for problem in ch.reseni.problem_set: + # if problem not in (m.Problem.STAV_ZADANY, m.Problem.STAV_VYRESENY): + # problem.stav = m.Problem.STAV_ZADANY + # problem.save() + + for ch in m.Uloha.objects.filter(cislo_zadani=cislo): + if ch.stav not in (m.Problem.STAV_ZADANY, m.Problem.STAV_VYRESENY): + ch.stav = m.Problem.STAV_ZADANY + ch.save() + + hp = hlavni_problem(ch) + if hp.stav not in (m.Problem.STAV_ZADANY, m.Problem.STAV_VYRESENY): + hp.stav = m.Problem.STAV_ZADANY + hp.save() + + # TODO Řešení, vzoráky? + # TODO Konfera/Článek? + + cislo.verejne_db = True + cislo.save() + + force_publish.short_description = 'Zveřejnit vybraná čísla a všechny návrhy úloh v nich učinit zadanými' + +@admin.register(m.Osoba) +class OsobaAdmin(admin.ModelAdmin): + actions = ['synchronizuj_maily', 'udelej_orgem'] + + def synchronizuj_maily(self, request, queryset): + for o in queryset: + if o.user is not None: + u = o.user + u.email = o.email + u.save() + self.message_user(request, "E-maily synchronizovány.") + synchronizuj_maily.short_description = "Synchronizuj vybraným osobám e-maily do uživatelů" + + def udelej_orgem(self,request,queryset): + org_group = Group.objects.get(name='org') + print(queryset) + for o in queryset: + user = o.user + print(user) + user.groups.add(org_group) + user.is_staff = True + user.save() + org = m.Organizator.objects.create(osoba=o) + org.save() + udelej_orgem.short_description = "Udělej vybraných osob organizátory" + +@admin.register(m.Organizator) +class OrganizatorAdmin(admin.ModelAdmin): + search_fields = ['osoba__jmeno', 'osoba__prijmeni', 'osoba__prezdivka'] + +@admin.register(m.Resitel) +class ResitelAdmin(admin.ModelAdmin): + search_fields = ['osoba__jmeno', 'osoba__prijmeni', 'osoba__prezdivka'] + ordering = ('osoba__jmeno','osoba__prijmeni') + +@admin.register(m.Problem) +class ProblemAdmin(PolymorphicParentModelAdmin): + base_model = m.Problem + child_models = [ + m.Tema, + m.Clanek, + m.Uloha, + m.Konfera, + ] + # Pokud chceme orezavat na aktualni rocnik, musime do modelu pridat odkaz na rocnik. Zatim bere vse. + search_fields = ['nazev'] + +# V ProblemAdmin to nejde, protoze se to nepropise do deti +class ProblemAdminMixin(object): + show_in_index = True + autocomplete_fields = ['nadproblem','autor','garant'] + filter_horizontal = ['opravovatele'] + + +@admin.register(m.Tema) +class TemaAdmin(ProblemAdminMixin,PolymorphicChildModelAdmin): + base_model = m.Tema + +@admin.register(m.Clanek) +class ClanekAdmin(ProblemAdminMixin,PolymorphicChildModelAdmin): + base_model = m.Clanek + +@admin.register(m.Uloha) +class UlohaAdmin(ProblemAdminMixin,PolymorphicChildModelAdmin): + base_model = m.Uloha + +@admin.register(m.Konfera) +class KonferaAdmin(ProblemAdminMixin,PolymorphicChildModelAdmin): + base_model = m.Konfera + + +class TextAdminInline(admin.TabularInline): + model = m.Text + formfield_overrides = { + models.TextField: {'widget': widgets.TextInput} + } + exclude = ['text_zkraceny_set','text_zkraceny'] + +admin.site.register(m.Text) class ResitelInline(admin.TabularInline): - model = Resitel - fields = ['jmeno', 'prijmeni', 'skola', 'mesto', 'rok_maturity', ] - readonly_fields = ['jmeno', 'prijmeni', 'skola', 'mesto', 'rok_maturity', ] - extra = 0 - view_on_site = False - - def has_add_permission(self, req): return False - - -class CisloInline(admin.TabularInline): - model = Cislo - fields = ['cislo', - 'datum_vydani', 'datum_deadline', 'datum_deadline_soustredeni', - 'verejne_db', 'poznamka'] - readonly_fields = ['cislo'] - extra = 0 - formfield_overrides = { - models.TextField: {'widget': forms.TextInput}, - } - view_on_site = Cislo.verejne_url - - def has_add_permission(self, req): return False - - -class PrilohaReseniInline(admin.StackedInline): - model = PrilohaReseni - fields = ['timestamp', 'soubor', 'poznamka'] - readonly_fields = ['timestamp'] - formfield_overrides = { - models.TextField: {'widget': forms.TextInput}, - } - view_on_site = False - - extra = 0 - - -class ProblemInline(admin.TabularInline): - model = Problem - fk_name = 'cislo_zadani' - fields = ['kod', 'typ', 'nazev', 'body', 'opravovatel', 'stav'] - formfield_overrides = { - models.TextField: {'widget': forms.TextInput}, - } - view_on_site = Problem.verejne_url - - extra = 0 - - -class ReseniKProblemuInline(admin.TabularInline): - form = autocomplete_light.modelform_factory(Reseni, autocomplete_fields=['resitel'], fields=['resitel']) - model = Reseni - fields = ['resitel', 'forma', 'body', 'cislo_body', 'timestamp', 'poznamka'] - readonly_fields = ['timestamp'] - extra = 0 - formfield_overrides = { - models.TextField: {'widget': forms.TextInput}, - } - view_on_site = False - - def get_queryset(self, request): - qs = super(ReseniKProblemuInline, self).get_queryset(request) - return qs.select_related('problem', 'cislo_body', 'resitel') - - # Potenciální DB HOG (cislo_body se dotazovalo na cisla pri kazdem zobrazeni jejich selectu ...) - def formfield_for_dbfield(self, db_field, **kwargs): - formfield = super(ReseniKProblemuInline, self).formfield_for_dbfield(db_field, **kwargs) - if db_field.name == 'cislo_body': - # dirty trick so queryset is evaluated and cached in .choices - formfield.choices = formfield.choices - return formfield - - -class ReseniKResiteliInline(admin.TabularInline): - model = Reseni - fields = ['problem', 'forma', 'body', 'cislo_body', 'timestamp', 'poznamka'] - readonly_fields = ['timestamp', 'problem'] - extra = 0 - formfield_overrides = { - models.TextField: {'widget': forms.TextInput}, - } - view_on_site = False - - def has_add_permission(self, req): return False - - def get_queryset(self, request): - qs = super(ReseniKResiteliInline, self).get_queryset(request) - return qs.select_related('problem', 'cislo_body', 'resitel') - - # Potenciální DB HOG (cislo_body se dotazovalo na cisla pri kazdem zobrazeni jejich selectu ...) - def formfield_for_dbfield(self, db_field, **kwargs): - formfield = super(ReseniKResiteliInline, self).formfield_for_dbfield(db_field, **kwargs) - if db_field.name == 'cislo_body': - # dirty trick so queryset is evaluated and cached in .choices - formfield.choices = formfield.choices - return formfield - - -class Soustredeni_UcastniciInline(admin.TabularInline): - form = autocomplete_light.modelform_factory(Soustredeni_Ucastnici, autocomplete_fields=['resitel'], fields=['resitel']) - model = Soustredeni_Ucastnici - fields = ['resitel', 'poznamka', ] - extra = 0 - formfield_overrides = { - models.TextField: {'widget': forms.TextInput}, - } - - def get_queryset(self, request): - qs = super(Soustredeni_UcastniciInline, self).get_queryset(request) - return qs.select_related('resitel', 'soustredeni') - - -class Soustredeni_OrganizatoriInline(admin.TabularInline): - form = autocomplete_light.modelform_factory(Soustredeni_Organizatori, autocomplete_fields=['organizator'], fields=['organizator'],) - model = Soustredeni_Organizatori - fields = ['organizator', 'poznamka', ] - extra = 0 - formfield_overrides = { - models.TextField: {'widget': forms.TextInput}, - } - - def get_queryset(self, request): - qs = super(Soustredeni_OrganizatoriInline, self).get_queryset(request) - return qs.select_related('organizator', 'soustredeni') - -### Resitel - -class ResitelAdmin(VersionAdmin): - form = autocomplete_light.modelform_factory(Resitel, autocomplete_fields=['skola'], fields=['skola']) - fieldsets = [ - (None, {'fields': ['jmeno', 'prijmeni', 'user']}), - (u'Škola', {'fields': ['skola', 'rok_maturity']}), - (u'Seminář', {'fields': ['datum_souhlasu_udaje', 'datum_souhlasu_zasilani', 'datum_prihlaseni', 'zasilat']}), - (u'Osobní údaje', {'fields': ['pohlavi_muz', 'datum_narozeni', 'email', 'telefon']}), - (u'Adresa', {'fields': ['ulice', 'mesto', 'psc', 'stat']}), - (u'Další', {'fields': ['poznamka']}), - ] - list_display = ['jmeno', 'prijmeni', 'user', 'pohlavi_muz', 'skola', 'rok_maturity', 'pocet_reseni'] - list_filter = ['pohlavi_muz', 'rok_maturity', 'zasilat'] - search_fields = ['jmeno', 'prijmeni', 'ulice', 'mesto', 'email'] - inlines = [ReseniKResiteliInline] - view_on_site = False - - def get_queryset(self, request): - qs = super(ResitelAdmin, self).get_queryset(request) - return qs.select_related('skola', 'user').annotate(pocet_reseni=Count('reseni')) - - def pocet_reseni(self, obj): - return obj.pocet_reseni - - -admin.site.register(Resitel, ResitelAdmin) - - -### Skola - -class SkolaAdmin(VersionAdmin): - fieldsets = [ - (None, {'fields': ['nazev', 'kratky_nazev', 'je_zs', 'je_ss']}), - (u'Interní ID', {'fields': ['aesop_id', 'izo'], 'classes': ['collapse']}), - (u'Adresa', {'fields': ['ulice', 'mesto', 'psc', 'stat']}), - (None, {'fields': ['poznamka']}), - ] - list_display = ['nazev', 'aesop_id', 'mesto', 'ulice', 'stat', 'je_zs', 'je_ss'] - list_filter = ['stat', 'je_zs', 'je_ss'] - search_fields = ['nazev', 'mesto', 'ulice'] - inlines = [ResitelInline] - view_on_site = False - -admin.site.register(Skola, SkolaAdmin) - - -### Cislo - -class CisloAdmin(VersionAdmin): - fieldsets = [ - (None, { - 'fields': [ - 'cislo', - 'rocnik', - 'verejne_db', - 'verejna_vysledkovka', - 'faze', - 'poznamka', - 'pdf' - ] - }), - (u'Data', {'fields': ['datum_vydani', 'datum_deadline', - 'datum_deadline_soustredeni']}), - ] - list_display = [ - 'kod', - 'rocnik', - 'cislo', - 'datum_vydani', - 'datum_deadline', - 'verejne', - 'verejna_vysledkovka' - ] - list_filter = ['rocnik'] - view_on_site = Cislo.verejne_url - actions = [ - make_set_action('verejne_db', True, u'Zveřejnit číslo'), - make_set_action('verejne_db', False, u'Skrýt (zneveřejnit) číslo'), - make_set_action('verejna_vysledkovka', True, u'Zveřejnit výsledkovku'), - make_set_action('verejna_vysledkovka', False, u'Skrýt (zneveřejnit) výsledkovku'), - ] - inlines = [ProblemInline] - - def get_queryset(self, request): - qs = super(CisloAdmin, self).get_queryset(request) - return qs.select_related('rocnik') - -admin.site.register(Cislo, CisloAdmin) - -### Rocnik - -class RocnikAdmin(VersionAdmin): - fieldsets = [ - (None, {'fields': ['rocnik', 'prvni_rok', 'exportovat']}), - ] - list_display = ['rocnik', 'prvni_rok', 'exportovat', 'verejne'] - inlines = [CisloInline] - view_on_site = Rocnik.verejne_url - actions = [ - make_set_action('exportovat', True, u'Nastavit pro AESOP export'), - make_set_action('exportovat', False, u'Skrýt pro AESOP export'), - ] - -admin.site.register(Rocnik, RocnikAdmin) - - -### PrilohaReseni -# NOTE: Nemá pravděpodobně smysl používat -# class PrilohaReseniAdmin(reversion.VersionAdmin): -# readonly_fields = ['timestamp', 'reseni'] -# fieldsets = [ -# (None, {'fields': ['reseni', 'soubor', 'timestamp']}), -# (u'Poznámky', {'fields': ['poznamka']}), -# ] -# list_display = ['reseni', 'soubor', 'timestamp'] -# list_filter = ['reseni', 'timestamp'] -# search_fields = [] -# -# admin.site.register(PrilohaReseni, PrilohaReseniAdmin) - - -### Reseni - -class ReseniAdmin(VersionAdmin): - form = autocomplete_light.modelform_factory(Reseni, autocomplete_fields=['problem', 'resitel'], fields=['problem', 'resitel']) - fieldsets = [ - (None, {'fields': ['problem', 'resitel', 'forma', 'body', 'cislo_body', 'timestamp']}), - (u'Poznámky', {'fields': ['poznamka']}), - ] - readonly_fields = ['timestamp'] - list_display = ['problem', 'resitel', 'forma', 'body', 'timestamp', 'cislo_body'] - list_filter = ['body', 'timestamp', 'forma'] - search_fields = [] - inlines = [PrilohaReseniInline] - view_on_site = False - - def get_queryset(self, request): - qs = super(ReseniAdmin, self).get_queryset(request) - return qs.select_related('resitel', 'problem', 'cislo_body') - -admin.site.register(Reseni, ReseniAdmin) - - -### Pohádka - -class PohadkaAdminForm(forms.ModelForm): - class Meta: - model = Pohadka - exclude = [] - autor = UserModelChoiceField(User.objects.filter(is_staff=True)) - uloha = forms.ModelChoiceField( - Problem.objects.filter(typ=Problem.TYP_ULOHA) - ) - - def __init__(self, *args, **kwargs): - super(PohadkaAdminForm, self).__init__(*args, **kwargs) - instance = getattr(self, 'instance', None) - - # viz ProblemAdminForm.__init__ - if instance and instance.pk: - if instance.uloha and instance.uloha.cislo_zadani: - if instance.uloha.cislo_zadani.faze != 'admin': - self.fields['text'].widget.attrs['readonly'] = True - - -class PohadkaAdmin(VersionAdmin): - form = PohadkaAdminForm - view_on_site = False - - def get_kod_ulohy(self, obj): - return obj.uloha.kod_v_rocniku() - get_kod_ulohy.short_description = u'Kód úlohy' - - def get_rocnik(self, obj): - return obj.uloha.cislo_zadani.rocnik.rocnik - get_rocnik.short_description = u'Ročník' - - list_display = [ - '__str__', - 'get_rocnik', - 'get_kod_ulohy', - 'uloha', - 'autor', - 'timestamp' - ] - - get_form = get_form_predvypln_autora - -class PohadkaKProblemuInline(admin.TabularInline): - form = PohadkaAdminForm - model = Pohadka - exclude = [] - extra = 0 - -admin.site.register(Pohadka, PohadkaAdmin) - - -### Problem - -from autocomplete_light.contrib.taggit_field import TaggitField, TaggitWidget - - -class ProblemAdminForm(forms.ModelForm): - text_zadani = forms.CharField(widget=CKEditorUploadingWidget(), required=False, **field_labels(Problem, 'text_zadani')) - text_reseni = forms.CharField(widget=CKEditorUploadingWidget(), required=False, **field_labels(Problem, 'text_reseni')) - text_org = forms.CharField(widget=CKEditorUploadingWidget(), required=False, **field_labels(Problem, 'text_org')) - zamereni = TaggitField(widget=TaggitWidget('TagAutocomplete'), required=False) - autor = UserModelChoiceField(User.objects.filter(is_staff=True)) - opravovatel = UserModelChoiceField(User.objects.filter(is_staff=True), required=False) - class Meta: - model = Problem - exclude = [] - - def __init__(self, *args, **kwargs): - super(ProblemAdminForm, self).__init__(*args, **kwargs) - instance = getattr(self, 'instance', None) - - # Nedovol měnit název a zadání resp. řešení, pokud je cislo_zadani - # resp. cislo_reseni mimo fázi admin. - # - # Nastavení readonly fields sice vypadá lépe (nevygeneruje input tag), - # ale při ukládání změny vypíše admin nespecifikovanou chybu, která je - # způsobena zřejmě tím, že se neodešle žádná hodnota pro povinné pole - # nazev. Navíc by se smazalo nepovinné pole zadání. - # - # Toto řešení je z http://stackoverflow.com/a/325038/4786205. - # - # TODO Django 1.9: použít field s atributem disabled? - if instance and instance.pk: - if instance.cislo_zadani and instance.cislo_zadani.faze != 'admin': - # CKEditor neumí readonly ... - self.fields['text_zadani'] = forms.CharField( - widget=forms.Textarea, - required=False - ) - for f in ['nazev', 'text_zadani', 'body']: - self.fields[f].widget.attrs['readonly'] = True - if instance.cislo_reseni and instance.cislo_reseni.faze != 'admin': - self.fields['text_reseni'] = forms.CharField( - widget=forms.Textarea, - required=False - ) - self.fields['text_reseni'].widget.attrs['readonly'] = True - - -class ProblemAdmin(VersionAdmin): - form = ProblemAdminForm - fieldsets = [ - (None, {'fields': ['nazev', 'typ', 'stav', 'autor', 'zamereni', 'body', 'timestamp', 'import_dakos_id']}), - (u'Vydání', {'fields': ['cislo_zadani', 'kod', 'cislo_reseni', 'opravovatel',]}), - (None, {'fields': ['text_zadani', 'text_reseni', 'text_org',]}), - ] - list_select_related = True - search_fields = ['nazev', 'text_zadani', 'text_reseni', 'text_org'] - view_on_site = Problem.verejne_url - ordering = ['-timestamp'] - - readonly_fields = ['timestamp', 'import_dakos_id'] - - def get_queryset(self, request): - qs = super(ProblemAdmin, self).get_queryset(request) - return qs.select_related('autor', 'opravovatel', 'cislo_zadani', 'cislo_reseni') - - def pocet_reseni(self, obj): - return obj.pocet_reseni - -class ProblemNavrhAdmin(ProblemAdmin): - list_display = ['nazev', 'typ', 'stav', 'autor', 'timestamp'] - list_filter = ['typ', 'zamereni', 'timestamp', 'stav'] - - def get_queryset(self, request): - qs = super(ProblemNavrhAdmin, self).get_queryset(request) - return qs.filter(stav__in=[Problem.STAV_NAVRH, Problem.STAV_SMAZANY]) - - get_form = get_form_predvypln_autora - - -create_modeladmin(ProblemNavrhAdmin, Problem, 'ProblemNavrh', verbose_name=u'Problém (návrh)', verbose_name_plural=u'Problémy (návrhy)') - - -class ProblemZadanyAdmin(ProblemAdmin): - list_display = [ - 'nazev', - 'typ', - 'cislo_zadani_link', - 'cislo_reseni_link', - 'autor', - 'opravovatel', - 'kod', - 'verejne' - ] - list_filter = [ - 'typ', 'zamereni', 'cislo_zadani__cislo', 'cislo_zadani__rocnik' - ] - - def cislo_zadani_link(self, obj): - if not obj.cislo_zadani: - return "" - return mark_safe('{}'.format( - reverse("admin:seminar_cislo_change", args=(obj.cislo_zadani.pk,)), - obj.cislo_zadani - )) - cislo_zadani_link.short_description = u'Číslo zadání' - - # TODO pokud se budou odkazy v adminu více používat, možná by se hodilo je - # nějak zjednodušit, např. tímto? - # https://github.com/gitaarik/django-admin-relation-links - def cislo_reseni_link(self, obj): - if not obj.cislo_reseni: - return "" - return mark_safe('{}'.format( - reverse("admin:seminar_cislo_change", args=(obj.cislo_reseni.pk,)), - obj.cislo_reseni - )) - cislo_reseni_link.short_description = u'Číslo řešení' - - def get_inline_instances(self, request, obj=None): - if obj and obj.typ == Problem.TYP_ULOHA: - inlines = [ReseniKProblemuInline, PohadkaKProblemuInline] - else: - inlines = [ReseniKProblemuInline] - - return [inline(self.model, self.admin_site) for inline in inlines] - - def get_queryset(self, request): - qs = super(ProblemZadanyAdmin, self).get_queryset(request) - return qs.filter(stav=Problem.STAV_ZADANY) - - get_form = get_form_predvypln_autora - -create_modeladmin(ProblemZadanyAdmin, Problem, 'ProblemZadany', verbose_name=u'Problém (zadaný)', verbose_name_plural=u'Problémy (zadané)') - -#admin.site.register(Problem, ProblemAdmin) - -### Prispevek (k tematkum) - -class PrispevekAdminForm(forms.ModelForm): - text_org = forms.CharField(widget=CKEditorUploadingWidget(), required=False, - **field_labels(Prispevek, 'text_org')) - text_resitel = forms.CharField(widget=CKEditorUploadingWidget(), required=False, - **field_labels(Prispevek, 'text_resitel')) - - class Meta: - model = Prispevek - exclude = [] - -class PrispevekAdmin(VersionAdmin): - form = PrispevekAdminForm - list_display = ['nazev', 'problem', 'reseni', 'zverejnit'] - -admin.site.register(Prispevek, PrispevekAdmin) - -### Soustredeni - -class SoustredeniAdminForm(forms.ModelForm): - text = forms.CharField(widget=CKEditorUploadingWidget(), required=False, **field_labels(Soustredeni, 'text')) - class Meta: - model = Soustredeni - exclude = [] - -class SoustredeniAdmin(VersionAdmin): - form = SoustredeniAdminForm - fieldsets = [ - (None, {'fields': ['rocnik', 'misto', 'typ', 'verejne_db', 'exportovat', 'text']}), - (u'Data', {'fields': ['datum_zacatku', 'datum_konce']}), - ] - list_display = ['rocnik', 'misto', 'datum_zacatku', 'typ', 'exportovat', 'verejne'] - inlines = [Soustredeni_UcastniciInline, Soustredeni_OrganizatoriInline] - list_filter = ['typ', 'rocnik'] - view_on_site = Soustredeni.verejne_url - actions = [ - make_set_action('verejne_db', True, u'Zveřejnit soustředění'), - make_set_action('verejne_db', False, u'Skrýt (zneveřejnit) soustředění'), - make_set_action('exportovat', True, u'Nastavit pro AESOP export'), - make_set_action('exportovat', False, u'Skrýt pro AESOP export'), - ] - -admin.site.register(Soustredeni, SoustredeniAdmin) - -### Konfery -class KonferaAdminForm(forms.ModelForm): - class Meta: - model=Konfera - exclude = [] - -class KonferaAdmin(VersionAdmin): - form = KonferaAdminForm - list_filter = ['soustredeni'] - list_display = ['nazev','soustredeni','organizator','typ_prezentace'] -# inlines = [Konfera_UcastniciInline] - -admin.site.register(Konfera,KonferaAdmin) - -### Novinky - -class NovinkyAdminForm(forms.ModelForm): - text = forms.CharField(widget=CKEditorUploadingWidget(), required=False, - **field_labels(Novinky, 'text')) - autor = UserModelChoiceField(User.objects.filter(is_staff=True)) - - class Meta: - model = Novinky - exclude = [] - -def zverejnit_novinky(modeladmin, request, queryset): - ''' zverejni vybrane novinky ''' - for novinka in queryset: - novinka.zverejneno = True - novinka.save() - zverejnit_novinky.short_description = 'Zveřejnit vybané novinky' - -def zneverejnit_novinky(modeladmin, request, queryset): - ''' zneverejni vybrane novinky''' - for novinka in queryset: - novinka.zverejneno = False - novinka.save() - zneverejnit_novinky.short_description = 'Zneveřejnit vybrané novinky' - - -class NovinkyAdmin(VersionAdmin): - form = NovinkyAdminForm - list_display = ['datum', 'autor', 'text', 'zverejneno', 'obrazek'] - actions = [zverejnit_novinky, zneverejnit_novinky] - - get_form = get_form_predvypln_autora - - -admin.site.register(Novinky, NovinkyAdmin) - -### Organizator - -def jmeno_organizatora(obj): - ''' vraci jmeno organizatora ''' - jmeno = obj.user.first_name - if obj.prezdivka: - jmeno = jmeno + ' "' + obj.prezdivka + '"' - jmeno = jmeno + ' ' + obj.user.last_name - if jmeno == ' ': # zobrazeni bezejmennych orgu - return 'org' - return jmeno -jmeno_organizatora.short_description = 'Jméno organizátora' - -def je_organizator_aktivni(obj): - ''' zjisti, zda-li je organizator aktivni ''' - return obj.user.is_active -je_organizator_aktivni.short_description = 'Aktivní' -je_organizator_aktivni.boolean = True - -def zaktivovat_organizatory(modeladmin, request, queryset): - ''' vybrane organizatory oznaci jako aktivni ''' - for org in queryset: - org.user.is_active = True - org.user.save() -zaktivovat_organizatory.short_description = 'Zaktivovat organizátory' - -def deaktivovat_organizatory(modeladmin, request, queryset): - ''' deaktivuje vybrane organizatory ''' - for org in queryset: - org.user.is_active = False - org.user.save() -deaktivovat_organizatory.short_description = 'Deaktivovat organizátory' - - -@admin.register(Organizator) -class OrganizatorAdmin(VersionAdmin): - list_filter = ['organizuje_do_roku'] - list_display = [jmeno_organizatora, je_organizator_aktivni,] - actions = [zaktivovat_organizatory, deaktivovat_organizatory,] - + model = m.Resitel + extra = 1 + +class SoustredeniUcastniciInline(admin.TabularInline): + model = m.Soustredeni_Ucastnici + extra = 1 + fields = ['resitel','poznamka'] + autocomplete_fields = ['resitel'] + ordering = ['resitel__osoba__jmeno', 'resitel__osoba__prijmeni'] + formfield_overrides = { + models.TextField: {'widget': widgets.TextInput} + } + + def get_queryset(self,request): + qs = super().get_queryset(request) + return qs.select_related('resitel','soustredeni') + +class SoustredeniOrganizatoriInline(admin.TabularInline): + model = m.Soustredeni.organizatori.through + extra = 1 + fields = ['organizator','poznamka'] + autocomplete_fields = ['organizator'] + ordering = ['organizator__osoba__jmeno','organizator__prijmeni'] + formfield_overrides = { + models.TextField: {'widget': widgets.TextInput} + } + + def get_queryset(self,request): + qs = super().get_queryset(request) + return qs.select_related('organizator', 'soustredeni') + + +@admin.register(m.Soustredeni) +class SoustredeniAdmin(admin.ModelAdmin): + model = m.Soustredeni + inline_type = 'tabular' + inlines = [SoustredeniUcastniciInline, SoustredeniOrganizatoriInline] + + +class PrilohaReseniInline(admin.TabularInline): + model = m.PrilohaReseni + extra = 1 +admin.site.register(m.PrilohaReseni) + +class Reseni_ResiteleInline(admin.TabularInline): + model = m.Reseni_Resitele + + +@admin.register(m.Reseni) +class ReseniAdmin(ReverseModelAdmin): + base_model = m.Reseni + inline_type = 'tabular' + inline_reverse = ['text_cely','resitele'] + exclude = ['text_zkraceny', 'text_zkraceny_set'] + inlines = [PrilohaReseniInline] +# FAIL in template +# inlines = [PrilohaReseniInline,Reseni_ResiteleInline] + +admin.site.register(m.Hodnoceni) +admin.site.register(m.Pohadka) +admin.site.register(m.Obrazek) + +# Polymorfismus pro stromy +# TODO: Inlines podle https://django-polymorphic.readthedocs.io/en/stable/admin.html + +@admin.register(m.TreeNode) +class TreeNodeAdmin(PolymorphicParentModelAdmin): + base_model = m.TreeNode + child_models = [ + m.RocnikNode, + m.CisloNode, + m.MezicisloNode, + m.TemaVCisleNode, + m.UlohaZadaniNode, + m.PohadkaNode, + m.UlohaVzorakNode, + m.TextNode, + m.CastNode, + m.OrgTextNode, + ] + + actions = ['aktualizuj_nazvy'] + + # XXX: nejspíš je to totální DB HOG, nechcete to použít moc často. + def aktualizuj_nazvy(self, request, queryset): + newqs = queryset.get_real_instances() + for tn in newqs: + tn.aktualizuj_nazev() + tn.save() + self.message_user(request, "Názvy aktualizovány.") + aktualizuj_nazvy.short_description = "Aktualizuj vybraným TreeNodům názvy" + +@admin.register(m.RocnikNode) +class RocnikNodeAdmin(PolymorphicChildModelAdmin): + base_model = m.RocnikNode + show_in_index = True + +@admin.register(m.CisloNode) +class CisloNodeAdmin(PolymorphicChildModelAdmin): + base_model = m.CisloNode + show_in_index = True + +@admin.register(m.MezicisloNode) +class MezicisloNodeAdmin(PolymorphicChildModelAdmin): + base_model = m.MezicisloNode + show_in_index = True + +@admin.register(m.TemaVCisleNode) +class TemaVCisleNodeAdmin(PolymorphicChildModelAdmin): + base_model = m.TemaVCisleNode + show_in_index = True + +@admin.register(m.UlohaZadaniNode) +class UlohaZadaniNodeAdmin(PolymorphicChildModelAdmin): + base_model = m.UlohaZadaniNode + show_in_index = True + +@admin.register(m.PohadkaNode) +class PohadkaNodeAdmin(PolymorphicChildModelAdmin): + base_model = m.PohadkaNode + show_in_index = True + +@admin.register(m.UlohaVzorakNode) +class UlohaVzorakNodeAdmin(PolymorphicChildModelAdmin): + base_model = m.UlohaVzorakNode + show_in_index = True + +@admin.register(m.TextNode) +class TextNodeAdmin(PolymorphicChildModelAdmin): + base_model = m.TextNode + show_in_index = True + +@admin.register(m.CastNode) +class TextNodeAdmin(PolymorphicChildModelAdmin): + base_model = m.CastNode + show_in_index = True + fields = ('nadpis',) + +@admin.register(m.OrgTextNode) +class TextNodeAdmin(PolymorphicChildModelAdmin): + base_model = m.OrgTextNode + show_in_index = True + + +admin.site.register(m.Nastaveni, SingletonModelAdmin) +admin.site.register(m.Novinky) diff --git a/seminar/autocomplete_light_registry.py b/seminar/autocomplete_light_registry.py.old similarity index 72% rename from seminar/autocomplete_light_registry.py rename to seminar/autocomplete_light_registry.py.old index 13318877..64590adf 100644 --- a/seminar/autocomplete_light_registry.py +++ b/seminar/autocomplete_light_registry.py.old @@ -2,7 +2,7 @@ from autocomplete_light import shortcuts as autocomplete_light -from models import Skola, Resitel, Problem, Organizator +from .models import Skola, Resitel, Problem, Organizator from taggit.models import Tag @@ -13,21 +13,21 @@ class SkolaAutocomplete(autocomplete_light.AutocompleteModelBase): model = Skola - search_fields=['nazev', 'mesto', 'ulice'] + search_fields = ['nazev', 'mesto', 'ulice'] split_words = True limit_choices = 15 - attrs={ + attrs = { # This will set the input placeholder attribute: - 'placeholder': u'Škola', + 'placeholder': 'Škola', # This will set the yourlabs.Autocomplete.minimumCharacters # options, the naming conversion is handled by jQuery 'data-autocomplete-minimum-characters': 1, } - widget_attrs={ + widget_attrs = { 'data-widget-maximum-values': 15, 'class': 'modern-style', } @@ -39,24 +39,24 @@ class ResitelAutocomplete(autocomplete_light.AutocompleteModelBase): model = Resitel - search_fields=['jmeno', 'prijmeni'] + search_fields = ['jmeno', 'prijmeni'] split_words = False limit_choices = 15 def choice_label(self, resitel): - return u"%s, %s (%s)" % (resitel.plne_jmeno(), resitel.mesto, resitel.rok_maturity) + return "%s, %s (%s)" % (resitel.plne_jmeno(), resitel.mesto, resitel.rok_maturity) - attrs={ + attrs= { # This will set the input placeholder attribute: - 'placeholder': u'Řešitel', + 'placeholder': 'Řešitel', # This will set the yourlabs.Autocomplete.minimumCharacters # options, the naming conversion is handled by jQuery 'data-autocomplete-minimum-characters': 1, } - widget_attrs={ + widget_attrs = { 'data-widget-maximum-values': 15, # Enable modern-style widget ! 'class': 'modern-style', @@ -68,26 +68,26 @@ class OrganizatorAutocomplete(autocomplete_light.AutocompleteModelBase): model = Organizator - search_fields=['user__first_name', 'user__last_name', 'prezdivka'] + search_fields = ['user__first_name', 'user__last_name', 'prezdivka'] split_words = False limit_choices = 15 def choice_label(self, organizator): - return u"%s '%s' %s" % (organizator.user.first_name, + return "%s '%s' %s" % (organizator.user.first_name, organizator.prezdivka, organizator.user.last_name) - attrs={ + attrs = { # This will set the input placeholder attribute: - 'placeholder': u'Organizátor', + 'placeholder': 'Organizátor', # This will set the yourlabs.Autocomplete.minimumCharacters # options, the naming conversion is handled by jQuery 'data-autocomplete-minimum-characters': 1, } - widget_attrs={ + widget_attrs = { 'data-widget-maximum-values': 15, # Enable modern-style widget ! 'class': 'modern-style', @@ -101,7 +101,7 @@ class ProblemAutocomplete(autocomplete_light.AutocompleteModelBase): model = Problem - search_fields=['nazev'] + search_fields = ['nazev'] split_words = False @@ -111,28 +111,29 @@ class ProblemAutocomplete(autocomplete_light.AutocompleteModelBase): if p.stav == Problem.STAV_ZADANY: popisek = "" try: - popisek = u"%s (%s, %s.%s)" % (p.nazev, p.typ, p.cislo_zadani.rocnik.rocnik, p.kod_v_rocniku()) + popisek = "%s (%s, %s.%s)".format(p.nazev, p.typ, p.cislo_zadani.rocnik.rocnik, p.kod_v_rocniku()) except: - #popisek = u"%s (%s, %s.%s)" % (p.nazev, p.typ, p.stav) + #popisek = "%s (%s, %s.%s)".format(p.nazev, p.typ, p.stav) popisek = "CHYBA" return popisek else: - return u"%s (%s, %s)" % (p.nazev, p.typ, p.stav) + return "%s (%s, %s)".format(p.nazev, p.typ, p.stav) - attrs={ + attrs = { # This will set the input placeholder attribute: - 'placeholder': u'Problém', + 'placeholder': 'Problém', # This will set the yourlabs.Autocomplete.minimumCharacters # options, the naming conversion is handled by jQuery 'data-autocomplete-minimum-characters': 1, } - widget_attrs={ + widget_attrs = { 'data-widget-maximum-values': 10, # Enable modern-style widget ! 'class': 'modern-style', } -autocomplete_light.register(ProblemAutocomplete) +#FIXME Nefunguje, nevime proc +#autocomplete_light.register(ProblemAutocomplete) diff --git a/seminar/export.py b/seminar/export.py index 86bce0ac..d2dcdd81 100644 --- a/seminar/export.py +++ b/seminar/export.py @@ -1,105 +1,109 @@ import datetime, django from django.shortcuts import get_object_or_404, render from django.http import HttpResponse -from django.core.urlresolvers import reverse +from django.urls import reverse from django.views import generic from django.utils.encoding import force_text from .models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni -from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva +#from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva from .ovvpfile import OvvpFile +from seminar import views +from seminar.views import vysledkovka +from seminar.utils import aktivniResitele class ExportIndexView(generic.View): - def get(self, request): + def get(self, request): + ls = [] + for r in Rocnik.objects.filter(exportovat = True): + url = reverse('seminar_export_rocnik', kwargs={'prvni_rok': r.prvni_rok}) + ls.append(url.split('/')[-1]) + for s in Soustredeni.objects.filter(exportovat = True): + url = reverse('seminar_export_sous', kwargs={'datum_zacatku': s.datum_zacatku.isoformat()}) + ls.append(url.split('/')[-1]) - ls = [] - for r in Rocnik.objects.filter(exportovat = True): - url = reverse('seminar_export_rocnik', kwargs={'prvni_rok': r.prvni_rok}) - ls.append(url.split('/')[-1]) - for s in Soustredeni.objects.filter(exportovat = True): - url = reverse('seminar_export_sous', kwargs={'datum_zacatku': s.datum_zacatku.isoformat()}) - ls.append(url.split('/')[-1]) - - return HttpResponse('\n'.join(ls) + '\n', content_type='text/plain; charset=utf-8') + return HttpResponse('\n'.join(ls) + '\n', content_type='text/plain; charset=utf-8') def default_ovvpfile(event, rocnik): - of = OvvpFile() - of.headers['version'] = '1' - of.headers['event'] = event - of.headers['year'] = force_text(rocnik.prvni_rok) - of.headers['date'] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") - of.headers['id-scope'] = 'mam' - of.headers['id-generation'] = '1' - return of + of = OvvpFile() + of.headers['version'] = '1' + of.headers['event'] = event + of.headers['year'] = force_text(rocnik.prvni_rok) + of.headers['date'] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + of.headers['id-scope'] = 'mam' + of.headers['id-generation'] = '1' + return of class ExportSousView(generic.View): - def get(self, request, datum_zacatku=None): - try: - dz = django.utils.dateparse.parse_date(datum_zacatku) - except: - dz = None - if dz is None: - raise django.http.Http404() - - s = get_object_or_404(Soustredeni, datum_zacatku=dz, exportovat=True) - - akce = {Soustredeni.TYP_JARNI: 'MaM.sous.jaro', - Soustredeni.TYP_PODZIMNI: 'MaM.sous.podzim', - Soustredeni.TYP_VIKEND: 'MaM.vikend', - }[s.typ] - - of = default_ovvpfile(akce, s.rocnik) - of.headers['x-event-begin'] = s.datum_zacatku.isoformat() - of.headers['x-event-end'] = s.datum_konce.isoformat() - of.headers['x-event-location'] = s.misto - of.headers['comment'] = u'MaM-Web export ucastniku soustredeni v {x-event-location} od {x-event-begin} do {x-event-end}'.format(**of.headers) - of.columns = ['id', 'name', 'surname', 'gender', 'email', 'end-year', 'school', 'school-name'] - - for u in s.ucastnici.all(): - of.rows.append(u.export_row()) - - return of.to_HttpResponse() - - + def get(self, request, datum_zacatku=None): + try: + dz = django.utils.dateparse.parse_date(datum_zacatku) + except: + dz = None + if dz is None: + raise django.http.Http404() + + s = get_object_or_404(Soustredeni, datum_zacatku=dz, exportovat=True) + + akce = {Soustredeni.TYP_JARNI: 'MaM.sous.jaro', + Soustredeni.TYP_PODZIMNI: 'MaM.sous.podzim', + Soustredeni.TYP_VIKEND: 'MaM.vikend', + }[s.typ] + + of = default_ovvpfile(akce, s.rocnik) + of.headers['x-event-begin'] = s.datum_zacatku.isoformat() + of.headers['x-event-end'] = s.datum_konce.isoformat() + of.headers['x-event-location'] = s.misto + of.headers['comment'] = u'MaM-Web export ucastniku soustredeni v {x-event-location} od {x-event-begin} do {x-event-end}'.format(**of.headers) + of.columns = ['id', 'name', 'surname', 'gender', 'email', 'end-year', 'school', 'school-name'] + + for u in s.ucastnici.all(): + of.rows.append(u.export_row()) + + return of.to_HttpResponse() + +# POZOR! Předělání na nový model neotestováno v reálu (ale zase jen drobné změny) class ExportRocnikView(generic.View): - def get(self, request, prvni_rok=None): - try: - pr = int(prvni_rok) - except: - pr = None - if pr is None: - raise django.http.Http404() - - rocnik = get_object_or_404(Rocnik, prvni_rok=pr, exportovat=True) - cislo = rocnik.posledni_zverejnena_vysledkovka_cislo() - vysledky = VysledkyKCisluZaRocnik.objects.filter(cislo = cislo).select_related("resitel").order_by('-body').all() - - of = default_ovvpfile('MaM.rocnik', rocnik) - of.headers['comment'] = u'MaM-Web export aktivnich resitelu rocniku {rocnik} do cisla {cislo}'.format( - rocnik=rocnik, cislo=cislo) - of.columns = ['id', 'name', 'surname', 'gender', 'born', 'email', 'end-year', - 'street', 'town', 'postcode', 'country', 'spam-flag', 'spam-date', - 'school', 'school-name', 'points', 'rank',] - - posledni_body = 100000 - posledni_poradi = 0 - for vi in range(len(vysledky)): - - v = vysledky[vi] - rd = v.resitel.export_row() - - if posledni_body > v.body: - posledni_body = v.body - posledni_poradi = vi + 1 - rd['rank'] = posledni_poradi - rd['points'] = v.body - - of.rows.append(rd) - - return of.to_HttpResponse() - - + def get(self, request, prvni_rok=None): + try: + pr = int(prvni_rok) + except: + pr = None + if pr is None: + raise django.http.Http404() + + rocnik = get_object_or_404(Rocnik, prvni_rok=pr, exportovat=True) + cislo = rocnik.posledni_zverejnena_vysledkovka_cislo() + resitele = aktivniResitele(cislo, True) + slovnik_body = vysledkovka.secti_body_za_rocnik(cislo, resitele, False) + setrizeni_resitele, body = vysledkovka.setrid_resitele_a_body(slovnik_body) + + of = default_ovvpfile('MaM.rocnik', rocnik) + of.headers['comment'] = u'MaM-Web export aktivnich resitelu rocniku {rocnik} do cisla {cislo}'.format(rocnik=rocnik, cislo=cislo) + of.columns = ['id', 'name', 'surname', 'gender', 'born', 'email', 'end-year', + 'street', 'town', 'postcode', 'country', 'spam-flag', 'spam-date', + 'school', 'school-name', 'points', 'rank',] + + resitele_slovnik = {} + for r in resitele: + resitele_slovnik[r.id] = r + + # počítání pořadí řešitelů + posledni_body = 100000 + posledni_poradi = 0 + for i in range(len(setrizeni_resitele)): + rd = resitele_slovnik[setrizeni_resitele[i]].export_row() + + if posledni_body > body[i]: + posledni_body = body[i] + posledni_poradi = i + 1 + rd['rank'] = posledni_poradi + rd['points'] = body[i] + + of.rows.append(rd) + + return of.to_HttpResponse() diff --git a/seminar/forms.py b/seminar/forms.py new file mode 100644 index 00000000..39d06513 --- /dev/null +++ b/seminar/forms.py @@ -0,0 +1,424 @@ +from django import forms +from dal import autocomplete +from django.contrib.auth.forms import PasswordResetForm +from django.core.exceptions import ObjectDoesNotExist +from django.contrib.auth.models import User +from django.forms import formset_factory +from django.forms.models import inlineformset_factory + +from .models import Skola, Resitel, Osoba, Problem +import seminar.models as m + +from datetime import date +import logging + +# pro přidání políčka do formuláře je potřeba +# - mít v modelu tu položku, kterou chci upravovat +# - přidat do views (prihlaskaView, resitelEditView) +# - přidat do forms +# - includovat do html + +class DateInput(forms.DateInput): + # aby se datum dalo vybírat z kalendáře + input_type = 'date' + +class TelInput(forms.TextInput): + # tohle je možná k niřemu, ale alepsoň to mění input type a nic to nekazí + input_type = 'tel' + input_pattern="^[+]?[()/0-9. -]{9,}$" + +class LoginForm(forms.Form): + username = forms.CharField(label='Přihlašovací jméno', + max_length=256, + required=True) + password = forms.CharField( + label='Heslo', + max_length=256, + required=True, + widget=forms.PasswordInput()) + + +class PrihlaskaForm(PasswordResetForm): + username = forms.CharField(label='Přihlašovací jméno', + max_length=256, + required=True, + help_text='Tímto jménem se následně budeš přihlašovat pro odevzdání řešení a další činnosti v semináři') + + jmeno = forms.CharField(label='Jméno', max_length=256, required=True) + prijmeni = forms.CharField(label='Příjmení', max_length=256, required=True) + pohlavi_muz = forms.ChoiceField(label='Pohlaví', + choices = ((True,'muž'),(False,'žena')), required=True) + email = forms.EmailField(label='E-mail',max_length=256, required=True) + telefon = forms.CharField(widget=TelInput(),label='Telefon',max_length=256, required=False) + datum_narozeni = forms.DateField(widget=DateInput(),label='Datum narození', required=False) + ulice = forms.CharField(label='Ulice', max_length=256, required=False) + mesto = forms.CharField(label='Město', max_length=256, required=False) + psc = forms.CharField(label='PSČ', max_length=32, required=False) + stat = forms.ChoiceField(label='Stát', + choices = (('CZ', 'Česká Republika'), + ('SK', 'Slovenská Republika'), + ('other', 'Jiné')), + required=False) + stat_text = forms.CharField(label='Stát', max_length=256, required=False) + + skola = forms.ModelChoiceField(label="Škola", + queryset=Skola.objects.all(), + widget=autocomplete.ModelSelect2( + url='autocomplete_skola', + attrs = {'data-placeholder--id': '-1', + 'data-placeholder--text' : '---', + 'data-allow-clear': 'true'}) + ,required=False) + + skola_nazev = forms.CharField(label='Název školy', max_length=256, required=False) + skola_adresa = forms.CharField(label='Adresa školy', max_length=256, required=False) + +# trida = forms.CharField(label='Třída',max_length=10, required=True) + + rok_maturity = forms.IntegerField( + label='Rok maturity', + min_value=date.today().year, + max_value=date.today().year+8, + required=True) + zasilat = forms.ChoiceField(label='Kam zasílat čísla a řešení',choices = Resitel.ZASILAT_CHOICES, required=True) + zasilat_cislo_emailem = forms.BooleanField(label='Chci dostávat e-mailem upozornění na vydání nového čísla', required=False) + + gdpr = forms.BooleanField(label='Souhlasím se zpracováním osobních údajů', required=True) + spam = forms.BooleanField(label='Souhlasím se zasíláním materiálů od MFF UK', required=False) + + def clean_username(self): + err_logger = logging.getLogger('seminar.prihlaska.problem') + username = self.cleaned_data.get('username') + try: + User.objects.get(username=username) + msg = "Username {} exists".format(username) + err_logger.info(msg) + raise forms.ValidationError('Přihlašovací jméno je již použito') + + except ObjectDoesNotExist: + pass + return username + + def clean_email(self): + err_logger = logging.getLogger('seminar.prihlaska.problem') + email = self.cleaned_data.get('email') + try: + osoba = Osoba.objects.get(email=email) + msg = "Email {} exists".format(email) + if osoba.user is not None: + err_logger.info(msg) + raise forms.ValidationError('E-mail je již použit') + else: + msg += ', but currently has no User, so allowing registration.' + err_logger.info(msg) + + except ObjectDoesNotExist: + pass + return email + + + def clean(self): + super().clean() + + err_logger = logging.getLogger('seminar.prihlaska.problem') + + data = self.cleaned_data + if data.get('stat') != 'other' and data.get('stat_text') != '': + self.add_error('stat',forms.ValidationError('Nelze mít vybraný stát z menu a zároven zapsaný textem')) + if data.get('skola') and (data.get('skola_nazev') or data.get('skola_adresa')): + self.add_error('skola',forms.ValidationError('Pokud je škola v seznamu, nevypisujte ji ručně, pokud není, zrušte výběr ze seznamu (křížek vpravo)')) + if not data.get('skola'): + if data.get('skola_nazev')=='' and data.get('skola_adresa')=='': + self.add_error('skola',forms.ValidationError('Je nutné vyplnit školu')) + elif data.get('skola_nazev')=='': + self.add_error('skola_nazev',forms.ValidationError('Je nutné vyplnit název školy')) + elif data.get('skola_adresa')=='': + self.add_error('skola_adresa',forms.ValidationError('Je nutné vyplnit adresu školy')) + + +class ProfileEditForm(forms.Form): + username = forms.CharField(label='Přihlašovací jméno', + max_length=256, + required=False, + disabled=True) + + jmeno = forms.CharField(label='Jméno', max_length=256, required=True) + prijmeni = forms.CharField(label='Příjmení', max_length=256, required=True) + pohlavi_muz = forms.ChoiceField(label='Pohlaví', + choices = ((True,'muž'),(False,'žena')), required=True) + email = forms.EmailField(label='E-mail',max_length=256, required=True) + telefon = forms.CharField(widget=TelInput(),label='Telefon',max_length=256, required=False) + datum_narozeni = forms.DateField(widget=DateInput(),label='Datum narození', required=False) + ulice = forms.CharField(label='Ulice', max_length=256, required=False) + mesto = forms.CharField(label='Město', max_length=256, required=False) + psc = forms.CharField(label='PSČ', max_length=32, required=False) + stat = forms.ChoiceField(label='Stát', + choices = (('CZ', 'Česká republika'), + ('SK', 'Slovenská republika'), + ('other', 'Jiné')), + required=False) + stat_text = forms.CharField(label='Stát', max_length=256, required=False) + + skola = forms.ModelChoiceField(label="Škola", + queryset=Skola.objects.all(), + widget=autocomplete.ModelSelect2( + url='autocomplete_skola', + attrs = {'data-placeholder--id': '-1', + 'data-placeholder--text' : '---', + 'data-allow-clear': 'true'}) + ,required=False) + + skola_nazev = forms.CharField(label='Název školy', max_length=256, required=False) + skola_adresa = forms.CharField(label='Adresa školy', max_length=256, required=False) + +# trida = forms.CharField(label='Třída',max_length=10, required=True) + + rok_maturity = forms.IntegerField( + label='Rok maturity', + min_value=date.today().year, + max_value=date.today().year+8, + required=True) + zasilat = forms.ChoiceField(label='Kam zasílat čísla a řešení',choices = Resitel.ZASILAT_CHOICES, required=True) + zasilat_cislo_emailem = forms.BooleanField(label='Chci dostávat email s upozorněním na vydání nového čísla', required=False) + + spam = forms.BooleanField(label='Souhlasím se zasíláním materiálů od MFF UK', required=False) +# def clean_username(self): +# err_logger = logging.getLogger('seminar.prihlaska.problem') +# username = self.cleaned_data.get('username') +# try: +# User.objects.get(username=username) +# msg = "Username {} exists".format(username) +# err_logger.info(msg) +# raise forms.ValidationError('Přihlašovací jméno je již použito') +# +# except ObjectDoesNotExist: +# pass +# return username +# + def clean_email(self): + err_logger = logging.getLogger('seminar.prihlaska.problem') + email = self.cleaned_data.get('email') + try: + Osoba.objects.exclude(user__username=self.username).get(email=email) + msg = "Email {} exists (in edit)".format(email) + err_logger.info(msg) + raise forms.ValidationError('Email je již použit') + + except ObjectDoesNotExist: + pass + return email + #def clean(self): + # super().clean() + # + # err_logger = logging.getLogger('seminar.prihlaska.problem') + + # data = self.cleaned_data + # if data.get('password') != data.get('password_check'): + # self.add_error('password_check',forms.ValidationError('Hesla se neshodují')) + # if data.get('stat') != '' and data.get('stat_text') != '': + # self.add_error('stat',forms.ValidationError('Nelze mít vybraný stát z menu a zároven zapsaný textem')) + # if data.get('skola') and (data.get('skola_nazev') or data.get('skola_adresa')): + # self.add_error('skola',forms.ValidationError('Pokud je škola v seznamu, nevypisujte ji ručně, pokud není, zrušte výběr ze seznamu (křížek vpravo)')) + # if not data.get('skola'): + # if data.get('skola_nazev')=='' and data.get('skola_adresa')=='': + # self.add_error('skola',forms.ValidationError('Je nutné vyplnit školu')) + # elif data.get('skola_nazev')=='': + # self.add_error('skola_nazev',forms.ValidationError('Je nutné vyplnit název školy')) + # elif data.get('skola_adresa')=='': + # self.add_error('skola_adresa',forms.ValidationError('Je nutné vyplnit adresu školy')) + +class PoMaturiteProfileEditForm(ProfileEditForm): + rok_maturity = forms.IntegerField( + label='Rok maturity', + required=True) + +class VlozReseniForm(forms.Form): + #FIXME jen podproblémy daného problému + problem = forms.ModelChoiceField(label='Problém',queryset=m.Problem.objects.all()) + # to_field_name + #problem = models.ManyToManyField(Problem, verbose_name='problém', help_text='Problém', + # through='Hodnoceni') + + # FIXME pridat vice resitelu + resitel = forms.ModelChoiceField(label="Řešitel", + queryset=Resitel.objects.all(), + widget=autocomplete.ModelSelect2( + url='autocomplete_resitel', + attrs = {'data-placeholder--id': '-1', + 'data-placeholder--text' : '---', + 'data-allow-clear': 'true'}) + ) + + + #resitele = models.ManyToManyField(Resitel, verbose_name='autoři řešení', + # help_text='Seznam autorů řešení', through='Reseni_Resitele') + + cas_doruceni = forms.DateField(widget=DateInput(),label="Čas doručení") + + #cas_doruceni = models.DateTimeField('čas_doručení', default=timezone.now, blank=True) + + forma = forms.ChoiceField(label="Forma řešení",choices = m.Reseni.FORMA_CHOICES) + #forma = models.CharField('forma řešení', max_length=16, choices=FORMA_CHOICES, blank=False, + # default=FORMA_EMAIL) + + poznamka = forms.CharField(label='Neveřejná poznámka', required=False) + #poznamka = models.TextField('neveřejná poznámka', blank=True, + # help_text='Neveřejná poznámka k řešení (plain text)') + + #TODO body do cisla + #TODO prilohy + + ##def __init__(self, *args, **kwargs): + ## super().__init__(*args, **kwargs) + ## #self.fields['favorite_color'] = forms.ChoiceField(choices=[(color.id, color.name) for color in Resitel.objects.all()]) + +class NahrajReseniForm(forms.ModelForm): + class Meta: + model = m.Reseni + fields = ('problem',) + help_texts = {'problem':''} # Nezobrazovat help text ve formuláři + + widgets = {'problem': + autocomplete.ModelSelect2Multiple( + url='autocomplete_problem_odevzdatelny', + attrs = {'data-placeholder--id': '-1', + 'data-placeholder--text' : '---', + 'data-allow-clear': 'true'}, + ) + } + +ReseniSPrilohamiFormSet = inlineformset_factory(m.Reseni,m.PrilohaReseni, + form = NahrajReseniForm, + fields = ('soubor','res_poznamka'), + widgets = {'res_poznamka':forms.TextInput()}, + extra = 1, + can_delete = False, + + ) + +class NahrajObrazekKTreeNoduForm(forms.ModelForm): + class Meta: + model = m.Obrazek + fields = ('na_web',) + + +class JednoHodnoceniForm(forms.ModelForm): + class Meta: + model = m.Hodnoceni + fields = ('problem', 'body', 'cislo_body') + widgets = { + 'problem': autocomplete.ModelSelect2( + url='autocomplete_problem_odevzdatelny', # FIXME: Dovolit i starší? + ) + } + +OhodnoceniReseniFormSet = formset_factory(JednoHodnoceniForm, + extra = 0, + ) + +# FIXME: Ideálně by mělo být součástí třídy níž, ale neumím to udělat +DATE_FORMAT = '%Y-%m-%d' + +class OdevzdavatkoTabulkaFiltrForm(forms.Form): + """Form pro filtrování přehledové odevzdávátkové tabulky + + Inspirováno https://kam.mff.cuni.cz/mffzoom/""" + + # Věci definované níž se importují i ve views pro odevzdávátko (Inspirováno https://docs.djangoproject.com/en/3.1/ref/models/fields/#field-choices) + + RESITELE_RELEVANTNI = 'relevantni' + RESITELE_NEODMATUROVAVSI = 'neodmaturovavsi' + RESITELE_CHOICES = [ + (RESITELE_RELEVANTNI, 'Relevantní řešitelé'), # I.e. nezobrazovat prázdné řádky tabulky + (RESITELE_NEODMATUROVAVSI, 'Všichni bez maturity'), + # Možná: všechny vč. historických? + ] + + PROBLEMY_MOJE = 'moje' + PROBLEMY_LETOSNI = 'letosni' + PROBLEMY_CHOICES = [ + (PROBLEMY_MOJE, 'Moje problémy'), # Letošní problémy, které mají v sobě nebo v nadproblémech přiřazeného daného orga + (PROBLEMY_LETOSNI, 'Všechny letošní'), + # TODO: *hlavní problémy, možná všechny... + # XXX: Chtělo by to i "aktuálně zadané... + ] + + # TODO: Typy problémů (problémy, úlohy, ostatní, všechny)? Jen některá řešení (obodovaná/neobodovaná, víc řešitelů, ...)? + + + @classmethod + def gen_terminy(cls): + import datetime + from time import strftime + + from django.db.utils import OperationalError + try: + aktualni_rocnik = m.Nastaveni.get_solo().aktualni_rocnik + aktualni_cislo = m.Nastaveni.get_solo().aktualni_cislo + except OperationalError: + # django.db.utils.OperationalError: no such table: seminar_nastaveni + # Nemáme databázi, takže to selhalo. Pro jistotu vrátíme aspoň dvě možnosti, ať to nepadá dál + logger = logging.getLogger(__name__) + logger.error("Rozbitá databáze (před počátečními migracemi?)") + return [('broken', 'Je to rozbitý'), ('fubar', 'Nefunguje to')] + + result = [] + + for cislo in m.Cislo.objects.filter( + rocnik=aktualni_rocnik, + poradi__lte=aktualni_cislo.poradi, + ).reverse(): # Standardně se řadí od nejnovějšího čísla + # Předem je mi líto kohokoliv, kdo tyhle řádky bude číst... + if cislo.datum_vydani is not None and cislo.datum_vydani <= datetime.date.today(): + result.append(( + strftime(DATE_FORMAT, cislo.datum_vydani.timetuple()), + f"Vydání {cislo.poradi}. čísla")) + if cislo.datum_preddeadline is not None and cislo.datum_preddeadline <= datetime.date.today(): + result.append(( + strftime(DATE_FORMAT, cislo.datum_preddeadline.timetuple()), + f"Předdeadline {cislo.poradi}. čísla")) + if cislo.datum_deadline_soustredeni is not None and cislo.datum_deadline_soustredeni <= datetime.date.today(): + result.append(( + strftime(DATE_FORMAT, cislo.datum_deadline_soustredeni.timetuple()), + f"Sous. deadline {cislo.poradi}. čísla")) + if cislo.datum_deadline is not None and cislo.datum_deadline <= datetime.date.today(): + result.append(( + strftime(DATE_FORMAT, cislo.datum_deadline.timetuple()), + f"Finální deadline {cislo.poradi}. čísla")) + result.append(( + strftime(DATE_FORMAT, datetime.date.today().timetuple()), f"Dnes")) + + return result + + @classmethod + def gen_initial(cls): + terminy = cls.gen_terminy() + initial = { + 'resitele': cls.RESITELE_RELEVANTNI, + 'problemy': cls.PROBLEMY_MOJE, + 'reseni_od': terminy[-2], + 'reseni_do': terminy[-1], + 'neobodovane': False, + } + return initial + + def __init__(self, *args, **kwargs): + if 'initial' not in kwargs: + super().__init__(initial=self.gen_initial(), *args, **kwargs) + else: + super().__init__(*args, **kwargs) + # choices jako parametr Select widgetu neumí brát callable, jen iterable, takže si pro jednoduchost můžu rovnou uložit výsledek sem... + # A "sem" znamená do libovolné metody, protože jinak se jedná o kód, který django spustí při inicializaci a protože potřebujeme databázi, tak by spadnul při vyrábění testdat... + self.terminy = self.gen_terminy() + self.fields['reseni_od'].widget = forms.Select(choices=self.gen_terminy()) + self.fields['reseni_od'].initial = self.terminy[-2] + self.fields['reseni_do'].widget = forms.Select(choices=self.gen_terminy()) + self.fields['reseni_do'].initial = self.terminy[-1] + + # NOTE: Initial definuji pro jednotlivé fieldy, aby to bylo tady a nebylo potřeba to řešit ve views... + resitele = forms.ChoiceField(choices=RESITELE_CHOICES) + problemy = forms.ChoiceField(choices=PROBLEMY_CHOICES) + + reseni_od = forms.DateField(input_formats=[DATE_FORMAT]) + reseni_do = forms.DateField(input_formats=[DATE_FORMAT]) + neobodovane = forms.BooleanField(required=False) diff --git a/seminar/management/commands/generate_thumbnails.py b/seminar/management/commands/generate_thumbnails.py new file mode 100644 index 00000000..e52ea9bc --- /dev/null +++ b/seminar/management/commands/generate_thumbnails.py @@ -0,0 +1,18 @@ +from django.core.management.base import BaseCommand + +from seminar.models import Cislo + +from subprocess import CalledProcessError +import logging + +logger = logging.getLogger(__name__) + +class Command(BaseCommand): + def handle(self, *args, **options): + for c in Cislo.objects.all(): + try: + c.vygeneruj_nahled() + except CalledProcessError: + logger.warning(f"Číslo {c} nezvládlo vygenerovat náhled titulky!") + pass + diff --git a/seminar/management/commands/load_org_permissions.py b/seminar/management/commands/load_org_permissions.py new file mode 100644 index 00000000..c1e4a106 --- /dev/null +++ b/seminar/management/commands/load_org_permissions.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- + +from django.core.management.base import BaseCommand +from django.contrib.sessions.models import Session +from django.contrib.auth.models import Group, Permission +from django.contrib.contenttypes.models import ContentType +from django.core.exceptions import ObjectDoesNotExist +import json +import argparse + +class Command(BaseCommand): + """ + + """ + def add_arguments(self, parser): + parser.add_argument('file', nargs=1, type=argparse.FileType('r', encoding='utf8')) + + + def handle(self, *args, **options): + try: + orgroup = Group.objects.get(name='org') + except ObjectDoesNotExist: + orgroup = Group(name='org') + orgroup.save() + permissions = json.load(options['file'][0]) + orgroup.permissions.clear() + for jp in permissions: + ct = ContentType.objects.get(app_label = jp['ct_app_label'], model = jp['ct_model']) + perm = Permission.objects.get(content_type = ct, codename = jp['codename']) + orgroup.permissions.add(perm) + orgroup.save() + diff --git a/seminar/management/commands/nukedb.py b/seminar/management/commands/nukedb.py new file mode 100644 index 00000000..f253841a --- /dev/null +++ b/seminar/management/commands/nukedb.py @@ -0,0 +1,20 @@ +from mamweb.settings import INSTALLED_APPS +from django.core.management.base import BaseCommand, CommandError +from django.core.management import call_command + +class Command(BaseCommand): + help = "Odmigruje všechny moduly (i.e. smaže všechny tabulky, ale databázi nechá)" + + def add_arguments(self, parser): + # TODO: --force (makat a neblábolit) + pass + def handle(self, *args, **options): + # TODO: zeptat se + for app in INSTALLED_APPS: + app = app.split('.')[-1] + try: + call_command('migrate', app, 'zero') + except CommandError: + # app nemá migrace (aspoň typicky) + pass + call_command('showmigrations') diff --git a/seminar/management/commands/save_org_permissions.py b/seminar/management/commands/save_org_permissions.py new file mode 100644 index 00000000..a6814e6f --- /dev/null +++ b/seminar/management/commands/save_org_permissions.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- + +from django.core.management.base import BaseCommand +from django.contrib.sessions.models import Session +from django.contrib.auth.models import Group, Permission +import json + +class Command(BaseCommand): + """ + Dump permissions for group 'org' such that them can be used on an other machine. + + """ + def handle(self, *args, **options): + orgroup = Group.objects.get(name='org') + permissions = [] + for p in orgroup.permissions.all(): + permissions.append({ + 'codename': p.codename, + 'ct_app_label': p.content_type.app_label, + 'ct_model': p.content_type.model}) + print(json.dumps(permissions)) + diff --git a/seminar/management/commands/testdata.py b/seminar/management/commands/testdata.py index 9f38ab57..dbbd908d 100644 --- a/seminar/management/commands/testdata.py +++ b/seminar/management/commands/testdata.py @@ -15,20 +15,35 @@ User = django.contrib.auth.get_user_model() class Command(BaseCommand): - help = "Clear database and load testing data." - - def handle(self, *args, **options): - assert settings.DEBUG == True - dbfile = settings.DATABASES['default']['NAME'] - if os.path.exists(dbfile): - os.rename(dbfile, dbfile + '.old') - self.stderr.write('Stara databaze prejmenovana na "%s"' % (dbfile + '.old')) - call_command('migrate', noinput=True) - self.stdout.write('Vytvarim uzivatele "admin" (heslo "admin") a pseudo-nahodna data ...') - create_test_data(size=8) - self.stdout.write('Vytvoreno %d uzivatelu, %d skol, %d resitelu, %d rocniku, %d cisel, %d problemu, %d reseni.' % - (User.objects.count(), Skola.objects.count(), Resitel.objects.count(), Rocnik.objects.count(), - Cislo.objects.count(), Problem.objects.count(), Reseni.objects.count())) + help = "Clear database and load testing data." + + def add_arguments(self, parser): + parser.add_argument( + '--no-clean', + action='store_true', + help='Změny se provedou v aktuální DB, ne v čisté. Aktuální DB se nezachová. (jen k debugování)', + ) + parser.add_argument( + '--no-migrate', + action='store_true', + help='Neprovádět migrace před generováním testovacích dat (jen k debugování)', + ) + + def handle(self, *args, **options): + assert settings.DEBUG == True + dbfile = settings.DATABASES['default']['NAME'] + if os.path.exists(dbfile) and not options['no_clean']: + os.rename(dbfile, dbfile + '.old') + self.stderr.write('Stara databaze prejmenovana na "%s"' % (dbfile + '.old')) + if not options['no_migrate']: + call_command('migrate', no_input=True) + self.stdout.write('Vytvarim uzivatele "admin" (heslo "admin") a pseudo-nahodna data ...') + create_test_data(size=5) + # menší počet ročníků, aby se zrychlilo generování dat a bylo dost úloh + self.stdout.write('Vytvoreno {} uzivatelu, {} skol, {} resitelu, {} rocniku, {} cisel,' + ' {} problemu, {} reseni.'.format(User.objects.count(), Skola.objects.count(), + Resitel.objects.count(), Rocnik.objects.count(), Cislo.objects.count(), + Problem.objects.count(), Reseni.objects.count())) diff --git a/seminar/migrations/0001_initial.py b/seminar/migrations/0001_initial.py index 12a6b605..088193b3 100644 --- a/seminar/migrations/0001_initial.py +++ b/seminar/migrations/0001_initial.py @@ -18,9 +18,9 @@ class Migration(migrations.Migration): migrations.CreateModel( name='VysledkyKCislu', fields=[ - ('dummy_id', models.CharField(max_length=32, serialize=False, verbose_name='dummy ID pro view', primary_key=True, db_column=b'id')), - ('body', models.IntegerField(verbose_name='body za \u010d\xedslo', db_column=b'body')), - ('body_celkem', models.IntegerField(verbose_name='body celkem do \u010d\xedsla', db_column=b'body_celkem')), + ('dummy_id', models.CharField(max_length=32, serialize=False, verbose_name='dummy ID pro view', primary_key=True, db_column='id')), + ('body', models.IntegerField(verbose_name='body za \u010d\xedslo', db_column='body')), + ('body_celkem', models.IntegerField(verbose_name='body celkem do \u010d\xedsla', db_column='body_celkem')), ], options={ 'abstract': False, @@ -32,8 +32,8 @@ class Migration(migrations.Migration): migrations.CreateModel( name='VysledkyZaCislo', fields=[ - ('dummy_id', models.CharField(max_length=32, serialize=False, verbose_name='dummy ID pro view', primary_key=True, db_column=b'id')), - ('body', models.IntegerField(verbose_name='body za \u010d\xedslo', db_column=b'body')), + ('dummy_id', models.CharField(max_length=32, serialize=False, verbose_name='dummy ID pro view', primary_key=True, db_column='id')), + ('body', models.IntegerField(verbose_name='body za \u010d\xedslo', db_column='body')), ], options={ 'abstract': False, @@ -49,7 +49,7 @@ class Migration(migrations.Migration): ('cislo', models.CharField(help_text='V\u011bt\u0161inou jen "1", vyj\xedme\u010dn\u011b "7-8", lexikograficky ur\u010dije po\u0159ad\xed v ro\u010dn\xedku!', max_length=32, verbose_name='n\xe1zev \u010d\xedsla')), ('datum_vydani', models.DateField(help_text='Datum vyd\xe1n\xed fin\xe1ln\xed verze', null=True, verbose_name='datum vyd\xe1n\xed', blank=True)), ('datum_deadline', models.DateField(help_text='Datum pro p\u0159\xedjem \u0159e\u0161en\xed \xfaloh zadan\xfdch v tomto \u010d\xedsle', null=True, verbose_name='datum deadline', blank=True)), - ('verejne_db', models.BooleanField(default=False, verbose_name='\u010d\xedslo zve\u0159ejn\u011bno', db_column=b'verejne')), + ('verejne_db', models.BooleanField(default=False, verbose_name='\u010d\xedslo zve\u0159ejn\u011bno', db_column='verejne')), ], options={ 'ordering': ['rocnik__rocnik', 'cislo'], @@ -63,7 +63,7 @@ class Migration(migrations.Migration): name='Nastaveni', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('aktualni_cislo', models.ForeignKey(verbose_name='posledn\xed vydan\xe9 \u010d\xedslo', to='seminar.Cislo')), + ('aktualni_cislo', models.ForeignKey(verbose_name='posledn\xed vydan\xe9 \u010d\xedslo', to='seminar.Cislo', on_delete=models.CASCADE)), ], options={ 'db_table': 'seminar_nastaveni', @@ -98,10 +98,10 @@ class Migration(migrations.Migration): ('text_problemu', models.TextField(verbose_name='ve\u0159ejn\xfd text zad\xe1n\xed a \u0159e\u0161en\xed', blank=True)), ('kod', models.CharField(default=b'', help_text='\u010c\xedslo/k\xf3d \xfalohy v \u010d\xedsle nebo k\xf3d t\xe9matu/\u010dl\xe1nku/seri\xe1lu v ro\u010dn\xedku', max_length=32, verbose_name='lok\xe1ln\xed k\xf3d', blank=True)), ('body', models.IntegerField(null=True, verbose_name='maximum bod\u016f', blank=True)), - ('autor', models.ForeignKey(related_name='autor_uloh', verbose_name='autor probl\xe9mu', to=settings.AUTH_USER_MODEL)), - ('cislo_reseni', models.ForeignKey(related_name='resene_problemy', blank=True, to='seminar.Cislo', help_text='\u010c\xedslo s \u0159e\u0161en\xedm \xfalohy, jen pro \xfalohy', null=True, verbose_name='\u010d\xedslo \u0159e\u0161en\xed')), - ('cislo_zadani', models.ForeignKey(related_name='zadane_problemy', verbose_name='\u010d\xedslo zad\xe1n\xed', blank=True, to='seminar.Cislo', null=True)), - ('opravovatel', models.ForeignKey(related_name='opravovatel_uloh', verbose_name='opravovatel', blank=True, to=settings.AUTH_USER_MODEL, null=True)), + ('autor', models.ForeignKey(related_name='autor_uloh', verbose_name='autor probl\xe9mu', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), + ('cislo_reseni', models.ForeignKey(related_name='resene_problemy', blank=True, to='seminar.Cislo', help_text='\u010c\xedslo s \u0159e\u0161en\xedm \xfalohy, jen pro \xfalohy', null=True, verbose_name='\u010d\xedslo \u0159e\u0161en\xed', on_delete=models.CASCADE)), + ('cislo_zadani', models.ForeignKey(related_name='zadane_problemy', verbose_name='\u010d\xedslo zad\xe1n\xed', blank=True, to='seminar.Cislo', null=True, on_delete=models.CASCADE)), + ('opravovatel', models.ForeignKey(related_name='opravovatel_uloh', verbose_name='opravovatel', blank=True, to=settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE)), ], options={ 'db_table': 'seminar_problemy', @@ -117,8 +117,8 @@ class Migration(migrations.Migration): ('body', models.IntegerField(null=True, verbose_name='body', blank=True)), ('timestamp', models.DateTimeField(auto_now=True, verbose_name='vytvo\u0159eno')), ('poznamka', models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \u0159e\u0161en\xed (plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True)), - ('cislo_body', models.ForeignKey(related_name='bodovana_reseni', verbose_name='\u010d\xedslo pro body', blank=True, to='seminar.Cislo', null=True)), - ('problem', models.ForeignKey(related_name='reseni', verbose_name='probl\xe9m', to='seminar.Problem')), + ('cislo_body', models.ForeignKey(related_name='bodovana_reseni', verbose_name='\u010d\xedslo pro body', blank=True, to='seminar.Cislo', null=True, on_delete=models.CASCADE)), + ('problem', models.ForeignKey(related_name='reseni', verbose_name='probl\xe9m', to='seminar.Problem', on_delete=models.CASCADE)), ], options={ 'ordering': ['problem', 'resitel'], @@ -199,10 +199,10 @@ class Migration(migrations.Migration): ('id', models.AutoField(serialize=False, primary_key=True)), ('datum_zacatku', models.DateField(help_text='Prvn\xed den soust\u0159ed\u011bn\xed', null=True, verbose_name='datum za\u010d\xe1tku', blank=True)), ('datum_konce', models.DateField(help_text='Posledn\xed den soust\u0159ed\u011bn\xed', null=True, verbose_name='datum konce', blank=True)), - ('verejne_db', models.BooleanField(default=False, verbose_name='soust\u0159ed\u011bn\xed zve\u0159ejn\u011bno', db_column=b'verejne')), + ('verejne_db', models.BooleanField(default=False, verbose_name='soust\u0159ed\u011bn\xed zve\u0159ejn\u011bno', db_column='verejne')), ('misto', models.CharField(default=b'', help_text='M\xedsto (n\xe1zev obce, voliteln\u011b t\xe9\u017e objektu', max_length=256, verbose_name='m\xedsto soust\u0159ed\u011bn\xed', blank=True)), - ('rocnik', models.ForeignKey(related_name='soustredeni', verbose_name='ro\u010dn\xedk', to='seminar.Rocnik')), - ('ucastnici', models.ManyToManyField(help_text='Seznam \xfa\u010dastn\xedk\u016f soust\u0159ed\u011bn\xed', to='seminar.Resitel', db_table=b'seminar_soustredeni_ucastnici', verbose_name='\xfa\u010dastn\xedci soust\u0159ed\u011bn\xed')), + ('rocnik', models.ForeignKey(related_name='soustredeni', verbose_name='ro\u010dn\xedk', to='seminar.Rocnik', on_delete=models.CASCADE)), + ('ucastnici', models.ManyToManyField(help_text='Seznam \xfa\u010dastn\xedk\u016f soust\u0159ed\u011bn\xed', to='seminar.Resitel', db_table='seminar_soustredeni_ucastnici', verbose_name='\xfa\u010dastn\xedci soust\u0159ed\u011bn\xed')), ], options={ 'ordering': ['rocnik__rocnik', 'datum_zacatku'], @@ -215,37 +215,37 @@ class Migration(migrations.Migration): migrations.AddField( model_name='resitel', name='skola', - field=models.ForeignKey(verbose_name='\u0161kola', blank=True, to='seminar.Skola', null=True), + field=models.ForeignKey(verbose_name='\u0161kola', blank=True, to='seminar.Skola', null=True, on_delete=models.CASCADE), preserve_default=True, ), migrations.AddField( model_name='resitel', name='user', - field=models.OneToOneField(null=True, blank=True, to=settings.AUTH_USER_MODEL, verbose_name='u\u017eivatel'), + field=models.OneToOneField(null=True, blank=True, to=settings.AUTH_USER_MODEL, verbose_name='u\u017eivatel', on_delete=models.CASCADE), preserve_default=True, ), migrations.AddField( model_name='reseni', name='resitel', - field=models.ForeignKey(related_name='reseni', verbose_name='\u0159e\u0161itel', to='seminar.Resitel'), + field=models.ForeignKey(related_name='reseni', verbose_name='\u0159e\u0161itel', to='seminar.Resitel', on_delete=models.CASCADE), preserve_default=True, ), migrations.AddField( model_name='prilohareseni', name='reseni', - field=models.ForeignKey(related_name='prilohy', verbose_name='\u0159e\u0161en\xed', to='seminar.Reseni'), + field=models.ForeignKey(related_name='prilohy', verbose_name='\u0159e\u0161en\xed', to='seminar.Reseni', on_delete=models.CASCADE), preserve_default=True, ), migrations.AddField( model_name='nastaveni', name='aktualni_rocnik', - field=models.ForeignKey(verbose_name='aktu\xe1ln\xed ro\u010dn\xedk', to='seminar.Rocnik'), + field=models.ForeignKey(verbose_name='aktu\xe1ln\xed ro\u010dn\xedk', to='seminar.Rocnik', on_delete=models.CASCADE), preserve_default=True, ), migrations.AddField( model_name='cislo', name='rocnik', - field=models.ForeignKey(related_name='cisla', verbose_name='ro\u010dn\xedk', to='seminar.Rocnik'), + field=models.ForeignKey(related_name='cisla', verbose_name='ro\u010dn\xedk', to='seminar.Rocnik', on_delete=models.CASCADE), preserve_default=True, ), ] diff --git a/seminar/migrations/0001_squashed_0067_auto_20190814_0805.py.bak b/seminar/migrations/0001_squashed_0067_auto_20190814_0805.py.bak new file mode 100644 index 00000000..eb2d950f --- /dev/null +++ b/seminar/migrations/0001_squashed_0067_auto_20190814_0805.py.bak @@ -0,0 +1,2214 @@ +# Generated by Django 2.2.6 on 2019-10-30 20:20 + +from django.conf import settings +from django.db import migrations, models +import django.db.migrations.operations.special +import django.db.models.deletion +import django.utils.timezone +import django_countries.fields +import imagekit.models.fields +import seminar.models +import taggit.managers + +# migr 0053 +import datetime as dt + +# migr 0058 +from django.db.models import Q + + +# Functions from the following migrations need manual copying. +# Move them and any dependencies into this file, then update the +# RunPython operations to refer to the local versions: + +# seminar.migrations.0051_resitel_to_osoba + +def resitel_to_osoba(apps,schema_editor): + Resitel = apps.get_model('seminar','Resitel') + Osoba = apps.get_model('seminar','Osoba') + for r in Resitel.objects.all(): + o = Osoba() + o.datum_narozeni = r.datum_narozeni + o.datum_registrace = r.datum_prihlaseni + o.datum_souhlasu_udaje = r.datum_souhlasu_udaje + o.datum_souhlasu_zasilani = r.datum_souhlasu_zasilani + o.email = r.email + o.jmeno = r.jmeno + o.mesto = r.mesto + o.pohlavi_muz = r.pohlavi_muz + o.prijmeni = r.prijmeni + o.psc = r.psc + o.stat = r.stat + o.telefon = r.telefon + o.ulice = r.ulice + o.user = r.user + if o.user: + u = o.user + if u.first_name: + if not o.jmeno: + o.jmeno = u.first_name + u.first_name = 'Použij osobu!' + elif o.jmeno == u.first_name: + u.first_name = 'Použij osobu!' + else: + raise ValueError('jmeno a first_name rozdílné: "{}" vs. "{}"'.format(o.jmeno, u.first_name)) + if u.last_name: + if not o.prijmeni: + o.prijmeni = u.last_name + u.last_name = 'Použij osobu!' + elif o.prijmeni == u.last_name: + u.last_name = 'Použij osobu!' + else: + raise ValueError('prijmeni a last_name rozdílné: "{}" vs. "{}"'.format(o.prijmeni, u.last_name)) + if u.email: + if not o.email: + o.email = u.email + u.email = 'Použij osobu!' + elif o.email == u.email: + u.email = 'Použij osobu!' + else: + raise ValueError('o.email a u.email rozdílné: "{}" vs. "{}"'.format(o.email, u.email)) + u.save() + + + o.save() + r.osoba = o + r.save() + +def osoba_to_resitel(apps, schema_editor): + Resitel = apps.get_model('seminar','Resitel') + Osoba = apps.get_model('seminar','Osoba') + for r in Resitel.objects.all(): + o = r.osoba + r.datum_narozeni = o.datum_narozeni + r.datum_prihlaseni = o.datum_registrace + r.datum_souhlasu_udaje = o.datum_souhlasu_udaje + r.datum_souhlasu_zasilani = o.datum_souhlasu_zasilani + r.email = o.email + r.jmeno = o.jmeno + r.mesto = o.mesto + r.pohlavi_muz = o.pohlavi_muz + r.prijmeni = o.prijmeni + r.psc = o.psc + r.stat = o.stat + r.telefon = o.telefon + r.ulice = o.ulice + r.user = o.user + r.save() + o.delete() + + +# seminar.migrations.0052_user_to_organizator + +def spoj_k_organizatorum_osoby(apps, scema_editor): + Organizator = apps.get_model('seminar', 'Organizator') + Resitel = apps.get_model('seminar', 'Resitel') + Osoba = apps.get_model('seminar', 'Osoba') + for org in Organizator.objects.all(): + + # Spárování organizátora s osobou + # Myšlenka: Když najdeme řešitele pro daného uživatele, tak se vezme Osoba příslušná uživateli, + # Pokud nenajdeme uživatele, tak ještě zkusíme dohledat Osobu podle e-mailu + user = org.user + if user is None: + logger.error(f'Org {org} nemá uživatele!') + # Je to podezřelé, ale prostě vyrobíme novou osobu. + osoba = Osoba(user=user) + # Téhle osobě nejdou nastavit detaily, protože žádné nemáme. + else: + logger.info(f'Org {org.user.email}(ID: {org.id}) má uživatele {user}') + # 💢💢💢 Python nemá goto, ale prý má výjimky… 💢💢💢 + class EndException(Exception): pass + try: + # Hledáme podle uživatele + resitele = Resitel.objects.filter(user=user) + if resitele.count() != 0 and user is not None: + osoba = resitele.first().osoba + logger.info(f'Našel jsem řešitele {resitele.first().email} podle uživatele, používám jeho Osobu') + raise EndException + + # Hledáme podle e-mailu + osoby = Osoba.objects.filter(email__iexact=user.email) + if osoby.count() != 0 and user.email != '': + osoba = osoby.first() + if osoba.user is None: + osoba.user = user + logger.info(f'Našel jsem Osobu {osoby.first().email} podle e-mailu') + raise EndException + + # Fallback + logger.warning(f'Org neměl řešitele, zakládám novou Osobu.') + osoba = Osoba(user=user) + + # Přesun informací z usera do osoby + # pro osoby z řešitelů (jediné dosud existující osoby) již v minule migraci + osoba.jmeno = user.first_name + osoba.prijmeni = user.last_name + osoba.email = user.email + user.jmeno = "Použij osobu!" + user.prijmeni = "Použij osobu!" + user.email = "Použij osobu!" + user.save() + + except EndException: pass + + # Přesun informací z organizátora do jeho osoby + osoba.prezdivka = org.prezdivka if org.prezdivka is not None else '' + osoba.foto = org.foto + + # Všechno uložit + osoba.save() + org.osoba = osoba + org.save() + +def fix_problem(apps, schema_editor): + Problem = apps.get_model('seminar', 'Problem') + Organizator = apps.get_model('seminar', 'Organizator') + for pr in Problem.objects.all(): + if pr.autor_old is not None: + pr.autor = Organizator.objects.filter(osoba__user=pr.autor_old).first() + else: + pr.autor = None + if pr.opravovatel is not None: + if Organizator.objects.filter(osoba__user=pr.opravovatel).first() is not None: + pr.opravovatele.add(Organizator.objects.filter(osoba__user=pr.opravovatel).first()) + else: + logger.error(f'WTF, nespárovaný opravovatel {pr.opravovatel} problému {pr}') + pr.save() + +def fix_pohadka(apps, schema_editor): + Pohadka = apps.get_model('seminar', 'Pohadka') + Organizator = apps.get_model('seminar', 'Organizator') + for poh in Pohadka.objects.all(): + if poh.autor_old is not None: + poh.autor = Organizator.objects.filter(osoba__user=poh.autor_old).first() + else: + poh.autor = None + poh.save() + +def fix_novinka(apps, schema_editor): + Novinky = apps.get_model('seminar', 'Novinky') + Organizator = apps.get_model('seminar', 'Organizator') + for nov in Novinky.objects.all(): + nov.autor = Organizator.objects.filter(osoba__user=nov.autor_old).first() + nov.save() + +# seminar.migrations.0053_organizator_organizuje_od_do + +def rok_to_datetime(apps,schema_editor): + Organizator = apps.get_model('seminar','Organizator') + for o in Organizator.objects.all(): + rok = o.organizuje_od_roku + if rok: + o.organizuje_od = dt.datetime(rok,1,1) + rok = o.organizuje_do_roku + if rok: + o.organizuje_do = dt.datetime(rok,12,31) + o.save() + +def datetime_to_rok(apps,schema_editor): + Organizator = apps.get_model('seminar','Organizator') + for o in Organizator.objects.all(): + o.organizuje_od_roku = o.organizuje_od.year + o.organizuje_do_roku = o.organizuje_do.year + o.save() + +# seminar.migrations.0056_vrcholy_pro_rocniky_a_cisla + +def generuj_RocnikNody_a_CisloNody(apps,schema_editor): + Rocnik = apps.get_model('seminar', 'Rocnik') + RocnikNode = apps.get_model('seminar', 'RocnikNode') + Cislo = apps.get_model('seminar', 'Cislo') + CisloNode = apps.get_model('seminar', 'CisloNode') + + last_rn = None # last_* slouží k navázání následníků + for r in Rocnik.objects.all(): + rn = RocnikNode.objects.create(rocnik=r) + rn.save() + rn.root = rn + rn.save() + if last_rn: + last_rn.succ = rn + last_rn.save() + last_rn = rn + + last_cn = None + for c in Cislo.objects.filter(rocnik=r): + cn = CisloNode.objects.create(cislo=c, root=rn) + cn.save() + if last_cn: # Jsme něčí následník + last_cn.succ = cn + last_cn.save() + else: # Jsme první v řadě, takže se musíme přidat jako first_child RočníkNodu + rn.first_child = cn + rn.save() + last_cn = cn + +# seminar.migrations.0057_reseni_to_reseni_hodnoceni + +def reseni_to_Reseni(apps, schema_editor): + Reseni = apps.get_model('seminar','Reseni') + Reseni_Resitele = apps.get_model('seminar','Reseni_Resitele') + Hodnoceni = apps.get_model('seminar','Hodnoceni') + + for r in Reseni.objects.all(): + rr = Reseni_Resitele.objects.create(resitele = r.resitel, reseni=r) + if r.body == None: + print("!!!!!!!!!!!!!!!") + print(r.id,r) + print("!!!!!!!!!!!!!!!") + else: + h = Hodnoceni.objects.create( + body=r.body, + cislo_body = r.cislo_body, + problem = r.problem_old, + reseni = r) + +# seminar.migrations.0058_problem_to_uloha_tema_clanek + +def poskladej_strom(apps, rodic, *texty): + Text = apps.get_model('seminar', 'Text') + TextNode = apps.get_model('seminar', 'TextNode') + if not rodic: + raise ValueError("Rodič musí být definovaný") + + uz_ma_deti = False + tn = None + for txt in texty: + if not txt: + continue + # Přidej do stromu: + textobj = Text.objects.create(na_web = txt) + textobj.save() + textnode = TextNode.objects.create(text = textobj) + textnode.save() + if not uz_ma_deti: + rodic.first_child = textnode + rodic.save() + tn = rodic.first_child + uz_ma_deti = True + else: + tn.succ = textnode + tn.save() + tn = tn.succ + +def uloha_to_Uloha(apps,schema_editor): + Problem = apps.get_model('seminar', 'Problem') + Uloha = apps.get_model('seminar', 'Uloha') + Text = apps.get_model('seminar', 'Text') + UlohaZadaniNode = apps.get_model('seminar', 'UlohaZadaniNode') + UlohaVzorakNode = apps.get_model('seminar', 'UlohaVzorakNode') + TextNode = apps.get_model('seminar', 'TextNode') + + ulohy = Problem.objects.filter(typ = 'uloha') + for uold in ulohy: + unew = Uloha.objects.create( + problem_ptr = uold, + # Zakomentované fieldy by se už měly nacházet v příslušném problému + #nazev = uold.nazev, + #stav = uold.stav, + #zamereni = uold.zamereni, + #poznamka = uold.poznamka, + #autor = uold.autor, + #kod = uold.kod, + cislo_zadani = uold.cislo_zadani_old, + cislo_reseni = uold.cislo_reseni_old, + max_body = uold.body, + #vytvoreno = uold.vytvoreno, + ) +# unew.opravovatele.add(*uold.opravovatele.all()) + unew.save() + + # Nody: + zadani_node = UlohaZadaniNode.objects.create(uloha = unew) + poskladej_strom(apps, zadani_node, uold.text_zadani) + zadani_node.save() + vzorak_node = UlohaVzorakNode.objects.create(uloha = unew) + poskladej_strom(apps, vzorak_node, uold.text_reseni) + vzorak_node.save() + +def konfery_rucne(apps, schema_editor): + # Tohle dělat nebudu, máme aktuálně celou jednu. Ale "Errors should never pass silently" + Problem = apps.get_model('seminar', 'Problem') + pocet_konfer = Problem.objects.filter(typ = 'konfera').count() + if pocet_konfer > 0: + raise NotImplementedError("Zkonvertuj {} konfer na objekt Konfera ručně, prosím".format(pocet_konfer)) + +def clanek_to_Clanek(apps,schema_editor): + Problem = apps.get_model('seminar', 'Problem') + Clanek = apps.get_model('seminar', 'Clanek') + ClanekNode = apps.get_model('seminar', 'ClanekNode') + Text = apps.get_model('seminar', 'Text') + TextNode = apps.get_model('seminar', 'TextNode') + + clanky = Problem.objects.filter(Q(typ='org-clanek') | Q(typ='res-clanek')) + for cl in clanky: + # Vybereme vhodné číslo pro článek z čísla zadání a čísla řešení: + if cl.cislo_zadani_old is None: + cislo = cl.cislo_reseni_old + elif cl.cislo_reseni_old is None: + cislo = cl.cislo_zadani_old + elif cl.cislo_reseni_old == cl.cislo_zadani_old: + cislo = cl.cislo_zadani_old + else: + raise ValueError("Různá čísla zadání a řešení u článku! (Článek: {})".format(cl.nazev)) + + clnew = Clanek.objects.create( + problem_ptr = cl, + # Problém by nemělo být potřeba upravovat + cislo = cislo, + # Body ignorujeme, protože už jsou v hodnocení + ) + clnew.save() + + # Aktuálně nemáme v modelu informaci o tom, jestli je to org-článek + # nebo řešitelský článek. Aby se neztratila informace, poznamenám to do + # poznámky. + cl.poznamka += "\nTyp:\t{}".format(cl.typ) + cl.save() + + # Vyrobíme nody: + clnode = ClanekNode(clanek = clnew) + poskladej_strom(apps, clnode, cl.text_zadani, cl.text_reseni) + clnode.save() + +def tema_to_Tema(apps, schema_editor): + Problem = apps.get_model('seminar', 'Problem') + Tema = apps.get_model('seminar', 'Tema') + TemaVCisleNode = apps.get_model('seminar', 'TemaVCisleNode') + Text = apps.get_model('seminar', 'Text') + TextNode = apps.get_model('seminar', 'TextNode') + + temata = Problem.objects.filter(Q(typ = 'tema') | Q(typ='serial')) + for t in temata: + # Vymyslíme správně ročník: + if t.cislo_zadani_old is None and t.cislo_reseni_old is None: + rocnik = None + elif t.cislo_zadani_old is None: + rocnik = t.cislo_reseni_old.rocnik + elif t.cislo_reseni_old is None: + rocnik = t.cislo_zadani_old.rocnik + elif t.cislo_reseni_old.rocnik == t.cislo_zadani_old.rocnik: + rocnik = t.cislo_zadani_old.rocnik + else: + raise ValueError("Nelze mít téma přes více ročníků! (Téma: {}".format(t.nazev)) + + tnew = Tema.objects.create( + problem_ptr = t, + tema_typ = t.typ, + rocnik = rocnik, + ) + tnew.save() + + # Nody: + tnode = TemaVCisleNode(tema = tnew) + poskladej_strom(apps, tnode, t.text_zadani, t.text_reseni) + tnode.save() + +# seminar.migrations.0059_vytvorit_pohadkanode + +def vytvor_pohadkanode(apps, schema_editor): + Pohadka = apps.get_model('seminar', 'Pohadka') + PohadkaNode = apps.get_model('seminar', 'PohadkaNode') + Text = apps.get_model('seminar', 'Text') + TextNode = apps.get_model('seminar', 'TextNode') + + for p in Pohadka.objects.all(): + t = Text.objects.create(na_web = p.text) + t.save() + tn = TextNode.objects.create(text = t) + tn.save() + pn = PohadkaNode.objects.create(pohadka = p, first_child = tn) + pn.save() + +# seminar.migrations.0060_spoj_stromy + +def pridej_potomka(rodic, potomek): + # Daný vrchol bude posledním potomkem rodiče + uz_ma_deti = False + posledni = None + + # Přidávaný potomek by neměl mít následovníka -- přidáváme potomka, ne podles. + if potomek.succ: + raise ValueError("Potomek má následovníka, to je velmi podezřelé!") + + # Najdeme aktuálně posledního potomka: + if rodic.first_child: + uz_ma_deti = True + posledni = rodic.first_child + while posledni.succ: + posledni = posledni.succ + + # Nastavíme kořen: + potomek.root = rodic.root + potomek.save() + + # Připojíme vrchol: + if uz_ma_deti: + posledni.succ = potomek + posledni.save() + else: + rodic.first_child = potomek + rodic.save() + +def pokacej_les(apps, schema_editor): + # Teď je potřeba všechny TreeNody příslušející k zadaným problémům připojit + # do hlavního stromu + # Tohle je jednoduchá verze: nejdřív témátka a seriály, pak úložky a pohádky, + # pak články a konfery, pak vzoráky, všechno setříděné podle kódu (FIXME?) + + # Kopírování je častým zdrojem chyb! + Cislo = apps.get_model('seminar', 'Cislo') + Tema = apps.get_model('seminar', 'Tema') + Konfera = apps.get_model('seminar', 'Konfera') + Clanek = apps.get_model('seminar', 'Clanek') + Uloha = apps.get_model('seminar', 'Uloha') + Problem = apps.get_model('seminar', 'Problem') + Pohadka = apps.get_model('seminar', 'Pohadka') + + for c in Cislo.objects.all().reverse(): + cnode = c.cislonode + + # Témata a seriály: + relevantni_temata = Tema.objects.filter(Q(cislo_zadani_old = c) | Q(cislo_reseni_old = c)).order_by('kod') + # Téma dáme do prvního čísla, kde se vyskytne + for t in relevantni_temata: + tnode = t.temavcislenode + if t.cislo_zadani_old and t.cislo_reseni_old: + assert(t.cislo_zadani_old <= t.cislo_reseni_old) + if t.cislo_reseni_old == c: + # Už by mělo být přidané do čísla zadání + continue + else: + # Patří sem (buď je to jediné číslo, nebo je to číslo zadání) + pridej_potomka(cnode, tnode) + + # Úložky (zadání) a pohádky + for u in Uloha.objects.filter(cislo_zadani = c).order_by('kod'): + unode = u.ulohazadaninode + pohadky_pred = Pohadka.objects.filter(uloha_old = u.problem_ptr, pred = True) + pohadky_po = Pohadka.objects.filter(uloha_old = u.problem_ptr, pred = False) + for p in pohadky_pred: + pnode = p.pohadkanode + pridej_potomka(cnode, pnode) + pridej_potomka(cnode, unode) + for p in pohadky_po: + pnode = p.pohadkanode + pridej_potomka(cnode, pnode) + + # Pohádky, které nejsou u úlohy jsou špatně: + if Pohadka.objects.exclude(uloha_old__typ='uloha').count(): + raise ValueError("Existuje pohádka, která není u úlohy") + + # Články + for cl in Clanek.objects.filter(cislo = c).order_by('kod'): + clnode = cl.claneknode + pridej_potomka(cnode, clnode) + + # Konfery + for k in Konfera.objects.all(): + knode = k.konferanode + if k.reseni and knode.root is None: + # Takováhle konfera nejspíš neexistuje + raise NotImplementedError("Konfery neumím zapojit do stromu") + + # Vzoráky + for u in Uloha.objects.filter(cislo_reseni = c).order_by('kod'): + unode = u.ulohavzoraknode + pridej_potomka(cnode, unode) + +# seminar.migrations.0065_treenode_polymorphic_ctype + +def vyrob_treenodum_ctypes(apps, schema_editor): + # Kód zkopírovaný z dokumentace: https://django-polymorphic.readthedocs.io/en/stable/migrating.html + # XXX: Nevím, jestli se tohle náhodou nemělo spustit na všech childech (jen/i) + TreeNode = apps.get_model('seminar', 'TreeNode') + ContentType = apps.get_model('contenttypes', 'ContentType') + + new_ct = ContentType.objects.get_for_model(TreeNode) + TreeNode.objects.filter(polymorphic_ctype__isnull=True).update(polymorphic_ctype=new_ct) + +# seminar.migrations.0066_problem_polymorphic_ctype + +def vyrob_problemum_ctypes(apps, schema_editor): + # Kód zkopírovaný z dokumentace: https://django-polymorphic.readthedocs.io/en/stable/migrating.html + # XXX: Nevím, jestli se tohle náhodou nemělo spustit na všech childech (jen/i) + Problem = apps.get_model('seminar', 'Problem') + ContentType = apps.get_model('contenttypes', 'ContentType') + + new_ct = ContentType.objects.get_for_model(Problem) + Problem.objects.filter(polymorphic_ctype__isnull=True).update(polymorphic_ctype=new_ct) + + +class Migration(migrations.Migration): + atomic = False + replaces = [('seminar', '0001_initial'), ('seminar', '0002_add_body_views'), ('seminar', '0003_add_skola_zs_ss'), ('seminar', '0004_add_old_dakos_id'), ('seminar', '0005_alter_problem_autor'), ('seminar', '0006_problem_add_timestamp'), ('seminar', '0007_problem_zamereni'), ('seminar', '0008_reseni_forma'), ('seminar', '0009_rename_imported_IDs'), ('seminar', '0010_alter_rok_maturity'), ('seminar', '0011_alter_timestamp_def'), ('seminar', '0012_remove_soustredeni_ucastnici'), ('seminar', '0013_soustredeni_ucastnici_through_model'), ('seminar', '0014_uprava_poznamek'), ('seminar', '0015_soustredeni_text'), ('seminar', '0016_texty_problemu'), ('seminar', '0017_texty_problemu_minor'), ('seminar', '0018_problemnavrh_problemzadany'), ('seminar', '0019_rocnik_ciselne'), ('seminar', '0020_indexy_a_razeni'), ('seminar', '0021_cislo_verejna_vysledkovka'), ('seminar', '0022_decimal_body'), ('seminar', '0023_add_novinky'), ('seminar', '0024_add_organizator'), ('seminar', '0025_zmena_cesty_nahravani_obrazku'), ('seminar', '0026_soustredeni_typ'), ('seminar', '0027_export_flag_a_typ_akce'), ('seminar', '0028_add_body_celkem_views'), ('seminar', '0029_fix_body_celkem_views'), ('seminar', '0030_add_vysledky'), ('seminar', '0031_cislo_pdf'), ('seminar', '0032_cislo_pdf_blank_typos'), ('seminar', '0033_organizator_studuje_popisek'), ('seminar', '0034_reseni_forma_default_email'), ('seminar', '0035_django_imagekit'), ('seminar', '0036_add_org_to_soustredeni'), ('seminar', '0037_prispevek'), ('seminar', '0038_change_meta_prispevek'), ('seminar', '0039_pohadka'), ('seminar', '0040_pohadka_nepovinny_autor'), ('seminar', '0041_konfery'), ('seminar', '0042_cislo_faze'), ('seminar', '0043_uprava_faze'), ('seminar', '0044_uprava_faze'), ('seminar', '0045_cislo_pridani_faze_nahrano'), ('seminar', '0042_auto_20161005_0847'), ('seminar', '0046_merge'), ('seminar', '0047_auto_20170120_2118'), ('seminar', '0048_add_cislo_datum_deadline_soustredeni'), ('seminar', '0049_auto_20190430_2354'), ('seminar', '0050_auto_20190510_2228'), ('seminar', '0051_resitel_to_osoba'), ('seminar', '0052_user_to_organizator'), ('seminar', '0053_organizator_organizuje_od_do'), ('seminar', '0055_smazat_nemigrovane_zastarale_veci'), ('seminar', '0056_vrcholy_pro_rocniky_a_cisla'), ('seminar', '0057_reseni_to_reseni_hodnoceni'), ('seminar', '0058_problem_to_uloha_tema_clanek'), ('seminar', 'fix_0058'), ('seminar', '0059_vytvorit_pohadkanode'), ('seminar', '0060_spoj_stromy'), ('seminar', '0061_kill_frankenstein'), ('seminar', '0062_redukce_modelu_pohadky'), ('seminar', '0063_procisteni_migraci'), ('seminar', '0064_auto_20190610_2358'), ('seminar', '0065_treenode_polymorphic_ctype'), ('seminar', '0066_problem_polymorphic_ctype'), ('seminar', '0067_auto_20190814_0805')] + + initial = True + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('taggit', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Cislo', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('cislo', models.CharField(help_text='Většinou jen "1", vyjímečně "7-8", lexikograficky určije pořadí v ročníku!', max_length=32, verbose_name='název čísla')), + ('datum_vydani', models.DateField(blank=True, help_text='Datum vydání finální verze', null=True, verbose_name='datum vydání')), + ('datum_deadline', models.DateField(blank=True, help_text='Datum pro příjem řešení úloh zadaných v tomto čísle', null=True, verbose_name='datum deadline')), + ('verejne_db', models.BooleanField(db_column='verejne', default=False, verbose_name='číslo zveřejněno')), + ], + options={ + 'ordering': ['rocnik__rocnik', 'cislo'], + 'db_table': 'seminar_cisla', + 'verbose_name': 'Číslo', + 'verbose_name_plural': 'Čísla', + }, + ), + migrations.CreateModel( + name='Problem', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('nazev', models.CharField(max_length=256, verbose_name='název')), + ('typ', models.CharField(choices=[(b'uloha', 'Úloha'), (b'tema', 'Téma'), (b'serial', 'Seriál'), (b'org-clanek', 'Organizátorský článek'), (b'res-clanek', 'Řesitelský článek')], default=b'uloha', max_length=32, verbose_name='typ problému')), + ('stav', models.CharField(choices=[(b'navrh', 'Návrh'), (b'zadany', 'Zadaný'), (b'smazany', 'Smazaný')], default=b'navrh', max_length=32, verbose_name='stav problému')), + ('text_problemu_org', models.TextField(blank=True, verbose_name='organizátorský (neveřejný) text')), + ('text_problemu', models.TextField(blank=True, verbose_name='veřejný text zadání a řešení')), + ('kod', models.CharField(blank=True, default=b'', help_text='Číslo/kód úlohy v čísle nebo kód tématu/článku/seriálu v ročníku', max_length=32, verbose_name='lokální kód')), + ('body', models.IntegerField(blank=True, null=True, verbose_name='maximum bodů')), + ('autor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='autor_uloh', to=settings.AUTH_USER_MODEL, verbose_name='autor problému')), + ('cislo_reseni', models.ForeignKey(blank=True, help_text='Číslo s řešením úlohy, jen pro úlohy', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='resene_problemy', to='seminar.Cislo', verbose_name='číslo řešení')), + ('cislo_zadani', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='zadane_problemy', to='seminar.Cislo', verbose_name='číslo zadání')), + ('opravovatel', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='opravovatel_uloh', to=settings.AUTH_USER_MODEL, verbose_name='opravovatel')), + ], + options={ + 'db_table': 'seminar_problemy', + 'verbose_name': 'Problém', + 'verbose_name_plural': 'Problémy', + }, + ), + migrations.CreateModel( + name='Resitel', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('jmeno', models.CharField(max_length=256, verbose_name='jméno')), + ('prijmeni', models.CharField(max_length=256, verbose_name='příjmení')), + ('pohlavi_muz', models.BooleanField(default=False, verbose_name='pohlaví (muž)')), + ('rok_maturity', models.IntegerField(verbose_name='rok maturity')), + ('email', models.EmailField(blank=True, default=b'', max_length=256, verbose_name='e-mail')), + ('telefon', models.CharField(blank=True, default=b'', max_length=256, verbose_name='telefon')), + ('datum_narozeni', models.DateField(blank=True, null=True, verbose_name='datum narození')), + ('datum_souhlasu_udaje', models.DateField(blank=True, help_text='Datum souhlasu se zpracováním osobních údajů', null=True, verbose_name='datum souhlasu (údaje)')), + ('datum_souhlasu_zasilani', models.DateField(blank=True, help_text='Datum souhlasu se zasíláním MFF materiálů', null=True, verbose_name='datum souhlasu (spam)')), + ('datum_prihlaseni', models.DateField(default=django.utils.timezone.now, verbose_name='datum přihlášení')), + ('zasilat', models.CharField(choices=[(b'domu', 'Domů'), (b'do_skoly', 'Do školy'), (b'nikam', 'Nikam')], default=b'domu', max_length=32, verbose_name='kam zasílat')), + ('ulice', models.CharField(blank=True, default=b'', max_length=256, verbose_name='ulice')), + ('mesto', models.CharField(blank=True, default=b'', max_length=256, verbose_name='město')), + ('psc', models.CharField(blank=True, default=b'', max_length=32, verbose_name='PSČ')), + ('stat', django_countries.fields.CountryField(default=b'CZ', help_text='ISO 3166-1 kód země velkými písmeny (CZ, SK, ...)', max_length=2, verbose_name='stát')), + ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k řešiteli (plain text)', verbose_name='neveřejná poznámka')), + ], + options={ + 'ordering': ['prijmeni', 'jmeno'], + 'db_table': 'seminar_resitele', + 'verbose_name': 'Řešitel', + 'verbose_name_plural': 'Řešitelé', + }, + ), + migrations.CreateModel( + name='Rocnik', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('prvni_rok', models.IntegerField(verbose_name='první rok')), + ('rocnik', models.CharField(max_length=16, verbose_name='číslo ročníku')), + ], + options={ + 'ordering': ['rocnik'], + 'db_table': 'seminar_rocniky', + 'verbose_name': 'Ročník', + 'verbose_name_plural': 'Ročníky', + }, + ), + migrations.CreateModel( + name='Skola', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('aesop_id', models.CharField(blank=True, default=b'', help_text='Aesopi ID typu "izo:..." nebo "aesop:..."', max_length=32, verbose_name='Aesop ID')), + ('izo', models.CharField(blank=True, help_text='IZO školy (jen české školy)', max_length=32, verbose_name='IZO')), + ('nazev', models.CharField(help_text='Celý název školy', max_length=256, verbose_name='název')), + ('kratky_nazev', models.CharField(blank=True, help_text=b'Zkr\xc3\xa1cen\xc3\xbd n\xc3\xa1zev pro zobrazen\xc3\xad ve v\xc3\xbdsledkovce', max_length=256, verbose_name='zkrácený název')), + ('ulice', models.CharField(max_length=256, verbose_name='ulice')), + ('mesto', models.CharField(max_length=256, verbose_name='město')), + ('psc', models.CharField(max_length=32, verbose_name='PSČ')), + ('stat', django_countries.fields.CountryField(default=b'CZ', help_text='ISO 3166-1 kód zeme velkými písmeny (CZ, SK, ...)', max_length=2, verbose_name='stát')), + ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka ke škole (plain text)', verbose_name='neveřejná poznámka')), + ], + options={ + 'db_table': 'seminar_skoly', + 'verbose_name': 'Škola', + 'verbose_name_plural': 'Školy', + }, + ), + migrations.CreateModel( + name='Soustredeni', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('datum_zacatku', models.DateField(blank=True, help_text='První den soustředění', null=True, verbose_name='datum začátku')), + ('datum_konce', models.DateField(blank=True, help_text='Poslední den soustředění', null=True, verbose_name='datum konce')), + ('verejne_db', models.BooleanField(db_column='verejne', default=False, verbose_name='soustředění zveřejněno')), + ('misto', models.CharField(blank=True, default=b'', help_text='Místo (název obce, volitelně též objektu', max_length=256, verbose_name='místo soustředění')), + ('rocnik', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='soustredeni', to='seminar.Rocnik', verbose_name='ročník')), + ('ucastnici', models.ManyToManyField(db_table='seminar_soustredeni_ucastnici', help_text='Seznam účastníků soustředění', to='seminar.Resitel', verbose_name='účastníci soustředění')), + ], + options={ + 'ordering': ['rocnik__rocnik', 'datum_zacatku'], + 'db_table': 'seminar_soustredeni', + 'verbose_name': 'Soustředění', + 'verbose_name_plural': 'Soustředění', + }, + ), + migrations.AddField( + model_name='resitel', + name='skola', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Skola', verbose_name='škola'), + ), + migrations.AddField( + model_name='resitel', + name='user', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='uživatel'), + ), + migrations.CreateModel( + name='Reseni', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('body', models.IntegerField(blank=True, null=True, verbose_name='body')), + ('timestamp', models.DateTimeField(auto_now=True, verbose_name='vytvořeno')), + ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k řešení (plain text)', verbose_name='neveřejná poznámka')), + ('cislo_body', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='bodovana_reseni', to='seminar.Cislo', verbose_name='číslo pro body')), + ('problem', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reseni', to='seminar.Problem', verbose_name='problém')), + ('resitel', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reseni', to='seminar.Resitel', verbose_name='řešitel')), + ], + options={ + 'ordering': ['problem', 'resitel'], + 'db_table': 'seminar_reseni', + 'verbose_name': 'Řešení', + 'verbose_name_plural': 'Řešení', + }, + ), + migrations.CreateModel( + name='PrilohaReseni', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('timestamp', models.DateTimeField(auto_now=True, verbose_name='vytvořeno')), + ('soubor', models.FileField(upload_to=seminar.models.generate_filename, verbose_name='soubor')), + ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k příloze řešení (plain text), např. o původu', verbose_name='neveřejná poznámka')), + ('reseni', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='prilohy', to='seminar.Reseni', verbose_name='řešení')), + ], + options={ + 'ordering': ['reseni', 'timestamp'], + 'db_table': 'seminar_priloha_reseni', + 'verbose_name': 'Příloha řešení', + 'verbose_name_plural': 'Přílohy řešení', + }, + ), + migrations.CreateModel( + name='Nastaveni', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('aktualni_cislo', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Cislo', verbose_name='poslední vydané číslo')), + ('aktualni_rocnik', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Rocnik', verbose_name='aktuální ročník')), + ], + options={ + 'db_table': 'seminar_nastaveni', + 'verbose_name': 'Nastavení semináře', + }, + ), + migrations.AddField( + model_name='cislo', + name='rocnik', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='cisla', to='seminar.Rocnik', verbose_name='ročník'), + ), + migrations.AlterField( + model_name='reseni', + name='poznamka', + field=models.TextField(blank=True, help_text='Neveřejná poznámka k řešení (plain text, editace v detailu řešení)', verbose_name='neveřejná poznámka'), + ), + migrations.AddField( + model_name='skola', + name='je_ss', + field=models.BooleanField(default=True, verbose_name='střední stupeň'), + ), + migrations.AddField( + model_name='skola', + name='je_zs', + field=models.BooleanField(default=True, verbose_name='základní stupeň'), + ), + migrations.AlterField( + model_name='problem', + name='autor', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='autor_uloh', to=settings.AUTH_USER_MODEL, verbose_name='autor problému'), + ), + migrations.AddField( + model_name='problem', + name='zamereni', + field=taggit.managers.TaggableManager(blank=True, help_text=b'Zam\xc4\x9b\xc5\x99en\xc3\xad M/F/I/O probl\xc3\xa9mu, p\xc5\x99\xc3\xadp. dal\xc5\xa1\xc3\xad tagy', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='zaměření'), + ), + migrations.AddField( + model_name='reseni', + name='forma', + field=models.CharField(choices=[(b'papir', 'Papírové řešení'), (b'email', 'Emailem'), (b'upload', 'Upload přes web')], default=b'papir', max_length=16, verbose_name='forma řešení'), + ), + migrations.AddField( + model_name='resitel', + name='import_mamoper_id', + field=models.CharField(blank=True, default=b'', help_text='MAMOPER.MM_RIESITELIA.ID z DAKOS importu, jen historický význam', max_length=32, verbose_name='importované MM_RIESITELIA.ID'), + ), + migrations.AddField( + model_name='skola', + name='import_dakos_id', + field=models.CharField(blank=True, default=b'', help_text='DKSROOT.V_SKOLA.ID z DAKOS importu, jen historický význam', max_length=32, verbose_name='importované DKSROOT.V_SKOLA.ID'), + ), + migrations.AlterField( + model_name='resitel', + name='rok_maturity', + field=models.IntegerField(blank=True, null=True, verbose_name='rok maturity'), + ), + migrations.AlterField( + model_name='prilohareseni', + name='timestamp', + field=models.DateTimeField(blank=True, default=django.utils.timezone.now, editable=False, verbose_name='vytvořeno'), + ), + migrations.AddField( + model_name='problem', + name='import_dakos_id', + field=models.CharField(blank=True, default=b'', help_text='ID z importu z DAKOSU s prefixem podle původu: "AZAD:xxx (MAMOPER.MM_AZAD), ""DOZ:xxx" (MAMOPER.MM_DOZ), "ZAD:rocnik.cislo.uloha.typ" (MAMOPER.MM_ZADANIA), "ULOHA:xxx" (MAMOPER.MM_ULOHY)', max_length=32, verbose_name='importované ID s typem'), + ), + migrations.AddField( + model_name='problem', + name='timestamp', + field=models.DateTimeField(blank=True, default=django.utils.timezone.now, editable=False, verbose_name='vytvořeno'), + ), + migrations.AlterField( + model_name='reseni', + name='timestamp', + field=models.DateTimeField(blank=True, default=django.utils.timezone.now, editable=False, verbose_name='vytvořeno'), + ), + migrations.RemoveField( + model_name='soustredeni', + name='ucastnici', + ), + migrations.CreateModel( + name='Soustredeni_Ucastnici', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k účasti (plain text)', verbose_name='neveřejná poznámka')), + ('resitel', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Resitel', verbose_name='řešitel')), + ('soustredeni', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Soustredeni', verbose_name='soustředění')), + ], + options={ + 'ordering': ['soustredeni', 'resitel'], + 'db_table': 'seminar_soustredeni_ucastnici', + 'verbose_name': 'Účast na soustředění', + 'verbose_name_plural': 'Účasti na soustředění', + }, + ), + migrations.AddField( + model_name='soustredeni', + name='ucastnici', + field=models.ManyToManyField(help_text='Seznam účastníků soustředění', through='seminar.Soustredeni_Ucastnici', to='seminar.Resitel', verbose_name='účastníci soustředění'), + ), + migrations.AlterModelOptions( + name='problem', + options={'ordering': ['nazev'], 'verbose_name': 'Problém', 'verbose_name_plural': 'Problémy'}, + ), + migrations.AlterModelOptions( + name='reseni', + options={'ordering': ['problem_id', 'resitel_id'], 'verbose_name': 'Řešení', 'verbose_name_plural': 'Řešení'}, + ), + migrations.AlterModelOptions( + name='skola', + options={'ordering': ['mesto', 'nazev'], 'verbose_name': 'Škola', 'verbose_name_plural': 'Školy'}, + ), + migrations.AddField( + model_name='cislo', + name='poznamka', + field=models.TextField(blank=True, help_text='Neveřejná poznámka k číslu (plain text)', verbose_name='neveřejná poznámka'), + ), + migrations.AlterField( + model_name='reseni', + name='poznamka', + field=models.TextField(blank=True, help_text='Neveřejná poznámka k řešení (plain text)', verbose_name='neveřejná poznámka'), + ), + migrations.AddField( + model_name='soustredeni', + name='text', + field=models.TextField(blank=True, default=b'', verbose_name='text k soustředění (HTML)'), + ), + migrations.RenameField( + model_name='problem', + old_name='text_problemu_org', + new_name='text_org', + ), + migrations.AlterField( + model_name='problem', + name='text_org', + field=models.TextField(blank=True, verbose_name='neveřejné zadání a organizátorské a poznámky'), + ), + migrations.RenameField( + model_name='problem', + old_name='text_problemu', + new_name='text_zadani', + ), + migrations.AlterField( + model_name='problem', + name='text_org', + field=models.TextField(blank=True, help_text='Neveřejný návrh úlohy, návrh řešení, text zadání, poznámky ...', verbose_name='org poznámky (HTML)'), + ), + migrations.AlterField( + model_name='problem', + name='text_zadani', + field=models.TextField(blank=True, help_text='Veřejný text zadání (HTML)', verbose_name='veřejné zadání (HTML)'), + ), + migrations.AddField( + model_name='problem', + name='text_reseni', + field=models.TextField(blank=True, help_text='Veřejný text řešení (HTML, u témat i příspěvky a komentáře)', verbose_name='veřejné řešení (HTML)'), + ), + migrations.CreateModel( + name='ProblemNavrh', + fields=[ + ], + options={ + 'verbose_name': 'Problém (návrh)', + 'proxy': True, + 'verbose_name_plural': 'Problémy (návrhy)', + }, + bases=('seminar.problem',), + ), + migrations.CreateModel( + name='ProblemZadany', + fields=[ + ], + options={ + 'verbose_name': 'Problém (zadaný)', + 'proxy': True, + 'verbose_name_plural': 'Problémy (zadané)', + }, + bases=('seminar.problem',), + ), + migrations.AddField( + model_name='rocnik', + name='rocnik_n', + field=models.IntegerField(default=0, verbose_name='číslo ročníku'), + preserve_default=False, + ), + migrations.RunSQL( + sql='update seminar_rocniky set rocnik_n = cast (rocnik as integer)', + reverse_sql='update seminar_rocniky set rocnik_n = cast (rocnik as nvarchar(16))', + ), + migrations.RemoveField( + model_name='rocnik', + name='rocnik', + ), + migrations.RenameField( + model_name='rocnik', + old_name='rocnik_n', + new_name='rocnik', + ), + migrations.AlterModelOptions( + name='cislo', + options={'ordering': ['-rocnik__rocnik', '-cislo'], 'verbose_name': 'Číslo', 'verbose_name_plural': 'Čísla'}, + ), + migrations.AlterModelOptions( + name='reseni', + options={'ordering': ['problem_id', 'resitel__prijmeni', 'resitel__jmeno'], 'verbose_name': 'Řešení', 'verbose_name_plural': 'Řešení'}, + ), + migrations.AlterModelOptions( + name='rocnik', + options={'ordering': ['-rocnik'], 'verbose_name': 'Ročník', 'verbose_name_plural': 'Ročníky'}, + ), + migrations.AlterField( + model_name='cislo', + name='cislo', + field=models.CharField(db_index=True, help_text='Většinou jen "1", vyjímečně "7-8", lexikograficky určije pořadí v ročníku!', max_length=32, verbose_name='název čísla'), + ), + migrations.AlterField( + model_name='rocnik', + name='prvni_rok', + field=models.IntegerField(db_index=True, unique=True, verbose_name='první rok'), + ), + migrations.AlterField( + model_name='rocnik', + name='rocnik', + field=models.IntegerField(db_index=True, unique=True, verbose_name='číslo ročníku'), + ), + migrations.AddField( + model_name='cislo', + name='verejna_vysledkovka', + field=models.BooleanField(default=False, help_text='Je-li false u veřejného čísla, není výsledkovka zatím veřejná.', verbose_name='zveřejněna výsledkovka'), + ), + migrations.AlterField( + model_name='problem', + name='body', + field=models.DecimalField(blank=True, decimal_places=1, max_digits=8, null=True, verbose_name='maximum bodů'), + ), + migrations.AlterField( + model_name='reseni', + name='body', + field=models.DecimalField(blank=True, decimal_places=1, max_digits=8, null=True, verbose_name='body'), + ), + migrations.CreateModel( + name='Novinky', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('datum', models.DateField(auto_now_add=True)), + ('text', models.TextField(blank=True, null=True, verbose_name=b'Text novinky')), + ('obrazek', models.ImageField(blank=True, null=True, upload_to=b'image_novinky/%Y/%m/%d/', verbose_name=b'Obr\xc3\xa1zek')), + ('zverejneno', models.BooleanField(default=False, verbose_name=b'Zve\xc5\x99ejn\xc4\x9bno')), + ('autor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name=b'Autor novinky')), + ], + options={ + 'verbose_name': 'Novinka', + 'verbose_name_plural': 'Novinky', + }, + ), + migrations.CreateModel( + name='Organizator', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('prezdivka', models.CharField(blank=True, max_length=32, null=True, verbose_name=b'P\xc5\x99ezd\xc3\xadvka')), + ('organizuje_od_roku', models.IntegerField(blank=True, null=True, verbose_name=b'Organizuje od roku')), + ('organizuje_do_roku', models.IntegerField(blank=True, null=True, verbose_name=b'Organizuje do roku')), + ('studuje', models.CharField(blank=True, max_length=256, null=True, verbose_name=b'Studuje')), + ('strucny_popis_organizatora', models.TextField(blank=True, null=True, verbose_name=b'Stru\xc4\x8dn\xc3\xbd popis organiz\xc3\xa1tora')), + ('foto', models.ImageField(blank=True, help_text=b'Vlo\xc5\xbe fotografii organiz\xc3\xa1tora o libovon\xc3\xa9 velikosti', null=True, upload_to=b'image_organizatori/velke/%Y/', verbose_name=b'Fotografie organiz\xc3\xa1tora')), + ('foto_male', models.ImageField(blank=True, editable=False, null=True, upload_to=b'image_organizatori/male/%Y/')), + ('user', models.OneToOneField(help_text=b'Vyber \xc3\xba\xc4\x8det sp\xc5\x99a\xc5\xbeen\xc3\xbd s organiz\xc3\xa1torem.', on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name=b'Osoba')), + ], + options={ + 'verbose_name': 'Organizátor', + 'verbose_name_plural': 'Organizátoři', + }, + ), + migrations.AddField( + model_name='rocnik', + name='exportovat', + field=models.BooleanField(db_column='exportovat', default=False, help_text='Exportuje se jen podle tohoto flagu (ne veřejnosti), a to jen čísla s veřejnou výsledkovkou', verbose_name='export do AESOPa'), + ), + migrations.AddField( + model_name='soustredeni', + name='exportovat', + field=models.BooleanField(db_column='exportovat', default=False, help_text='Exportuje se jen podle tohoto flagu (ne veřejnosti)', verbose_name='export do AESOPa'), + ), + migrations.AddField( + model_name='soustredeni', + name='typ', + field=models.CharField(choices=[(b'jarni', 'Jarní soustředění'), (b'podzimni', 'Podzimní soustředění'), (b'vikend', 'Víkendový sraz')], default=b'podzimni', max_length=16, verbose_name='typ akce'), + ), + migrations.AlterField( + model_name='organizator', + name='foto', + field=models.ImageField(blank=True, help_text=b'Vlo\xc5\xbe fotografii organiz\xc3\xa1tora o libovoln\xc3\xa9 velikosti', null=True, upload_to=b'image_organizatori/velke/%Y/', verbose_name=b'Fotografie organiz\xc3\xa1tora'), + ), + migrations.AlterModelOptions( + name='soustredeni', + options={'ordering': ['-rocnik__rocnik', '-datum_zacatku'], 'verbose_name': 'Soustředění', 'verbose_name_plural': 'Soustředění'}, + ), + migrations.AlterField( + model_name='cislo', + name='cislo', + field=models.CharField(db_index=True, help_text='Většinou jen "1", vyjímečně "7-8", lexikograficky určuje pořadí v ročníku!', max_length=32, verbose_name='název čísla'), + ), + migrations.AddField( + model_name='cislo', + name='pdf', + field=models.FileField(blank=True, help_text='Pdf čísla, které si mohou řešitelé stáhnout', null=True, upload_to=seminar.models.cislo_pdf_filename, verbose_name='pdf'), + ), + migrations.AlterField( + model_name='problem', + name='typ', + field=models.CharField(choices=[(b'uloha', 'Úloha'), (b'tema', 'Téma'), (b'serial', 'Seriál'), (b'org-clanek', 'Organizátorský článek'), (b'res-clanek', 'Řešitelský článek')], default=b'uloha', max_length=32, verbose_name='typ problému'), + ), + migrations.AlterField( + model_name='skola', + name='stat', + field=django_countries.fields.CountryField(default=b'CZ', help_text='ISO 3166-1 kód země velkými písmeny (CZ, SK, ...)', max_length=2, verbose_name='stát'), + ), + migrations.AlterField( + model_name='organizator', + name='studuje', + field=models.CharField(blank=True, help_text=b"Nap\xc5\x99. 'Studuje Obecnou fyziku (Bc.), 3. ro\xc4\x8dn\xc3\xadk', 'Vystudovala Diskr\xc3\xa9tn\xc3\xad modely a algoritmy (Mgr.)' nebo 'P\xc5\x99edn\xc3\xa1\xc5\xa1\xc3\xad na MFF'", max_length=256, null=True, verbose_name=b'Studium aj.'), + ), + migrations.AlterField( + model_name='reseni', + name='forma', + field=models.CharField(choices=[(b'papir', 'Papírové řešení'), (b'email', 'Emailem'), (b'upload', 'Upload přes web')], default=b'email', max_length=16, verbose_name='forma řešení'), + ), + migrations.RemoveField( + model_name='organizator', + name='foto_male', + ), + migrations.AlterField( + model_name='organizator', + name='foto', + field=imagekit.models.fields.ProcessedImageField(blank=True, help_text=b'Vlo\xc5\xbe fotografii organiz\xc3\xa1tora o libovoln\xc3\xa9 velikosti', null=True, upload_to=b'image_organizatori/velke/%Y/', verbose_name=b'Fotografie organiz\xc3\xa1tora'), + ), + migrations.CreateModel( + name='Soustredeni_Organizatori', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k účasti organizátora (plain text)', verbose_name='neveřejná poznámka')), + ('organizator', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Organizator', verbose_name='organizátor')), + ('soustredeni', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Soustredeni', verbose_name='soustředění')), + ], + options={ + 'ordering': ['soustredeni', 'organizator'], + 'db_table': 'seminar_soustredeni_organizatori', + 'verbose_name': 'Účast organizátorů na soustředění', + 'verbose_name_plural': 'Účasti organizátorů na soustředění', + }, + ), + migrations.AddField( + model_name='soustredeni', + name='organizatori', + field=models.ManyToManyField(help_text='Seznam organizátorů soustředění', through='seminar.Soustredeni_Organizatori', to='seminar.Organizator', verbose_name='Organizátoři soustředění'), + ), + migrations.CreateModel( + name='Prispevek', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('nazev', models.CharField(max_length=200, verbose_name=b'N\xc3\xa1zev')), + ('text_org', models.TextField(blank=True, null=True, verbose_name=b'Orgovsk\xc3\xbd text')), + ('text_resitel', models.TextField(blank=True, null=True, verbose_name=b'\xc5\x98e\xc5\xa1itelsk\xc3\xbd text')), + ('zverejnit', models.BooleanField(verbose_name=b'Zve\xc5\x99ejnit?')), + ('problem', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Problem', verbose_name=b'Probl\xc3\xa9m')), + ('reseni', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Reseni', verbose_name=b'\xc5\x98e\xc5\xa1en\xc3\xad')), + ], + options={ + 'abstract': False, + 'verbose_name': 'Příspěvek k problému', + 'verbose_name_plural': 'Příspěvky k problémům', + }, + ), + migrations.CreateModel( + name='Konfera', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('nazev', models.CharField(help_text='Název konfery', max_length=40, verbose_name='název konfery')), + ('popis', models.TextField(blank=True, help_text='Popis konfery k zobrazení na webu', verbose_name='popis konfery')), + ('abstrakt', models.TextField(blank=True, help_text='Abstrakt konfery tak, jak byl uveden ve sborníku', verbose_name='abstrakt')), + ('org_poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka ke konfeře(plain text)', verbose_name='neveřejná poznámka')), + ('typ_prezentace', models.CharField(choices=[(b'veletrh', 'Veletrh (postery)'), (b'prezentace', 'Prezentace (přednáška)')], default=b'veletrh', max_length=16, verbose_name='typ prezentace')), + ('prezentace', models.FileField(help_text='Prezentace nebo fotka posteru', upload_to=seminar.models.generate_filename_konfera, verbose_name='prezentace')), + ('materialy', models.FileField(help_text='Další materiály ke konfeře zabalené do jednoho souboru', upload_to=seminar.models.generate_filename_konfera, verbose_name='materialy')), + ('organizator', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='konfery', to='seminar.Organizator', verbose_name='organizátor')), + ('soustredeni', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='konfery', to='seminar.Soustredeni', verbose_name='soustředění')), + ], + options={ + 'db_table': 'seminar_konfera', + 'verbose_name': 'Konfera', + 'verbose_name_plural': 'Konfery', + }, + ), + migrations.CreateModel( + name='Konfery_Ucastnici', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k účasti (plain text)', verbose_name='neveřejná poznámka')), + ('konfera', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Konfera', verbose_name='konfera')), + ('resitel', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Resitel', verbose_name='řešitel')), + ], + options={ + 'ordering': ['konfera', 'resitel'], + 'db_table': 'seminar_konfery_ucastnici', + 'verbose_name': 'Účast na konfeře', + 'verbose_name_plural': 'Účasti na konfeře', + }, + ), + migrations.AlterField( + model_name='problem', + name='typ', + field=models.CharField(choices=[(b'uloha', 'Úloha'), (b'tema', 'Téma'), (b'serial', 'Seriál'), (b'konfera', 'Konfera'), (b'org-clanek', 'Organizátorský článek'), (b'res-clanek', 'Řešitelský článek')], default=b'uloha', max_length=32, verbose_name='typ problému'), + ), + migrations.AddField( + model_name='konfera', + name='ucastnici', + field=models.ManyToManyField(help_text='Seznam účastníků konfery', through='seminar.Konfery_Ucastnici', to='seminar.Resitel', verbose_name='účastníci konfery'), + ), + migrations.AlterField( + model_name='konfera', + name='materialy', + field=models.FileField(blank=True, help_text='Další materiály ke konfeře zabalené do jednoho souboru', upload_to=seminar.models.generate_filename_konfera, verbose_name='materialy'), + ), + migrations.AlterField( + model_name='konfera', + name='prezentace', + field=models.FileField(blank=True, help_text='Prezentace nebo fotka posteru', upload_to=seminar.models.generate_filename_konfera, verbose_name='prezentace'), + ), + migrations.AddField( + model_name='konfera', + name='prispevek', + field=models.ForeignKey(blank=True, help_text='Účastnický přípěvek o konfeře', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='konfery', to='seminar.Problem', verbose_name='příspěvek do čísla'), + ), + migrations.AddField( + model_name='cislo', + name='faze', + field=models.CharField(choices=[('admin', 'Úpravy na webu'), ('tex', 'Úpravy v TeXu'), ('nahrano', 'Nahráno na web')], default='admin', help_text='Během fáze "Úpravy na webu" se obsah čísla vytváří (a případně komentuje) ve webovém rozhraní. Během fáze "Úpravy v TeXu" už obsah ve webovém rozhraní editovat nelze a návrhy na úpravy se píší do korekturovátka a zanášejí do gitu. Z něj se pak vygeneruje verze pro web a číslo se přepne do fáze "Nahráno na web", což jen znamená, že už nejde automaticky stáhnout obsah pro založení čísla v TeXu.', max_length=32, verbose_name='Fáze vytváření obsahu'), + ), + migrations.AddField( + model_name='cislo', + name='datum_deadline_soustredeni', + field=models.DateField(blank=True, help_text='Datum pro příjem řešení pro účast na soustředění', null=True, verbose_name='datum deadline soustředění'), + ), + migrations.CreateModel( + name='Osoba', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('jmeno', models.CharField(max_length=256, verbose_name='jméno')), + ('prijmeni', models.CharField(max_length=256, verbose_name='příjmení')), + ('prezdivka', models.CharField(max_length=256, verbose_name='přezdívka')), + ('pohlavi_muz', models.BooleanField(default=False, verbose_name='pohlaví (muž)')), + ('email', models.EmailField(blank=True, default='', max_length=256, verbose_name='e-mail')), + ('telefon', models.CharField(blank=True, default='', max_length=256, verbose_name='telefon')), + ('datum_narozeni', models.DateField(blank=True, null=True, verbose_name='datum narození')), + ('datum_souhlasu_udaje', models.DateField(blank=True, help_text='Datum souhlasu se zpracováním osobních údajů', null=True, verbose_name='datum souhlasu (údaje)')), + ('datum_souhlasu_zasilani', models.DateField(blank=True, help_text='Datum souhlasu se zasíláním MFF materiálů', null=True, verbose_name='datum souhlasu (spam)')), + ('datum_registrace', models.DateField(default=django.utils.timezone.now, verbose_name='datum registrace do semináře')), + ('ulice', models.CharField(blank=True, default='', max_length=256, verbose_name='ulice')), + ('mesto', models.CharField(blank=True, default='', max_length=256, verbose_name='město')), + ('psc', models.CharField(blank=True, default='', max_length=32, verbose_name='PSČ')), + ('stat', django_countries.fields.CountryField(default='CZ', help_text='ISO 3166-1 kód země velkými písmeny (CZ, SK, ...)', max_length=2, verbose_name='stát')), + ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k osobě (plain text)', verbose_name='neveřejná poznámka')), + ('foto', imagekit.models.fields.ProcessedImageField(blank=True, help_text='Vlož fotografii osoby o libovolné velikosti', null=True, upload_to='image_osoby/velke/%Y/', verbose_name='Fotografie osoby')), + ('user', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='uživatel')), + ], + options={ + 'verbose_name': 'Osoba', + 'verbose_name_plural': 'Osoby', + 'db_table': 'seminar_osoby', + 'ordering': ['prijmeni', 'jmeno'], + }, + ), + migrations.CreateModel( + name='Prijemce', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k příemci čísel (plain text)', verbose_name='neveřejná poznámka')), + ('osoba', models.ForeignKey(help_text='Které osobě či na jakou adresu se mají zasílat čísla', on_delete=django.db.models.deletion.CASCADE, to='seminar.Osoba', verbose_name='komu')), + ], + options={ + 'verbose_name': 'příjemce', + 'verbose_name_plural': 'příjemce', + 'db_table': 'seminar_prijemce', + }, + ), + migrations.CreateModel( + name='Text', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('na_web', models.TextField(blank=True, help_text='Text ke zveřejnění na webu', verbose_name='text na web')), + ('do_cisla', models.TextField(blank=True, help_text='Text ke zveřejnění v čísle', verbose_name='text do čísla')), + ], + options={ + 'verbose_name': 'text', + 'verbose_name_plural': 'texty', + 'db_table': 'seminar_texty', + }, + ), + migrations.CreateModel( + name='Uloha', + fields=[ + ('problem_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.Problem')), + ('max_body', models.DecimalField(blank=True, decimal_places=1, max_digits=8, null=True, verbose_name='maximum bodů')), + ], + options={ + 'verbose_name': 'Úloha', + 'verbose_name_plural': 'Úlohy', + 'db_table': 'seminar_ulohy', + }, + bases=('seminar.problem',), + ), + migrations.AlterModelOptions( + name='novinky', + options={'ordering': ['-datum'], 'verbose_name': 'Novinka', 'verbose_name_plural': 'Novinky'}, + ), + migrations.AlterModelOptions( + name='prilohareseni', + options={'ordering': ['reseni', 'vytvoreno'], 'verbose_name': 'Příloha řešení', 'verbose_name_plural': 'Přílohy řešení'}, + ), + migrations.AlterModelOptions( + name='reseni', + options={'ordering': ['-cas_doruceni'], 'verbose_name': 'Řešení', 'verbose_name_plural': 'Řešení'}, + ), + migrations.AlterModelOptions( + name='resitel', + options={'ordering': ['osoba'], 'verbose_name': 'Řešitel', 'verbose_name_plural': 'Řešitelé'}, + ), + migrations.RenameField( + model_name='konfera', + old_name='org_poznamka', + new_name='poznamka', + ), + migrations.RenameField( + model_name='reseni', + old_name='timestamp', + new_name='cas_doruceni', + ), + migrations.RenameField( + model_name='prilohareseni', + old_name='timestamp', + new_name='vytvoreno', + ), + migrations.RenameField( + model_name='problem', + old_name='text_org', + new_name='poznamka', + ), + migrations.RenameField( + model_name='problem', + old_name='timestamp', + new_name='vytvoreno', + ), + migrations.RenameField( + model_name='problem', + old_name='cislo_zadani', + new_name='cislo_zadani_old', + ), + migrations.RenameField( + model_name='problem', + old_name='cislo_reseni', + new_name='cislo_reseni_old', + ), + migrations.AddField( + model_name='konfera', + name='anotace', + field=models.TextField(blank=True, help_text='Popis, o čem bude konfera.', verbose_name='anotace'), + ), + migrations.AddField( + model_name='organizator', + name='organizuje_do', + field=models.DateTimeField(blank=True, null=True, verbose_name='Organizuje do'), + ), + migrations.AddField( + model_name='organizator', + name='organizuje_od', + field=models.DateTimeField(blank=True, null=True, verbose_name='Organizuje od'), + ), + migrations.AddField( + model_name='organizator', + name='skola', + field=models.CharField(blank=True, help_text='Škola, např. MFF, VŠCHT, VUT, ... prostě aby se nemuselo psát do studuješkolu, ale jen obor, možnost zobrazit zvlášť', max_length=256, null=True, verbose_name='Škola, kterou studuje'), + ), + migrations.AddField( + model_name='organizator', + name='vytvoreno', + field=models.DateTimeField(blank=True, default=django.utils.timezone.now, editable=False, verbose_name='Vytvořeno'), + ), + migrations.AddField( + model_name='problem', + name='garant', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='garant_problemu_problem', to='seminar.Organizator', verbose_name='garant zadaného problému'), + ), + migrations.AddField( + model_name='problem', + name='nadproblem', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='nadproblem_problem', to='seminar.Problem', verbose_name='nadřazený problém'), + ), + migrations.AddField( + model_name='problem', + name='opravovatele', + field=models.ManyToManyField(blank=True, related_name='opravovatele_problem', to='seminar.Organizator', verbose_name='opravovatelé'), + ), + migrations.AddField( + model_name='reseni', + name='zverejneno', + field=models.BooleanField(default=False, help_text='Udává, zda je řešení zveřejněno', verbose_name='řešení zveřejněno'), + ), + migrations.AlterField( + model_name='cislo', + name='verejna_vysledkovka', + field=models.BooleanField(default=False, help_text='Je-li false u veřejného čísla,\t\t\t\t není výsledkovka zatím veřejná.', verbose_name='zveřejněna výsledkovka'), + ), + migrations.AlterField( + model_name='cislo', + name='verejne_db', + field=models.BooleanField(db_column='verejne', default=False, verbose_name='číslo zveřejněno'), + ), + migrations.AlterField( + model_name='konfera', + name='typ_prezentace', + field=models.CharField(choices=[('veletrh', 'Veletrh (postery)'), ('prezentace', 'Prezentace (přednáška)')], default='veletrh', max_length=16, verbose_name='typ prezentace'), + ), + migrations.RenameField( + model_name='novinky', + old_name='autor', + new_name='autor_old', + ), + migrations.AddField( + model_name='novinky', + name='autor', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Organizator', verbose_name='Autor novinky'), + ), + migrations.AlterField( + model_name='novinky', + name='obrazek', + field=models.ImageField(blank=True, null=True, upload_to='image_novinky/%Y/%m/%d/', verbose_name='Obrázek'), + ), + migrations.AlterField( + model_name='novinky', + name='text', + field=models.TextField(blank=True, null=True, verbose_name='Text novinky'), + ), + migrations.AlterField( + model_name='novinky', + name='zverejneno', + field=models.BooleanField(default=False, verbose_name='Zveřejněno'), + ), + migrations.AlterField( + model_name='organizator', + name='strucny_popis_organizatora', + field=models.TextField(blank=True, null=True, verbose_name='Stručný popis organizátora'), + ), + migrations.AlterField( + model_name='organizator', + name='studuje', + field=models.CharField(blank=True, help_text="Např. 'Studuje Obecnou fyziku (Bc.), 3. ročník', 'Vystudovala Diskrétní modely a algoritmy (Mgr.)' nebo 'Přednáší na MFF'", max_length=256, null=True, verbose_name='Studium aj.'), + ), + migrations.CreateModel( + name='Pohadka', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('text', models.TextField(verbose_name='Text pohádky')), + ('pred', models.BooleanField(default=True, verbose_name='Před úlohou')), + ('vytvoreno', models.DateTimeField(blank=True, default=django.utils.timezone.now, editable=False, verbose_name='Vytvořeno')), + ('autor_old', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name=b'Autor poh\xc3\xa1dky')), + ('uloha_old', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='pohadky', to='seminar.Problem', verbose_name='Úloha')), + ('autor', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Organizator', verbose_name='Autor pohádky')), + ('uloha', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='pohadky', to='seminar.Uloha', verbose_name='Úloha')), + ], + options={ + 'ordering': ['uloha__cislo_zadani', 'uloha__kod', '-pred'], + 'db_table': 'seminar_pohadky', + 'verbose_name': 'Pohádka', + 'verbose_name_plural': 'Pohádky', + }, + ), + migrations.RenameField( + model_name='problem', + old_name='autor', + new_name='autor_old', + ), + migrations.AddField( + model_name='problem', + name='autor', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='autor_problemu_problem', to='seminar.Organizator', verbose_name='autor problému'), + ), + migrations.AlterField( + model_name='problem', + name='kod', + field=models.CharField(blank=True, default='', help_text='Číslo/kód úlohy v čísle nebo kód tématu/článku/seriálu v ročníku', max_length=32, verbose_name='lokální kód'), + ), + migrations.AlterField( + model_name='problem', + name='stav', + field=models.CharField(choices=[('navrh', 'Návrh'), ('zadany', 'Zadaný'), ('vyreseny', 'Vyřešený'), ('smazany', 'Smazaný')], default='navrh', max_length=32, verbose_name='stav problému'), + ), + migrations.AlterField( + model_name='problem', + name='zamereni', + field=taggit.managers.TaggableManager(blank=True, help_text='Zaměření M/F/I/O problému, příp. další tagy', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='zaměření'), + ), + migrations.AlterField( + model_name='reseni', + name='forma', + field=models.CharField(choices=[('papir', 'Papírové řešení'), ('email', 'Emailem'), ('upload', 'Upload přes web')], default='email', max_length=16, verbose_name='forma řešení'), + ), + migrations.RenameField( + model_name='reseni', + old_name='problem', + new_name='problem_old', + ), + migrations.AlterField( + model_name='resitel', + name='zasilat', + field=models.CharField(choices=[('domu', 'Domů'), ('do_skoly', 'Do školy'), ('nikam', 'Nikam')], default='domu', max_length=32, verbose_name='kam zasílat'), + ), + migrations.AlterField( + model_name='rocnik', + name='exportovat', + field=models.BooleanField(db_column='exportovat', default=False, help_text='Exportuje se jen podle tohoto flagu (ne veřejnosti), a to jen čísla s veřejnou výsledkovkou', verbose_name='export do AESOPa'), + ), + migrations.AlterField( + model_name='skola', + name='aesop_id', + field=models.CharField(blank=True, default='', help_text='Aesopi ID typu "izo:..." nebo "aesop:..."', max_length=32, verbose_name='Aesop ID'), + ), + migrations.AlterField( + model_name='skola', + name='kratky_nazev', + field=models.CharField(blank=True, help_text='Zkrácený název pro zobrazení ve výsledkovce', max_length=256, verbose_name='zkrácený název'), + ), + migrations.AlterField( + model_name='skola', + name='stat', + field=django_countries.fields.CountryField(default='CZ', help_text='ISO 3166-1 kód země velkými písmeny (CZ, SK, ...)', max_length=2, verbose_name='stát'), + ), + migrations.AlterField( + model_name='soustredeni', + name='exportovat', + field=models.BooleanField(db_column='exportovat', default=False, help_text='Exportuje se jen podle tohoto flagu (ne veřejnosti)', verbose_name='export do AESOPa'), + ), + migrations.AlterField( + model_name='soustredeni', + name='misto', + field=models.CharField(blank=True, default='', help_text='Místo (název obce, volitelně též objektu', max_length=256, verbose_name='místo soustředění'), + ), + migrations.AlterField( + model_name='soustredeni', + name='text', + field=models.TextField(blank=True, default='', verbose_name='text k soustředění (HTML)'), + ), + migrations.AlterField( + model_name='soustredeni', + name='typ', + field=models.CharField(choices=[('jarni', 'Jarní soustředění'), ('podzimni', 'Podzimní soustředění'), ('vikend', 'Víkendový sraz')], default='podzimni', max_length=16, verbose_name='typ akce'), + ), + migrations.AlterField( + model_name='soustredeni', + name='verejne_db', + field=models.BooleanField(db_column='verejne', default=False, verbose_name='soustředění zveřejněno'), + ), + migrations.AlterModelTable( + name='problem', + table='seminar_problemy', + ), + migrations.AddField( + model_name='uloha', + name='cislo_deadline', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='deadlinove_ulohy', to='seminar.Cislo', verbose_name='číslo deadlinu'), + ), + migrations.AddField( + model_name='uloha', + name='cislo_reseni', + field=models.ForeignKey(blank=True, help_text='Číslo s řešením úlohy, jen pro úlohy', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='resene_ulohy', to='seminar.Cislo', verbose_name='číslo řešení'), + ), + migrations.AddField( + model_name='uloha', + name='cislo_zadani', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='zadane_ulohy', to='seminar.Cislo', verbose_name='číslo zadání'), + ), + migrations.CreateModel( + name='Tema', + fields=[ + ('problem_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.Problem')), + ('tema_typ', models.CharField(choices=[('tema', 'Téma'), ('serial', 'Seriál')], default='tema', max_length=16, verbose_name='Typ tématu')), + ('rocnik', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Rocnik', verbose_name='ročník')), + ], + options={ + 'verbose_name': 'Téma', + 'verbose_name_plural': 'Témata', + 'db_table': 'seminar_temata', + }, + bases=('seminar.problem',), + ), + migrations.CreateModel( + name='Reseni_Resitele', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('reseni', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Reseni', verbose_name='řešení')), + ('resitele', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Resitel', verbose_name='řešitel')), + ], + options={ + 'verbose_name': 'Řešení řešitelů', + 'verbose_name_plural': 'Řešení řešitelů', + 'db_table': 'seminar_reseni_resitele', + 'ordering': ['reseni', 'resitele'], + }, + ), + migrations.CreateModel( + name='Obrazek', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('na_web', models.ImageField(blank=True, null=True, upload_to='obrazky/%Y/%m/%d/', verbose_name='obrázek na web')), + ('do_cisla_barevny', models.FileField(blank=True, help_text='Barevná verze obrázku do čísla', null=True, upload_to='obrazky/%Y/%m/%d/', verbose_name='barevný obrázek do čísla')), + ('do_cisla_cernobily', models.FileField(blank=True, help_text='Černobílá verze obrázku do čísla', null=True, upload_to='obrazky/%Y/%m/%d/', verbose_name='černobílý obrázek do čísla')), + ('text', models.ForeignKey(help_text='text, ve kterém se obrázek vyskytuje', on_delete=django.db.models.deletion.CASCADE, to='seminar.Text', verbose_name='text')), + ], + options={ + 'verbose_name': 'obrázek', + 'verbose_name_plural': 'obrázky', + 'db_table': 'seminar_obrazky', + }, + ), + migrations.CreateModel( + name='Hodnoceni', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('body', models.DecimalField(decimal_places=1, max_digits=8, verbose_name='body')), + ('cislo_body', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='hodnoceni', to='seminar.Cislo', verbose_name='číslo pro body', null=True)), + ('problem', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Problem', verbose_name='problém')), + ('reseni', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Reseni', verbose_name='řešení')), + ], + options={ + 'verbose_name': 'Hodnocení', + 'verbose_name_plural': 'Hodnocení', + 'db_table': 'seminar_hodnoceni', + }, + ), + migrations.CreateModel( + name='Clanek', + fields=[ + ('problem_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.Problem')), + ('cislo', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Cislo', verbose_name='číslo')), + ], + options={ + 'verbose_name': 'Článek', + 'verbose_name_plural': 'Články', + 'db_table': 'seminar_clanky', + }, + bases=('seminar.problem',), + ), + migrations.AddField( + model_name='reseni', + name='resitele', + field=models.ManyToManyField(help_text='Seznam autorů řešení', through='seminar.Reseni_Resitele', to='seminar.Resitel', verbose_name='autoři řešení'), + ), + migrations.AddField( + model_name='reseni', + name='text_cely', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='reseni_cely_set', to='seminar.Text', verbose_name='Plná verze textu řešení'), + ), + migrations.AddField( + model_name='reseni', + name='text_zkraceny', + field=models.ManyToManyField(help_text='Seznam úryvků z řešení', related_name='reseni_zkraceny_set', to='seminar.Text', verbose_name='zkrácené verze řešení'), + ), + migrations.AddField( + model_name='skola', + name='kontaktni_osoba', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Osoba', verbose_name='Kontaktní osoba'), + ), + migrations.AddField( + model_name='reseni', + name='problem', + field=models.ManyToManyField(help_text='Problém', through='seminar.Hodnoceni', to='seminar.Problem', verbose_name='problém'), + ), + migrations.AddField( + model_name='konfera', + name='reseni', + field=models.OneToOneField(blank=True, help_text='Účastnický přípěvek o konfeře', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='konfery', to='seminar.Reseni', verbose_name='článek ke konfeře'), + ), + migrations.AddField( + model_name='organizator', + name='osoba', + field=models.OneToOneField(help_text='osobní údaje organizátora', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='org', to='seminar.Osoba', verbose_name='osoba'), + ), + migrations.AddField( + model_name='resitel', + name='osoba', + field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Osoba', verbose_name='osoba'), + ), + migrations.CreateModel( + name='TreeNode', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('first_child', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.TreeNode', verbose_name='první potomek')), + ('root', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='potomci_set', to='seminar.TreeNode', verbose_name='kořen stromu')), + ('succ', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='prev', to='seminar.TreeNode', verbose_name='další element na stejné úrovni')), + ], + options={ + 'verbose_name': 'TreeNode', + 'verbose_name_plural': 'TreeNody', + 'db_table': 'seminar_nodes_treenode', + }, + ), + migrations.CreateModel( + name='CisloNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('cislo', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='seminar.Cislo', verbose_name='číslo')), + ], + options={ + 'verbose_name': 'Číslo (Node)', + 'verbose_name_plural': 'Čísla (Node)', + 'db_table': 'seminar_nodes_cislo', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='ClanekNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('clanek', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Clanek', verbose_name='článek')), + ], + options={ + 'verbose_name': 'Článek (Node)', + 'verbose_name_plural': 'Články (Node)', + 'db_table': 'seminar_nodes_clanek', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='KonferaNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('konfera', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Konfera', verbose_name='konfera')), + ], + options={ + 'verbose_name': 'Konfera (Node)', + 'verbose_name_plural': 'Konfery (Node)', + 'db_table': 'seminar_nodes_konfera', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='MezicisloNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ], + options={ + 'verbose_name': 'Mezičíslo (Node)', + 'verbose_name_plural': 'Mezičísla (Node)', + 'db_table': 'seminar_nodes_mezicislo', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='RocnikNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('rocnik', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='seminar.Rocnik', verbose_name='ročník')), + ], + options={ + 'verbose_name': 'Ročník (Node)', + 'verbose_name_plural': 'Ročníky (Node)', + 'db_table': 'seminar_nodes_rocnik', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='TemaVCisleNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('tema', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Tema', verbose_name='téma v čísle')), + ], + options={ + 'verbose_name': 'Téma v čísle (Node)', + 'verbose_name_plural': 'Témata v čísle (Node)', + 'db_table': 'seminar_nodes_temavcisle', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='TextNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('text', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Text', verbose_name='text')), + ], + options={ + 'verbose_name': 'Text (Node)', + 'verbose_name_plural': 'Text (Node)', + 'db_table': 'seminar_nodes_obsah', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='UlohaVzorakNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('uloha', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Uloha', verbose_name='úloha')), + ], + options={ + 'verbose_name': 'Vzorák úlohy (Node)', + 'verbose_name_plural': 'Vzoráky úloh (Node)', + 'db_table': 'seminar_nodes_uloha_vzorak', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='UlohaZadaniNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('uloha', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Uloha', verbose_name='úloha')), + ], + options={ + 'verbose_name': 'Zadání úlohy (Node)', + 'verbose_name_plural': 'Zadání úloh (Node)', + 'db_table': 'seminar_nodes_uloha_zadani', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='PohadkaNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('pohadka', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='seminar.Pohadka', verbose_name='pohádka')), + ], + options={ + 'verbose_name': 'Pohádka (Node)', + 'verbose_name_plural': 'Pohádky (Node)', + 'db_table': 'seminar_nodes_pohadka', + }, + bases=('seminar.treenode',), + ), + + # migr 0051 + migrations.RunPython( + resitel_to_osoba, + reverse_code=osoba_to_resitel, + ), + + # migr 0052 + migrations.RunPython( + spoj_k_organizatorum_osoby, + reverse_code=migrations.RunPython.noop, + ), + migrations.RunPython( + fix_problem, + reverse_code=migrations.RunPython.noop, + ), + migrations.RunPython( + fix_pohadka, + reverse_code=migrations.RunPython.noop, + ), + migrations.RunPython( + fix_novinka, + reverse_code=migrations.RunPython.noop, + ), + + # migr 0053 + migrations.RunPython( + rok_to_datetime, + reverse_code=datetime_to_rok, + ), + + migrations.RemoveField( + model_name='prispevek', + name='problem', + ), + migrations.RemoveField( + model_name='prispevek', + name='reseni', + ), + migrations.DeleteModel( + name='ProblemNavrh', + ), + migrations.DeleteModel( + name='ProblemZadany', + ), + migrations.RemoveField( + model_name='cislo', + name='faze', + ), + migrations.RemoveField( + model_name='konfera', + name='popis', + ), + migrations.RemoveField( + model_name='konfera', + name='prispevek', + ), + migrations.RemoveField( + model_name='problem', + name='import_dakos_id', + ), + migrations.RemoveField( + model_name='resitel', + name='import_mamoper_id', + ), + migrations.RemoveField( + model_name='skola', + name='import_dakos_id', + ), + migrations.DeleteModel( + name='Prispevek', + ), + + # migr 0056 + migrations.RunPython( + generuj_RocnikNody_a_CisloNody, + reverse_code=migrations.RunPython.noop, + ), + + # migr 0057 + migrations.RunPython( + reseni_to_Reseni, + reverse_code=migrations.RunPython.noop, + ), + + # migr 0058 + migrations.RunPython( + uloha_to_Uloha, + reverse_code=migrations.RunPython.noop, + ), + migrations.RunPython( + tema_to_Tema, + reverse_code=migrations.RunPython.noop, + ), + migrations.RunPython( + clanek_to_Clanek, + reverse_code=migrations.RunPython.noop, + ), + migrations.RunPython( + konfery_rucne, + reverse_code=migrations.RunPython.noop, + ), + + # migr "fix 0058" + migrations.RunSQL( + "update seminar_problemy set typ = 'uloha' where typ like 'b_uloha_';", + "update seminar_problemy set typ = 'uloha' where typ like 'b_uloha_';" + ), + + # migr 0059 + migrations.RunPython( + vytvor_pohadkanode, + reverse_code=migrations.RunPython.noop, + ), + + # migr 0060 + migrations.RunPython( + pokacej_les, + reverse_code=migrations.RunPython.noop, + ), + + migrations.RemoveField( + model_name='novinky', + name='autor_old', + ), + migrations.RemoveField( + model_name='organizator', + name='foto', + ), + migrations.RemoveField( + model_name='organizator', + name='organizuje_do_roku', + ), + migrations.RemoveField( + model_name='organizator', + name='organizuje_od_roku', + ), + migrations.RemoveField( + model_name='organizator', + name='prezdivka', + ), + migrations.RemoveField( + model_name='organizator', + name='user', + ), + migrations.RemoveField( + model_name='pohadka', + name='autor_old', + ), + migrations.RemoveField( + model_name='pohadka', + name='uloha_old', + ), + migrations.RemoveField( + model_name='problem', + name='autor_old', + ), + migrations.RemoveField( + model_name='problem', + name='body', + ), + migrations.RemoveField( + model_name='problem', + name='cislo_reseni_old', + ), + migrations.RemoveField( + model_name='problem', + name='cislo_zadani_old', + ), + migrations.RemoveField( + model_name='problem', + name='opravovatel', + ), + migrations.RemoveField( + model_name='problem', + name='text_reseni', + ), + migrations.RemoveField( + model_name='problem', + name='text_zadani', + ), + migrations.RemoveField( + model_name='problem', + name='typ', + ), + migrations.RemoveField( + model_name='reseni', + name='body', + ), + migrations.RemoveField( + model_name='reseni', + name='cislo_body', + ), + migrations.RemoveField( + model_name='reseni', + name='problem_old', + ), + migrations.RemoveField( + model_name='reseni', + name='resitel', + ), + migrations.RemoveField( + model_name='resitel', + name='datum_narozeni', + ), + migrations.RemoveField( + model_name='resitel', + name='datum_prihlaseni', + ), + migrations.RemoveField( + model_name='resitel', + name='datum_souhlasu_udaje', + ), + migrations.RemoveField( + model_name='resitel', + name='datum_souhlasu_zasilani', + ), + migrations.RemoveField( + model_name='resitel', + name='email', + ), + migrations.RemoveField( + model_name='resitel', + name='jmeno', + ), + migrations.RemoveField( + model_name='resitel', + name='mesto', + ), + migrations.RemoveField( + model_name='resitel', + name='pohlavi_muz', + ), + migrations.RemoveField( + model_name='resitel', + name='prijmeni', + ), + migrations.RemoveField( + model_name='resitel', + name='psc', + ), + migrations.RemoveField( + model_name='resitel', + name='stat', + ), + migrations.RemoveField( + model_name='resitel', + name='telefon', + ), + migrations.RemoveField( + model_name='resitel', + name='ulice', + ), + migrations.RemoveField( + model_name='resitel', + name='user', + ), + migrations.AlterModelOptions( + name='pohadka', + options={'ordering': ['vytvoreno'], 'verbose_name': 'Pohádka', 'verbose_name_plural': 'Pohádky'}, + ), + migrations.RemoveField( + model_name='pohadka', + name='pred', + ), + migrations.RemoveField( + model_name='pohadka', + name='text', + ), + migrations.RemoveField( + model_name='pohadka', + name='uloha', + ), + migrations.AlterField( + model_name='cislo', + name='verejna_vysledkovka', + field=models.BooleanField(default=False, help_text='Je-li false u veřejného čísla, není výsledkovka zatím veřejná.', verbose_name='zveřejněna výsledkovka'), + ), + migrations.AlterField( + model_name='prijemce', + name='osoba', + field=models.OneToOneField(help_text='Které osobě či na jakou adresu se mají zasílat čísla', on_delete=django.db.models.deletion.CASCADE, to='seminar.Osoba', verbose_name='komu'), + ), + migrations.AlterField( + model_name='reseni', + name='cas_doruceni', + field=models.DateTimeField(blank=True, default=django.utils.timezone.now, verbose_name='čas_doručení'), + ), + migrations.AlterField( + model_name='cislo', + name='rocnik', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='cisla', to='seminar.Rocnik', verbose_name='ročník'), + ), + migrations.AlterField( + model_name='clanek', + name='cislo', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Cislo', verbose_name='číslo'), + ), + migrations.AlterField( + model_name='hodnoceni', + name='cislo_body', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='hodnoceni', to='seminar.Cislo', verbose_name='číslo pro body', null=True), + ), + migrations.AlterField( + model_name='hodnoceni', + name='problem', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Problem', verbose_name='problém'), + ), + migrations.AlterField( + model_name='konfery_ucastnici', + name='konfera', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Konfera', verbose_name='konfera'), + ), + migrations.AlterField( + model_name='konfery_ucastnici', + name='resitel', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Resitel', verbose_name='řešitel'), + ), + migrations.AlterField( + model_name='nastaveni', + name='aktualni_cislo', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Cislo', verbose_name='poslední vydané číslo'), + ), + migrations.AlterField( + model_name='nastaveni', + name='aktualni_rocnik', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Rocnik', verbose_name='aktuální ročník'), + ), + migrations.AlterField( + model_name='novinky', + name='autor', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Organizator', verbose_name='Autor novinky'), + ), + migrations.AlterField( + model_name='organizator', + name='osoba', + field=models.OneToOneField(help_text='osobní údaje organizátora', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='org', to='seminar.Osoba', verbose_name='osoba'), + ), + migrations.AlterField( + model_name='osoba', + name='user', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL, verbose_name='uživatel'), + ), + migrations.AlterField( + model_name='pohadka', + name='autor', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Organizator', verbose_name='Autor pohádky'), + ), + migrations.AlterField( + model_name='problem', + name='autor', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='autor_problemu_problem', to='seminar.Organizator', verbose_name='autor problému'), + ), + migrations.AlterField( + model_name='problem', + name='garant', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='garant_problemu_problem', to='seminar.Organizator', verbose_name='garant zadaného problému'), + ), + migrations.AlterField( + model_name='problem', + name='nadproblem', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='nadproblem_problem', to='seminar.Problem', verbose_name='nadřazený problém'), + ), + migrations.AlterField( + model_name='reseni', + name='text_cely', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='reseni_cely_set', to='seminar.Text', verbose_name='Plná verze textu řešení'), + ), + migrations.AlterField( + model_name='reseni_resitele', + name='resitele', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Resitel', verbose_name='řešitel'), + ), + migrations.AlterField( + model_name='resitel', + name='osoba', + field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Osoba', verbose_name='osoba'), + ), + migrations.AlterField( + model_name='resitel', + name='skola', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Skola', verbose_name='škola'), + ), + migrations.AlterField( + model_name='skola', + name='kontaktni_osoba', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Osoba', verbose_name='Kontaktní osoba'), + ), + migrations.AlterField( + model_name='soustredeni', + name='rocnik', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='soustredeni', to='seminar.Rocnik', verbose_name='ročník'), + ), + migrations.AlterField( + model_name='soustredeni_organizatori', + name='organizator', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Organizator', verbose_name='organizátor'), + ), + migrations.AlterField( + model_name='soustredeni_organizatori', + name='soustredeni', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Soustredeni', verbose_name='soustředění'), + ), + migrations.AlterField( + model_name='soustredeni_ucastnici', + name='resitel', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Resitel', verbose_name='řešitel'), + ), + migrations.AlterField( + model_name='soustredeni_ucastnici', + name='soustredeni', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Soustredeni', verbose_name='soustředění'), + ), + migrations.AlterField( + model_name='tema', + name='rocnik', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Rocnik', verbose_name='ročník'), + ), + migrations.AlterField( + model_name='uloha', + name='cislo_deadline', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='deadlinove_ulohy', to='seminar.Cislo', verbose_name='číslo deadlinu'), + ), + migrations.AlterField( + model_name='uloha', + name='cislo_reseni', + field=models.ForeignKey(blank=True, help_text='Číslo s řešením úlohy, jen pro úlohy', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='resene_ulohy', to='seminar.Cislo', verbose_name='číslo řešení'), + ), + migrations.AlterField( + model_name='uloha', + name='cislo_zadani', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='zadane_ulohy', to='seminar.Cislo', verbose_name='číslo zadání'), + ), + migrations.AddField( + model_name='treenode', + name='polymorphic_ctype', + field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_seminar.treenode_set+', to='contenttypes.ContentType'), + ), + migrations.RunPython( + vyrob_treenodum_ctypes, + reverse_code=migrations.RunPython.noop, + ), + migrations.AddField( + model_name='problem', + name='polymorphic_ctype', + field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_seminar.problem_set+', to='contenttypes.ContentType'), + ), + migrations.RunPython( + vyrob_problemum_ctypes, + reverse_code=migrations.RunPython.noop, + ), + migrations.AlterField( + model_name='konfera', + name='nazev', + field=models.CharField(help_text='Název konfery', max_length=100, verbose_name='název konfery'), + ), + ] diff --git a/seminar/migrations/0005_alter_problem_autor.py b/seminar/migrations/0005_alter_problem_autor.py index 264e9848..d8a40585 100644 --- a/seminar/migrations/0005_alter_problem_autor.py +++ b/seminar/migrations/0005_alter_problem_autor.py @@ -15,7 +15,7 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='problem', name='autor', - field=models.ForeignKey(related_name='autor_uloh', verbose_name='autor probl\xe9mu', blank=True, to=settings.AUTH_USER_MODEL, null=True), + field=models.ForeignKey(related_name='autor_uloh', verbose_name='autor probl\xe9mu', blank=True, to=settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE), preserve_default=True, ), ] diff --git a/seminar/migrations/0013_soustredeni_ucastnici_through_model.py b/seminar/migrations/0013_soustredeni_ucastnici_through_model.py index 37027c2d..c725691d 100644 --- a/seminar/migrations/0013_soustredeni_ucastnici_through_model.py +++ b/seminar/migrations/0013_soustredeni_ucastnici_through_model.py @@ -16,8 +16,8 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(serialize=False, primary_key=True)), ('poznamka', models.CharField(default=b'', help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \xfa\u010dasti (plain text)', max_length=64, verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True)), - ('resitel', models.ForeignKey(verbose_name='\u0159e\u0161itel', to='seminar.Resitel')), - ('soustredeni', models.ForeignKey(verbose_name='soust\u0159ed\u011bn\xed', to='seminar.Soustredeni')), + ('resitel', models.ForeignKey(verbose_name='\u0159e\u0161itel', to='seminar.Resitel', on_delete=models.CASCADE)), + ('soustredeni', models.ForeignKey(verbose_name='soust\u0159ed\u011bn\xed', to='seminar.Soustredeni',on_delete=models.CASCADE)), ], options={ 'ordering': ['soustredeni', 'resitel'], diff --git a/seminar/migrations/0019_rocnik_ciselne.py b/seminar/migrations/0019_rocnik_ciselne.py index 42308b2f..da9591aa 100644 --- a/seminar/migrations/0019_rocnik_ciselne.py +++ b/seminar/migrations/0019_rocnik_ciselne.py @@ -18,7 +18,8 @@ class Migration(migrations.Migration): preserve_default=False, ), migrations.RunSQL( - sql="update seminar_rocniky set rocnik_n = cast (rocnik as integer)" + sql="update seminar_rocniky set rocnik_n = cast (rocnik as integer)", + reverse_sql='update seminar_rocniky set rocnik_n = cast (rocnik as nvarchar(16))', ), migrations.RemoveField( model_name='rocnik', diff --git a/seminar/migrations/0023_add_novinky.py b/seminar/migrations/0023_add_novinky.py index 3babdc2d..7db2a005 100644 --- a/seminar/migrations/0023_add_novinky.py +++ b/seminar/migrations/0023_add_novinky.py @@ -20,8 +20,8 @@ class Migration(migrations.Migration): ('datum', models.DateField(auto_now_add=True)), ('text', models.TextField(null=True, verbose_name=b'Text novinky', blank=True)), ('obrazek', models.ImageField(upload_to=b'image_novinky/%Y/%m/%d/', null=True, verbose_name=b'Obr\xc3\xa1zek', blank=True)), - ('zverejneno', models.BooleanField(default=b'False', verbose_name=b'Zve\xc5\x99ejn\xc4\x9bno')), - ('autor', models.ForeignKey(verbose_name=b'Autor novinky', to=settings.AUTH_USER_MODEL)), + ('zverejneno', models.BooleanField(default=False, verbose_name=b'Zve\xc5\x99ejn\xc4\x9bno')), + ('autor', models.ForeignKey(verbose_name=b'Autor novinky', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)) ], options={ 'verbose_name': 'Novinka', diff --git a/seminar/migrations/0024_add_organizator.py b/seminar/migrations/0024_add_organizator.py index f9bf2cb8..16faee72 100644 --- a/seminar/migrations/0024_add_organizator.py +++ b/seminar/migrations/0024_add_organizator.py @@ -24,7 +24,7 @@ class Migration(migrations.Migration): ('strucny_popis_organizatora', models.TextField(null=True, verbose_name=b'Stru\xc4\x8dn\xc3\xbd popis organiz\xc3\xa1tora', blank=True)), ('foto', models.ImageField(help_text=b'Vlo\xc5\xbe fotografii organiz\xc3\xa1tora o libovon\xc3\xa9 velikosti', upload_to=b'image_organizatori/%Y/', null=True, verbose_name=b'Fotografie organiz\xc3\xa1tora', blank=True)), ('foto_male', models.ImageField(upload_to=b'image_organizatori/male/%Y/', null=True, editable=False, blank=True)), - ('user', models.OneToOneField(verbose_name=b'Osoba', to=settings.AUTH_USER_MODEL, help_text=b'Vyber \xc3\xba\xc4\x8det sp\xc5\x99a\xc5\xbeen\xc3\xbd s organiz\xc3\xa1torem.')), + ('user', models.OneToOneField(verbose_name=b'Osoba', to=settings.AUTH_USER_MODEL, help_text=b'Vyber \xc3\xba\xc4\x8det sp\xc5\x99a\xc5\xbeen\xc3\xbd s organiz\xc3\xa1torem.',on_delete=models.CASCADE)), ], options={ 'verbose_name': 'Organiz\xe1tor', diff --git a/seminar/migrations/0027_export_flag_a_typ_akce.py b/seminar/migrations/0027_export_flag_a_typ_akce.py index 254657cb..e7172dcc 100644 --- a/seminar/migrations/0027_export_flag_a_typ_akce.py +++ b/seminar/migrations/0027_export_flag_a_typ_akce.py @@ -14,13 +14,13 @@ class Migration(migrations.Migration): migrations.AddField( model_name='rocnik', name='exportovat', - field=models.BooleanField(default=False, help_text='Exportuje se jen podle tohoto flagu (ne ve\u0159ejnosti), a to jen \u010d\xedsla s ve\u0159ejnou v\xfdsledkovkou', verbose_name='export do AESOPa', db_column=b'exportovat'), + field=models.BooleanField(default=False, help_text='Exportuje se jen podle tohoto flagu (ne ve\u0159ejnosti), a to jen \u010d\xedsla s ve\u0159ejnou v\xfdsledkovkou', verbose_name='export do AESOPa', db_column='exportovat'), preserve_default=True, ), migrations.AddField( model_name='soustredeni', name='exportovat', - field=models.BooleanField(default=False, help_text='Exportuje se jen podle tohoto flagu (ne ve\u0159ejnosti)', verbose_name='export do AESOPa', db_column=b'exportovat'), + field=models.BooleanField(default=False, help_text='Exportuje se jen podle tohoto flagu (ne ve\u0159ejnosti)', verbose_name='export do AESOPa', db_column='exportovat'), preserve_default=True, ), migrations.AlterField( diff --git a/seminar/migrations/0036_add_org_to_soustredeni.py b/seminar/migrations/0036_add_org_to_soustredeni.py index cd6a2aed..4db43239 100644 --- a/seminar/migrations/0036_add_org_to_soustredeni.py +++ b/seminar/migrations/0036_add_org_to_soustredeni.py @@ -16,8 +16,8 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(serialize=False, primary_key=True)), ('poznamka', models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \xfa\u010dasti organiz\xe1tora (plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True)), - ('organizator', models.ForeignKey(verbose_name='organiz\xe1tor', to='seminar.Organizator')), - ('soustredeni', models.ForeignKey(verbose_name='soust\u0159ed\u011bn\xed', to='seminar.Soustredeni')), + ('organizator', models.ForeignKey(verbose_name='organiz\xe1tor', to='seminar.Organizator', on_delete=models.CASCADE)), + ('soustredeni', models.ForeignKey(verbose_name='soust\u0159ed\u011bn\xed', to='seminar.Soustredeni', on_delete=models.CASCADE)), ], options={ 'ordering': ['soustredeni', 'organizator'], diff --git a/seminar/migrations/0037_prispevek.py b/seminar/migrations/0037_prispevek.py index fd3df05a..c4c3b867 100644 --- a/seminar/migrations/0037_prispevek.py +++ b/seminar/migrations/0037_prispevek.py @@ -19,8 +19,8 @@ class Migration(migrations.Migration): ('text_org', models.TextField(null=True, verbose_name=b'Orgovsk\xc3\xbd text', blank=True)), ('text_resitel', models.TextField(null=True, verbose_name=b'\xc5\x98e\xc5\xa1itelsk\xc3\xbd text', blank=True)), ('zverejnit', models.BooleanField(verbose_name=b'Zve\xc5\x99ejnit?')), - ('problem', models.ForeignKey(verbose_name=b'Probl\xc3\xa9m', to='seminar.Problem')), - ('reseni', models.OneToOneField(null=True, blank=True, to='seminar.Reseni', verbose_name=b'\xc5\x98e\xc5\xa1en\xc3\xad')), + ('problem', models.ForeignKey(verbose_name=b'Probl\xc3\xa9m', to='seminar.Problem', on_delete=models.CASCADE)), + ('reseni', models.OneToOneField(null=True, blank=True, to='seminar.Reseni', verbose_name=b'\xc5\x98e\xc5\xa1en\xc3\xad', on_delete=models.CASCADE)), ], options={ 'abstract': False, diff --git a/seminar/migrations/0039_pohadka.py b/seminar/migrations/0039_pohadka.py index 800be0e8..f798bd75 100644 --- a/seminar/migrations/0039_pohadka.py +++ b/seminar/migrations/0039_pohadka.py @@ -21,8 +21,8 @@ class Migration(migrations.Migration): ('text', models.TextField(verbose_name='Text poh\xe1dky')), ('pred', models.BooleanField(default=True, verbose_name='P\u0159ed \xfalohou')), ('timestamp', models.DateTimeField(default=django.utils.timezone.now, verbose_name='Vytvo\u0159eno', editable=False, blank=True)), - ('autor', models.ForeignKey(verbose_name=b'Autor poh\xc3\xa1dky', to=settings.AUTH_USER_MODEL)), - ('uloha', models.ForeignKey(related_name='pohadky', verbose_name='\xdaloha', to='seminar.Problem')), + ('autor', models.ForeignKey(verbose_name=b'Autor poh\xc3\xa1dky', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), + ('uloha', models.ForeignKey(related_name='pohadky', verbose_name='\xdaloha', to='seminar.Problem',on_delete=models.CASCADE)), ], options={ 'ordering': ['uloha__cislo_zadani', 'uloha__kod', '-pred'], diff --git a/seminar/migrations/0040_pohadka_nepovinny_autor.py b/seminar/migrations/0040_pohadka_nepovinny_autor.py index 092cb578..babf9b24 100644 --- a/seminar/migrations/0040_pohadka_nepovinny_autor.py +++ b/seminar/migrations/0040_pohadka_nepovinny_autor.py @@ -15,6 +15,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='pohadka', name='autor', - field=models.ForeignKey(verbose_name=b'Autor poh\xc3\xa1dky', to=settings.AUTH_USER_MODEL, null=True), + field=models.ForeignKey(verbose_name=b'Autor poh\xc3\xa1dky', to=settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE), ), ] diff --git a/seminar/migrations/0041_konfery.py b/seminar/migrations/0041_konfery.py index e0adaa2d..9fddbe17 100644 --- a/seminar/migrations/0041_konfery.py +++ b/seminar/migrations/0041_konfery.py @@ -37,8 +37,9 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(serialize=False, primary_key=True)), ('poznamka', models.TextField(help_text='Neve\u0159ejn\xe1 pozn\xe1mka k \xfa\u010dasti (plain text)', verbose_name='neve\u0159ejn\xe1 pozn\xe1mka', blank=True)), - ('konfera', models.ForeignKey(verbose_name='konfera', to='seminar.Konfera')), - ('resitel', models.ForeignKey(verbose_name='\u0159e\u0161itel', to='seminar.Resitel')), + ('konfera', models.ForeignKey(verbose_name='konfera', to='seminar.Konfera', + on_delete=models.PROTECT)), + ('resitel', models.ForeignKey(verbose_name='\u0159e\u0161itel', to='seminar.Resitel',on_delete=models.CASCADE)), ], options={ 'ordering': ['konfera', 'resitel'], diff --git a/seminar/migrations/0049_auto_20190430_2354.py b/seminar/migrations/0049_auto_20190430_2354.py new file mode 100644 index 00000000..14fa23d8 --- /dev/null +++ b/seminar/migrations/0049_auto_20190430_2354.py @@ -0,0 +1,503 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-04-30 21:54 +from __future__ import unicode_literals + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone +import django_countries.fields +import imagekit.models.fields +import taggit.managers + + +class Migration(migrations.Migration): + atomic = False + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('seminar', '0048_add_cislo_datum_deadline_soustredeni'), + ] + + operations = [ + migrations.CreateModel( + name='Clanek', + fields=[ + ('problem_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.Problem')), + ], + options={ + 'verbose_name': 'Článek', + 'verbose_name_plural': 'Články', + 'db_table': 'seminar_clanky', + }, + bases=('seminar.problem',), + ), + migrations.CreateModel( + name='Hodnoceni', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('body', models.DecimalField(decimal_places=1, max_digits=8, verbose_name='body')), + ], + options={ + 'verbose_name': 'Hodnocení', + 'verbose_name_plural': 'Hodnocení', + 'db_table': 'seminar_hodnoceni', + }, + ), + migrations.CreateModel( + name='Obrazek', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('na_web', models.ImageField(blank=True, null=True, upload_to='obrazky/%Y/%m/%d/', verbose_name='obrázek na web')), + ('do_cisla_barevny', models.FileField(blank=True, help_text='Barevná verze obrázku do čísla', null=True, upload_to='obrazky/%Y/%m/%d/', verbose_name='barevný obrázek do čísla')), + ('do_cisla_cernobily', models.FileField(blank=True, help_text='Černobílá verze obrázku do čísla', null=True, upload_to='obrazky/%Y/%m/%d/', verbose_name='černobílý obrázek do čísla')), + ], + options={ + 'verbose_name': 'obrázek', + 'verbose_name_plural': 'obrázky', + 'db_table': 'seminar_obrazky', + }, + ), + migrations.CreateModel( + name='Osoba', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('jmeno', models.CharField(max_length=256, verbose_name='jméno')), + ('prijmeni', models.CharField(max_length=256, verbose_name='příjmení')), + ('prezdivka', models.CharField(max_length=256, verbose_name='přezdívka', blank=True, null=False)), + ('pohlavi_muz', models.BooleanField(default=False, verbose_name='pohlaví (muž)')), + ('email', models.EmailField(blank=True, default='', max_length=256, verbose_name='e-mail')), + ('telefon', models.CharField(blank=True, default='', max_length=256, verbose_name='telefon')), + ('datum_narozeni', models.DateField(blank=True, null=True, verbose_name='datum narození')), + ('datum_souhlasu_udaje', models.DateField(blank=True, help_text='Datum souhlasu se zpracováním osobních údajů', null=True, verbose_name='datum souhlasu (údaje)')), + ('datum_souhlasu_zasilani', models.DateField(blank=True, help_text='Datum souhlasu se zasíláním MFF materiálů', null=True, verbose_name='datum souhlasu (spam)')), + ('datum_registrace', models.DateField(default=django.utils.timezone.now, verbose_name='datum registrace do semináře')), + ('ulice', models.CharField(blank=True, default='', max_length=256, verbose_name='ulice')), + ('mesto', models.CharField(blank=True, default='', max_length=256, verbose_name='město')), + ('psc', models.CharField(blank=True, default='', max_length=32, verbose_name='PSČ')), + ('stat', django_countries.fields.CountryField(default='CZ', help_text='ISO 3166-1 kód země velkými písmeny (CZ, SK, ...)', max_length=2, verbose_name='stát')), + ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k osobě (plain text)', verbose_name='neveřejná poznámka')), + ('foto', imagekit.models.fields.ProcessedImageField(blank=True, help_text='Vlož fotografii osoby o libovolné velikosti', null=True, upload_to='image_osoby/velke/%Y/', verbose_name='Fotografie osoby')), + ('user', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='uživatel')), + ], + options={ + 'verbose_name': 'Osoba', + 'verbose_name_plural': 'Osoby', + 'db_table': 'seminar_osoby', + 'ordering': ['prijmeni', 'jmeno'], + }, + ), + migrations.CreateModel( + name='Prijemce', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k příemci čísel (plain text)', verbose_name='neveřejná poznámka')), + ('osoba', models.ForeignKey(help_text='Které osobě či na jakou adresu se mají zasílat čísla', on_delete=django.db.models.deletion.CASCADE, to='seminar.Osoba', verbose_name='komu')), + ], + options={ + 'verbose_name': 'příjemce', + 'verbose_name_plural': 'příjemce', + 'db_table': 'seminar_prijemce', + }, + ), + migrations.CreateModel( + name='Reseni_Resitele', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ], + options={ + 'verbose_name': 'Řešení řešitelů', + 'verbose_name_plural': 'Řešení řešitelů', + 'db_table': 'seminar_reseni_resitele', + 'ordering': ['reseni', 'resitele'], + }, + ), + migrations.CreateModel( + name='Tema', + fields=[ + ('problem_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.Problem')), + ('tema_typ', models.CharField(choices=[('tema', 'Téma'), ('serial', 'Seriál')], default='tema', max_length=16, verbose_name='Typ tématu')), + ], + options={ + 'verbose_name': 'Téma', + 'verbose_name_plural': 'Témata', + 'db_table': 'seminar_temata', + }, + bases=('seminar.problem',), + ), + migrations.CreateModel( + name='Text', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('na_web', models.TextField(blank=True, help_text='Text ke zveřejnění na webu', verbose_name='text na web')), + ('do_cisla', models.TextField(blank=True, help_text='Text ke zveřejnění v čísle', verbose_name='text do čísla')), + ], + options={ + 'verbose_name': 'text', + 'verbose_name_plural': 'texty', + 'db_table': 'seminar_texty', + }, + ), + migrations.CreateModel( + name='Uloha', + fields=[ + ('problem_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.Problem')), + ('max_body', models.DecimalField(blank=True, decimal_places=1, max_digits=8, null=True, verbose_name='maximum bodů')), + ], + options={ + 'verbose_name': 'Úloha', + 'verbose_name_plural': 'Úlohy', + 'db_table': 'seminar_ulohy', + }, + bases=('seminar.problem',), + ), + migrations.AlterModelOptions( + name='novinky', + options={'ordering': ['-datum'], 'verbose_name': 'Novinka', 'verbose_name_plural': 'Novinky'}, + ), + migrations.AlterModelOptions( + name='prilohareseni', + options={'ordering': ['reseni', 'vytvoreno'], 'verbose_name': 'Příloha řešení', 'verbose_name_plural': 'Přílohy řešení'}, + ), + migrations.AlterModelOptions( + name='reseni', + options={'ordering': ['-cas_doruceni'], 'verbose_name': 'Řešení', 'verbose_name_plural': 'Řešení'}, + ), + migrations.AlterModelOptions( + name='resitel', + options={'ordering': ['osoba'], 'verbose_name': 'Řešitel', 'verbose_name_plural': 'Řešitelé'}, + ), + migrations.RenameField( + model_name='konfera', + old_name='org_poznamka', + new_name='poznamka', + ), + migrations.RenameField( + model_name='pohadka', + old_name='timestamp', + new_name='vytvoreno', + ), + migrations.RenameField( + model_name='reseni', + old_name='timestamp', + new_name='cas_doruceni', + ), + migrations.RenameField( + model_name='prilohareseni', + old_name='timestamp', + new_name='vytvoreno', + ), + migrations.RenameField( + model_name='problem', + old_name='text_org', + new_name='poznamka', + ), + migrations.RenameField( + model_name='problem', + old_name='timestamp', + new_name='vytvoreno', + ), + migrations.RenameField( + model_name='problem', + old_name='cislo_zadani', + new_name='cislo_zadani_old', + ), + migrations.RenameField( + model_name='problem', + old_name='cislo_reseni', + new_name='cislo_reseni_old', + ), + migrations.AddField( + model_name='konfera', + name='anotace', + field=models.TextField(blank=True, help_text='Popis, o čem bude konfera.', verbose_name='anotace'), + ), + migrations.AddField( + model_name='konfera', + name='reseni', + field=models.ForeignKey(blank=True, help_text='Účastnický přípěvek o konfeře', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='konfery', to='seminar.Reseni', verbose_name='článek ke konfeře'), + ), + migrations.AddField( + model_name='organizator', + name='organizuje_do', + field=models.DateTimeField(blank=True, null=True, verbose_name='Organizuje do'), + ), + migrations.AddField( + model_name='organizator', + name='organizuje_od', + field=models.DateTimeField(null=True,blank=True, verbose_name='Organizuje od'), + ), + migrations.AddField( + model_name='organizator', + name='skola', + field=models.CharField(blank=True, help_text='Škola, např. MFF, VŠCHT, VUT, ... prostě aby se nemuselo psát do studuješkolu, ale jen obor, možnost zobrazit zvlášť', max_length=256, null=True, verbose_name='Škola, kterou studuje'), + ), + migrations.AddField( + model_name='organizator', + name='vytvoreno', + field=models.DateTimeField(blank=True, default=django.utils.timezone.now, editable=False, verbose_name='Vytvořeno'), + ), + migrations.AddField( + model_name='problem', + name='garant', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='garant_problemu_problem', to='seminar.Organizator', verbose_name='garant zadaného problému'), + ), + migrations.AddField( + model_name='problem', + name='nadproblem', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='nadproblem_problem', to='seminar.Problem', verbose_name='nadřazený problém'), + ), + migrations.AddField( + model_name='problem', + name='opravovatele', + field=models.ManyToManyField(blank=True, related_name='opravovatele_problem', to='seminar.Organizator', verbose_name='opravovatelé'), + ), + migrations.AddField( + model_name='reseni', + name='zverejneno', + field=models.BooleanField(default=False, help_text='Udává, zda je řešení zveřejněno', verbose_name='řešení zveřejněno'), + ), + migrations.AlterField( + model_name='cislo', + name='verejna_vysledkovka', + field=models.BooleanField(default=False, help_text='Je-li false u veřejného čísla,\t\t\t\t není výsledkovka zatím veřejná.', verbose_name='zveřejněna výsledkovka'), + ), + migrations.AlterField( + model_name='cislo', + name='verejne_db', + field=models.BooleanField(db_column='verejne', default=False, verbose_name='číslo zveřejněno'), + ), + migrations.AlterField( + model_name='konfera', + name='typ_prezentace', + field=models.CharField(choices=[('veletrh', 'Veletrh (postery)'), ('prezentace', 'Prezentace (přednáška)')], default='veletrh', max_length=16, verbose_name='typ prezentace'), + ), + migrations.RenameField( + model_name='novinky', + old_name='autor', + new_name='autor_old' + ), + migrations.AddField( + model_name='novinky', + name='autor', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Organizator', verbose_name='Autor novinky', null=True), + ), + migrations.AlterField( + model_name='novinky', + name='obrazek', + field=models.ImageField(blank=True, null=True, upload_to='image_novinky/%Y/%m/%d/', verbose_name='Obrázek'), + ), + migrations.AlterField( + model_name='novinky', + name='text', + field=models.TextField(blank=True, null=True, verbose_name='Text novinky'), + ), + migrations.AlterField( + model_name='novinky', + name='zverejneno', + field=models.BooleanField(default=False, verbose_name='Zveřejněno'), + ), + migrations.AlterField( + model_name='organizator', + name='strucny_popis_organizatora', + field=models.TextField(blank=True, null=True, verbose_name='Stručný popis organizátora'), + ), + migrations.AlterField( + model_name='organizator', + name='studuje', + field=models.CharField(blank=True, help_text="Např. 'Studuje Obecnou fyziku (Bc.), 3. ročník', 'Vystudovala Diskrétní modely a algoritmy (Mgr.)' nebo 'Přednáší na MFF'", max_length=256, null=True, verbose_name='Studium aj.'), + ), + migrations.RenameField( + model_name='pohadka', + old_name='autor', + new_name='autor_old' + ), + migrations.AddField( + model_name='pohadka', + name='autor', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Organizator', verbose_name='Autor pohádky'), + ), + migrations.RenameField( + model_name='pohadka', + old_name='uloha', + new_name='uloha_old' + ), + migrations.AddField( + model_name='pohadka', + name='uloha', + field=models.ForeignKey(null=True,on_delete=django.db.models.deletion.CASCADE, related_name='pohadky', to='seminar.Uloha', verbose_name='Úloha'), + ), + migrations.RenameField( + model_name='problem', + old_name='autor', + new_name='autor_old', + ), + migrations.AddField( + model_name='problem', + name='autor', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='autor_problemu_problem', to='seminar.Organizator', verbose_name='autor problému'), + ), + migrations.AlterField( + model_name='problem', + name='kod', + field=models.CharField(blank=True, default='', help_text='Číslo/kód úlohy v čísle nebo kód tématu/článku/seriálu v ročníku', max_length=32, verbose_name='lokální kód'), + ), + migrations.AlterField( + model_name='problem', + name='stav', + field=models.CharField(choices=[('navrh', 'Návrh'), ('zadany', 'Zadaný'), ('vyreseny', 'Vyřešený'), ('smazany', 'Smazaný')], default='navrh', max_length=32, verbose_name='stav problému'), + ), + migrations.AlterField( + model_name='problem', + name='zamereni', + field=taggit.managers.TaggableManager(blank=True, help_text='Zaměření M/F/I/O problému, příp. další tagy', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='zaměření'), + ), + migrations.AlterField( + model_name='reseni', + name='forma', + field=models.CharField(choices=[('papir', 'Papírové řešení'), ('email', 'Emailem'), ('upload', 'Upload přes web')], default='email', max_length=16, verbose_name='forma řešení'), + ), + migrations.RenameField( + model_name='reseni', + old_name='problem', + new_name='problem_old', + ), + migrations.AlterField( + model_name='resitel', + name='zasilat', + field=models.CharField(choices=[('domu', 'Domů'), ('do_skoly', 'Do školy'), ('nikam', 'Nikam')], default='domu', max_length=32, verbose_name='kam zasílat'), + ), + migrations.AlterField( + model_name='rocnik', + name='exportovat', + field=models.BooleanField(db_column='exportovat', default=False, help_text='Exportuje se jen podle tohoto flagu (ne veřejnosti), a to jen čísla s veřejnou výsledkovkou', verbose_name='export do AESOPa'), + ), + migrations.AlterField( + model_name='skola', + name='aesop_id', + field=models.CharField(blank=True, default='', help_text='Aesopi ID typu "izo:..." nebo "aesop:..."', max_length=32, verbose_name='Aesop ID'), + ), + migrations.AlterField( + model_name='skola', + name='kratky_nazev', + field=models.CharField(blank=True, help_text='Zkrácený název pro zobrazení ve výsledkovce', max_length=256, verbose_name='zkrácený název'), + ), + migrations.AlterField( + model_name='skola', + name='stat', + field=django_countries.fields.CountryField(default='CZ', help_text='ISO 3166-1 kód země velkými písmeny (CZ, SK, ...)', max_length=2, verbose_name='stát'), + ), + migrations.AlterField( + model_name='soustredeni', + name='exportovat', + field=models.BooleanField(db_column='exportovat', default=False, help_text='Exportuje se jen podle tohoto flagu (ne veřejnosti)', verbose_name='export do AESOPa'), + ), + migrations.AlterField( + model_name='soustredeni', + name='misto', + field=models.CharField(blank=True, default='', help_text='Místo (název obce, volitelně též objektu', max_length=256, verbose_name='místo soustředění'), + ), + migrations.AlterField( + model_name='soustredeni', + name='text', + field=models.TextField(blank=True, default='', verbose_name='text k soustředění (HTML)'), + ), + migrations.AlterField( + model_name='soustredeni', + name='typ', + field=models.CharField(choices=[('jarni', 'Jarní soustředění'), ('podzimni', 'Podzimní soustředění'), ('vikend', 'Víkendový sraz')], default='podzimni', max_length=16, verbose_name='typ akce'), + ), + migrations.AlterField( + model_name='soustredeni', + name='verejne_db', + field=models.BooleanField(db_column='verejne', default=False, verbose_name='soustředění zveřejněno'), + ), + migrations.AlterModelTable( + name='problem', + table='seminar_problemy', + ), + migrations.AddField( + model_name='uloha', + name='cislo_deadline', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='deadlinove_ulohy', to='seminar.Cislo', verbose_name='číslo deadlinu'), + ), + migrations.AddField( + model_name='uloha', + name='cislo_reseni', + field=models.ForeignKey(blank=True, help_text='Číslo s řešením úlohy, jen pro úlohy', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='resene_ulohy', to='seminar.Cislo', verbose_name='číslo řešení'), + ), + migrations.AddField( + model_name='uloha', + name='cislo_zadani', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='zadane_ulohy', to='seminar.Cislo', verbose_name='číslo zadání'), + ), + migrations.AddField( + model_name='tema', + name='rocnik', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Rocnik', verbose_name='ročník'), + ), + migrations.AddField( + model_name='reseni_resitele', + name='reseni', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Reseni', verbose_name='řešení'), + ), + migrations.AddField( + model_name='reseni_resitele', + name='resitele', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Resitel', verbose_name='řešitel'), + ), + migrations.AddField( + model_name='obrazek', + name='text', + field=models.ForeignKey(help_text='text, ve kterém se obrázek vyskytuje', on_delete=django.db.models.deletion.CASCADE, to='seminar.Text', verbose_name='text'), + ), + migrations.AddField( + model_name='hodnoceni', + name='cislo_body', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='hodnoceni', to='seminar.Cislo', verbose_name='číslo pro body', null=True), + ), + migrations.AddField( + model_name='hodnoceni', + name='problem', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Problem', verbose_name='problém'), + ), + migrations.AddField( + model_name='hodnoceni', + name='reseni', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Reseni', verbose_name='řešení'), + ), + migrations.AddField( + model_name='clanek', + name='cislo', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Cislo', verbose_name='číslo'), + ), + migrations.AddField( + model_name='organizator', + name='osoba', + field=models.ForeignKey(help_text='osobní údaje organizátora', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='org', to='seminar.Osoba', verbose_name='osoba'), + ), + migrations.AddField( + model_name='reseni', + name='resitele', + field=models.ManyToManyField(help_text='Seznam autorů řešení', through='seminar.Reseni_Resitele', to='seminar.Resitel', verbose_name='autoři řešení'), + ), + migrations.AddField( + model_name='reseni', + name='text_zkraceny', + field=models.ManyToManyField(help_text='Seznam úryvků z řešení', related_name='reseni_zkraceny_set', to='seminar.Text', verbose_name='zkrácené verze řešení'), + ), + migrations.AddField( + model_name='resitel', + name='osoba', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Osoba', verbose_name='osoba'), + ), + migrations.AddField( + model_name='skola', + name='kontaktni_osoba', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Osoba', verbose_name='Kontaktní osoba'), + ), + migrations.AddField( + model_name='reseni', + name='problem', + field=models.ManyToManyField(help_text='Problém', through='seminar.Hodnoceni', to='seminar.Problem', verbose_name='problém'), + ), + ] diff --git a/seminar/migrations/0050_auto_20190510_2228.py b/seminar/migrations/0050_auto_20190510_2228.py new file mode 100644 index 00000000..a9afc764 --- /dev/null +++ b/seminar/migrations/0050_auto_20190510_2228.py @@ -0,0 +1,186 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-10 20:28 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0049_auto_20190430_2354'), + ] + + operations = [ + migrations.AlterField( + model_name='konfera', + name='reseni', + field=models.OneToOneField(blank=True, help_text='Účastnický přípěvek o konfeře', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='konfery', to='seminar.Reseni', verbose_name='článek ke konfeře'), + ), + migrations.AlterField( + model_name='organizator', + name='osoba', + field=models.OneToOneField(help_text='osobní údaje organizátora', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='org', to='seminar.Osoba', verbose_name='osoba'), + ), + migrations.AlterField( + model_name='resitel', + name='osoba', + field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to='seminar.Osoba', verbose_name='osoba'), + ), + migrations.CreateModel( + name='TreeNode', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ], + options={ + 'verbose_name': 'TreeNode', + 'verbose_name_plural': 'TreeNody', + 'db_table': 'seminar_nodes_treenode', + }, + ), + migrations.CreateModel( + name='CisloNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('cislo', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='seminar.Cislo', verbose_name='číslo')), + ], + options={ + 'verbose_name': 'Číslo (Node)', + 'verbose_name_plural': 'Čísla (Node)', + 'db_table': 'seminar_nodes_cislo', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='ClanekNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('clanek', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Clanek', verbose_name='článek')), + ], + options={ + 'verbose_name': 'Článek (Node)', + 'verbose_name_plural': 'Články (Node)', + 'db_table': 'seminar_nodes_clanek', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='KonferaNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('konfera', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Konfera', verbose_name='konfera')), + ], + options={ + 'verbose_name': 'Konfera (Node)', + 'verbose_name_plural': 'Konfery (Node)', + 'db_table': 'seminar_nodes_konfera', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='MezicisloNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ], + options={ + 'verbose_name': 'Mezičíslo (Node)', + 'verbose_name_plural': 'Mezičísla (Node)', + 'db_table': 'seminar_nodes_mezicislo', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='RocnikNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('rocnik', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='seminar.Rocnik', verbose_name='ročník')), + ], + options={ + 'verbose_name': 'Ročník (Node)', + 'verbose_name_plural': 'Ročníky (Node)', + 'db_table': 'seminar_nodes_rocnik', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='TemaVCisleNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('tema', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Tema', verbose_name='téma v čísle')), + ], + options={ + 'verbose_name': 'Téma v čísle (Node)', + 'verbose_name_plural': 'Témata v čísle (Node)', + 'db_table': 'seminar_nodes_temavcisle', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='TextNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('text', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Text', verbose_name='text')), + ], + options={ + 'verbose_name': 'Text (Node)', + 'verbose_name_plural': 'Text (Node)', + 'db_table': 'seminar_nodes_obsah', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='UlohaVzorakNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('uloha', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Uloha', verbose_name='úloha')), + ], + options={ + 'verbose_name': 'Vzorák úlohy (Node)', + 'verbose_name_plural': 'Vzoráky úloh (Node)', + 'db_table': 'seminar_nodes_uloha_vzorak', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='UlohaZadaniNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('uloha', models.OneToOneField(null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Uloha', verbose_name='úloha')), + ], + options={ + 'verbose_name': 'Zadání úlohy (Node)', + 'verbose_name_plural': 'Zadání úloh (Node)', + 'db_table': 'seminar_nodes_uloha_zadani', + }, + bases=('seminar.treenode',), + ), + migrations.CreateModel( + name='PohadkaNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('pohadka', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='seminar.Pohadka', verbose_name='pohádka')), + ], + options={ + 'verbose_name': 'Pohádka (Node)', + 'verbose_name_plural': 'Pohádky (Node)', + 'db_table': 'seminar_nodes_pohadka', + }, + bases=('seminar.treenode',), + ), + migrations.AddField( + model_name='treenode', + name='first_child', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.TreeNode', verbose_name='první potomek'), + ), + migrations.AddField( + model_name='treenode', + name='root', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='potomci_set', to='seminar.TreeNode', verbose_name='kořen stromu'), + ), + migrations.AddField( + model_name='treenode', + name='succ', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='prev', to='seminar.TreeNode', verbose_name='další element na stejné úrovni'), + ), + ] diff --git a/seminar/migrations/0051_resitel_to_osoba.py b/seminar/migrations/0051_resitel_to_osoba.py new file mode 100644 index 00000000..6644ab7d --- /dev/null +++ b/seminar/migrations/0051_resitel_to_osoba.py @@ -0,0 +1,89 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-10 20:44 +from __future__ import unicode_literals + +from django.db import migrations + +from datetime import date + +def resitel_to_osoba(apps,schema_editor): + Resitel = apps.get_model('seminar','Resitel') + Osoba = apps.get_model('seminar','Osoba') + for r in Resitel.objects.all(): + o = Osoba() + o.datum_narozeni = r.datum_narozeni + o.datum_registrace = r.datum_prihlaseni if r.datum_prihlaseni else date.max # Myslím si, že None by způsobilo použití defaultu + o.datum_souhlasu_udaje = r.datum_souhlasu_udaje + o.datum_souhlasu_zasilani = r.datum_souhlasu_zasilani + o.email = r.email + o.jmeno = r.jmeno + o.mesto = r.mesto + o.pohlavi_muz = r.pohlavi_muz + o.prijmeni = r.prijmeni + o.psc = r.psc + o.stat = r.stat + o.telefon = r.telefon + o.ulice = r.ulice + o.user = r.user + o.poznamka += f'\nWEB DEBUG: Osoba pro řešitele {r.id}' + if o.user: + u = o.user + if u.first_name: + if not o.jmeno: + o.jmeno = u.first_name + u.first_name += ' (Uživatel!)' + elif o.jmeno == u.first_name: + u.first_name += ' (Uživatel!)' + else: + raise ValueError('jmeno a first_name rozdílné: "{}" vs. "{}"'.format(o.jmeno, u.first_name)) + if u.last_name: + if not o.prijmeni: + o.prijmeni = u.last_name + u.last_name += ' (Uživatel!)' + elif o.prijmeni == u.last_name: + u.last_name += ' (Uživatel!)' + else: + raise ValueError('prijmeni a last_name rozdílné: "{}" vs. "{}"'.format(o.prijmeni, u.last_name)) + if u.email: + if not o.email: + o.email = u.email + elif o.email != u.email: + raise ValueError('o.email a u.email rozdílné: "{}" vs. "{}"'.format(o.email, u.email)) + u.save() + + + o.save() + r.osoba = o + r.save() + +def osoba_to_resitel(apps, schema_editor): + Resitel = apps.get_model('seminar','Resitel') + Osoba = apps.get_model('seminar','Osoba') + for r in Resitel.objects.all(): + o = r.osoba + r.datum_narozeni = o.datum_narozeni + r.datum_prihlaseni = o.datum_registrace + r.datum_souhlasu_udaje = o.datum_souhlasu_udaje + r.datum_souhlasu_zasilani = o.datum_souhlasu_zasilani + r.email = o.email + r.jmeno = o.jmeno + r.mesto = o.mesto + r.pohlavi_muz = o.pohlavi_muz + r.prijmeni = o.prijmeni + r.psc = o.psc + r.stat = o.stat + r.telefon = o.telefon + r.ulice = o.ulice + r.user = o.user + r.save() + o.delete() + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0066c_reseninode'), + ] + + operations = [ + migrations.RunPython(resitel_to_osoba, osoba_to_resitel), + ] diff --git a/seminar/migrations/0052_user_to_organizator.py b/seminar/migrations/0052_user_to_organizator.py new file mode 100644 index 00000000..a91a7966 --- /dev/null +++ b/seminar/migrations/0052_user_to_organizator.py @@ -0,0 +1,125 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.15 on 2019-05-16 20:59 +from __future__ import unicode_literals + +from django.db import migrations + +from datetime import date + +import logging + +logger = logging.getLogger(__name__) + +def spoj_k_organizatorum_osoby(apps, scema_editor): + Organizator = apps.get_model('seminar', 'Organizator') + Resitel = apps.get_model('seminar', 'Resitel') + Osoba = apps.get_model('seminar', 'Osoba') + for org in Organizator.objects.all(): + + # Spárování organizátora s osobou + # Myšlenka: Když najdeme řešitele pro daného uživatele, tak se vezme Osoba příslušná uživateli, + # Pokud nenajdeme uživatele, tak ještě zkusíme dohledat Osobu podle e-mailu + user = org.user + if user is None: + logger.error(f'Org {org} nemá uživatele!') + # Je to podezřelé, ale prostě vyrobíme novou osobu. + osoba = Osoba() + osoba.poznamka += f'\nWEB DEBUG: BUG: Osoba pro Orga {org.id} bez Uživatele' + # Téhle osobě nejdou nastavit detaily, protože žádné nemáme. + # Datum registrace budiž maximální + osoba.datum_registrace = date.max + else: + logger.info(f'Org {org.user.email}(ID: {org.id}) má uživatele {user}') + # 💢💢💢 Python nemá goto, ale prý má výjimky… 💢💢💢 + class EndException(Exception): pass + try: + # Hledáme podle uživatele + resitele = Resitel.objects.filter(user=user) + if resitele.count() != 0 and user is not None: + osoba = resitele.first().osoba + osoba.poznamka += f'\nWEB DEBUG: Osoba pro Orga {org.id} spárovaná podle Uživatele Řešitele' + logger.info(f'Našel jsem řešitele {resitele.first().email} podle uživatele, používám jeho Osobu') + raise EndException + + # Hledáme podle e-mailu + osoby = Osoba.objects.filter(email__iexact=user.email) + if osoby.count() != 0 and user.email != '': + osoba = osoby.first() + if osoba.user is None: + osoba.user = user + osoba.poznamka += f'\nWEB DEBUG: Osoba pro Orga {org.id} spárovaná podle e-mailu' + logger.info(f'Našel jsem Osobu {osoby.first().email} podle e-mailu') + raise EndException + + # Fallback + logger.warning(f'Org neměl řešitele, zakládám novou Osobu.') + osoba = Osoba(user=user) + osoba.poznamka += f'\nWEB DEBUG: Osoba pro Orga {org.id} vytvořena nová jen podle existence Uživatele' + + # Přesun informací z usera do osoby + # pro osoby z řešitelů (jediné dosud existující osoby) již v minule migraci + osoba.jmeno = user.first_name + osoba.prijmeni = user.last_name + osoba.email = user.email + user.first_name += " (Uživatel!)" + user.last_name += " (Uživatel!)" + osoba.datum_registrace = min(osoba.datum_registrace, user.date_joined, key=lambda d: d if d is not None else date.max) + user.save() + + except EndException: pass + + # Přesun informací z organizátora do jeho osoby + osoba.prezdivka = org.prezdivka if org.prezdivka is not None else '' + osoba.foto = org.foto + + # Všechno uložit + osoba.save() + org.osoba = osoba + org.save() + +def fix_problem(apps, schema_editor): + Problem = apps.get_model('seminar', 'Problem') + Organizator = apps.get_model('seminar', 'Organizator') + for pr in Problem.objects.all(): + if pr.autor_old is not None: + pr.autor = Organizator.objects.filter(osoba__user=pr.autor_old).first() + else: + pr.autor = None + if pr.opravovatel is not None: + if Organizator.objects.filter(osoba__user=pr.opravovatel).first() is not None: + pr.opravovatele.add(Organizator.objects.filter(osoba__user=pr.opravovatel).first()) + else: + logger.error(f'WTF, nespárovaný opravovatel {pr.opravovatel} problému {pr}') + pr.save() + +def fix_pohadka(apps, schema_editor): + Pohadka = apps.get_model('seminar', 'Pohadka') + Organizator = apps.get_model('seminar', 'Organizator') + for poh in Pohadka.objects.all(): + if poh.autor_old is not None: + poh.autor = Organizator.objects.filter(osoba__user=poh.autor_old).first() + else: + poh.autor = None + poh.save() + +def fix_novinka(apps, schema_editor): + Novinky = apps.get_model('seminar', 'Novinky') + Organizator = apps.get_model('seminar', 'Organizator') + for nov in Novinky.objects.all(): + nov.autor = Organizator.objects.filter(osoba__user=nov.autor_old).first() + nov.save() + + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0051_resitel_to_osoba'), + ] + + operations = [ + migrations.RunPython(spoj_k_organizatorum_osoby, migrations.RunPython.noop), + migrations.RunPython(fix_problem, migrations.RunPython.noop), + migrations.RunPython(fix_pohadka, migrations.RunPython.noop), + migrations.RunPython(fix_novinka, migrations.RunPython.noop), + ] diff --git a/seminar/migrations/0053_organizator_organizuje_od_do.py b/seminar/migrations/0053_organizator_organizuje_od_do.py new file mode 100644 index 00000000..b94e8032 --- /dev/null +++ b/seminar/migrations/0053_organizator_organizuje_od_do.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-16 21:26 +from __future__ import unicode_literals + +import datetime as dt +from django.db import migrations + +def rok_to_datetime(apps,schema_editor): + Organizator = apps.get_model('seminar','Organizator') + for o in Organizator.objects.all(): + rok = o.organizuje_od_roku + if rok: + o.organizuje_od = dt.datetime(rok,1,1) + rok = o.organizuje_do_roku + if rok: + o.organizuje_do = dt.datetime(rok,12,31) + o.save() + +def datetime_to_rok(apps,schema_editor): + Organizator = apps.get_model('seminar','Organizator') + for o in Organizator.objects.all(): + o.organizuje_od_roku = o.organizuje_od.year + o.organizuje_do_roku = o.organizuje_do.year + o.save() + + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0052_user_to_organizator'), + ] + + operations = [ + migrations.RunPython(rok_to_datetime, datetime_to_rok), + ] diff --git a/seminar/migrations/0055_smazat_nemigrovane_zastarale_veci.py b/seminar/migrations/0055_smazat_nemigrovane_zastarale_veci.py new file mode 100644 index 00000000..1b6f95f4 --- /dev/null +++ b/seminar/migrations/0055_smazat_nemigrovane_zastarale_veci.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-23 20:16 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0053_organizator_organizuje_od_do'), + ] + + operations = [ + migrations.RemoveField( + model_name='prispevek', + name='problem', + ), + migrations.RemoveField( + model_name='prispevek', + name='reseni', + ), + migrations.DeleteModel( + name='ProblemNavrh', + ), + migrations.DeleteModel( + name='ProblemZadany', + ), + migrations.RemoveField( + model_name='cislo', + name='faze', + ), + migrations.RemoveField( + model_name='konfera', + name='popis', + ), + migrations.RemoveField( + model_name='konfera', + name='prispevek', + ), + migrations.RemoveField( + model_name='problem', + name='import_dakos_id', + ), + migrations.RemoveField( + model_name='resitel', + name='import_mamoper_id', + ), + migrations.RemoveField( + model_name='skola', + name='import_dakos_id', + ), + migrations.DeleteModel( + name='Prispevek', + ), + ] diff --git a/seminar/migrations/0056_vrcholy_pro_rocniky_a_cisla.py b/seminar/migrations/0056_vrcholy_pro_rocniky_a_cisla.py new file mode 100644 index 00000000..56146261 --- /dev/null +++ b/seminar/migrations/0056_vrcholy_pro_rocniky_a_cisla.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-23 21:54 +from __future__ import unicode_literals + +from django.db import migrations + +def generuj_RocnikNody_a_CisloNody(apps,schema_editor): + Rocnik = apps.get_model('seminar', 'Rocnik') + RocnikNode = apps.get_model('seminar', 'RocnikNode') + Cislo = apps.get_model('seminar', 'Cislo') + CisloNode = apps.get_model('seminar', 'CisloNode') + + last_rn = None # last_* slouží k navázání následníků + for r in Rocnik.objects.all(): + rn = RocnikNode.objects.create(rocnik=r) + rn.save() + rn.root = rn + rn.save() + if last_rn: + last_rn.succ = rn + last_rn.save() + last_rn = rn + + last_cn = None + for c in Cislo.objects.filter(rocnik=r): + cn = CisloNode.objects.create(cislo=c, root=rn) + cn.save() + if last_cn: # Jsme něčí následník + last_cn.succ = cn + last_cn.save() + else: # Jsme první v řadě, takže se musíme přidat jako first_child RočníkNodu + rn.first_child = cn + rn.save() + last_cn = cn + + + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0055_smazat_nemigrovane_zastarale_veci'), + ] + + operations = [ + migrations.RunPython(generuj_RocnikNody_a_CisloNody, migrations.RunPython.noop), + ] diff --git a/seminar/migrations/0057_reseni_to_reseni_hodnoceni.py b/seminar/migrations/0057_reseni_to_reseni_hodnoceni.py new file mode 100644 index 00000000..a11d99ae --- /dev/null +++ b/seminar/migrations/0057_reseni_to_reseni_hodnoceni.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-28 21:46 +from __future__ import unicode_literals + +from django.db import migrations + +def reseni_to_Reseni(apps, schema_editor): + Reseni = apps.get_model('seminar','Reseni') + Reseni_Resitele = apps.get_model('seminar','Reseni_Resitele') + Hodnoceni = apps.get_model('seminar','Hodnoceni') + + for r in Reseni.objects.all(): + rr = Reseni_Resitele.objects.create(resitele = r.resitel, reseni=r) + if r.body == None: + print("!!!!!!!!!!!!!!!") + print(r.id,r) + print("!!!!!!!!!!!!!!!") + else: + h = Hodnoceni.objects.create( + body=r.body, + cislo_body = r.cislo_body, + problem = r.problem_old, + reseni = r) + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0056_vrcholy_pro_rocniky_a_cisla'), + ] + + operations = [ + migrations.RunPython(reseni_to_Reseni, migrations.RunPython.noop) + ] diff --git a/seminar/migrations/0058_problem_to_uloha_tema_clanek.py b/seminar/migrations/0058_problem_to_uloha_tema_clanek.py new file mode 100644 index 00000000..4ef135c4 --- /dev/null +++ b/seminar/migrations/0058_problem_to_uloha_tema_clanek.py @@ -0,0 +1,211 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-17 17:44 +from __future__ import unicode_literals + +from django.db import migrations, models + +from django.db.models import Q +import django.db.models.deletion + +def poskladej_strom(apps, rodic, *texty): + Text = apps.get_model('seminar', 'Text') + TextNode = apps.get_model('seminar', 'TextNode') + if not rodic: + raise ValueError("Rodič musí být definovaný") + + uz_ma_deti = False + tn = None + for txt in texty: + if not txt: + continue + # Přidej do stromu: + textobj = Text.objects.create(na_web = txt) + textobj.save() + textnode = TextNode.objects.create(text = textobj) + textnode.save() + if not uz_ma_deti: + rodic.first_child = textnode + rodic.save() + tn = rodic.first_child + uz_ma_deti = True + else: + tn.succ = textnode + tn.save() + tn = tn.succ + +def uloha_to_Uloha(apps,schema_editor): + Problem = apps.get_model('seminar', 'Problem') + Uloha = apps.get_model('seminar', 'Uloha') + Text = apps.get_model('seminar', 'Text') + UlohaZadaniNode = apps.get_model('seminar', 'UlohaZadaniNode') + UlohaVzorakNode = apps.get_model('seminar', 'UlohaVzorakNode') + TextNode = apps.get_model('seminar', 'TextNode') + + ulohy = Problem.objects.filter(typ = 'uloha') + for uold in ulohy: + unew = Uloha.objects.create( + # Zakomentované fieldy by se už měly nacházet v příslušném problému + problem_ptr = uold, + nazev = uold.nazev, + stav = uold.stav, + zamereni = uold.zamereni, + poznamka = uold.poznamka, + autor = uold.autor, + kod = uold.kod, + cislo_zadani = uold.cislo_zadani_old, + cislo_reseni = uold.cislo_reseni_old, + max_body = uold.body, + vytvoreno = uold.vytvoreno, + ) + uold.save() # DULEZITE!!! Jinak Uloha.objects.create() přepíše všechny atributy Problému + unew.opravovatele.add(*uold.opravovatele.all()) + + # Nody: + zadani_node = UlohaZadaniNode.objects.create(uloha = unew) + poskladej_strom(apps, zadani_node, uold.text_zadani) + zadani_node.save() + vzorak_node = UlohaVzorakNode.objects.create(uloha = unew) + poskladej_strom(apps, vzorak_node, uold.text_reseni) + vzorak_node.save() + +def konfery_rucne(apps, schema_editor): + # Tohle dělat nebudu, máme aktuálně celou jednu. Ale "Errors should never pass silently" + Problem = apps.get_model('seminar', 'Problem') + pocet_konfer = Problem.objects.filter(typ = 'konfera').count() + if pocet_konfer > 0: + raise NotImplementedError("Zkonvertuj {} konfer na objekt Konfera ručně, prosím".format(pocet_konfer)) + +def clanek_to_Clanek(apps,schema_editor): + Problem = apps.get_model('seminar', 'Problem') + Clanek = apps.get_model('seminar', 'Clanek') + ReseniNode = apps.get_model('seminar', 'ReseniNode') + Text = apps.get_model('seminar', 'Text') + TextNode = apps.get_model('seminar', 'TextNode') + + # XXX: Org-clanky neexistuji, tak je migrace ani nepodporuje. + clanky = Problem.objects.filter(typ='res-clanek') + for cl in clanky: + # Vybereme vhodné číslo pro článek z čísla zadání a čísla řešení: + if cl.cislo_zadani_old is None: + cislo = cl.cislo_reseni_old + elif cl.cislo_reseni_old is None: + cislo = cl.cislo_zadani_old + elif cl.cislo_reseni_old == cl.cislo_zadani_old: + cislo = cl.cislo_zadani_old + else: + raise ValueError("Různá čísla zadání a řešení u článku! (Článek: {})".format(cl.nazev)) + + clnew = Clanek.objects.create( + problem_ptr = cl, + # Problém by nemělo být potřeba upravovat + cislo = cislo, + # Body ignorujeme, protože už jsou v hodnocení + ) + cl.save() # DULEZITE!!! Jinak Clanek.objects.create() přepíše všechny atributy Problému + + +def Clanek_Treenody(apps, schema_editor): + Problem = apps.get_model('seminar', 'Problem') + Clanek = apps.get_model('seminar', 'Clanek') + ReseniNode = apps.get_model('seminar', 'ReseniNode') + Text = apps.get_model('seminar', 'Text') + TextNode = apps.get_model('seminar', 'TextNode') + for cl in Clanek.objects.all(): + # Vyrobíme nody: + # Clanek nema vlastni node, ma (prave jedno) Reseni a to ma text_cely -- ReseniNode + reseni = cl.reseni_set.all() + if len(reseni) != 1: + raise ValueError(f'Clanek {cl.id} ma vic reseni {len(reseni)} ({reseni})') + reseni = reseni[0] + resnode = ReseniNode(reseni=reseni) + poskladej_strom(apps, resnode, cl.text_zadani, cl.text_reseni) + resnode.save() + reseni.text_cely = resnode + reseni.save() + +def fix_Clanek_Reseni(apps, schema_editor): + Problem = apps.get_model('seminar', 'Problem') + Clanek = apps.get_model('seminar', 'Clanek') + Reseni = apps.get_model('seminar', 'Reseni') + Hodnoceni = apps.get_model('seminar', 'Hodnoceni') + Resitel = apps.get_model('seminar', 'Resitel') + + # Je potreba zajistit, ze clanky budou mit jen jedno reseni -- z pohledu + # modelu nic jineho nedava smysl. Ve stavajicim modelu ale naopak nelze + # reprezentovat vice resitelu jednoho clanku (coz je ale bezne -- clanky z + # konfer) Musime tedy opravit, aby misto nekolika reseni kazdeho resitele + # samostatne zustalo jen jedno reseni, spravne obodovane a s vice resiteli + # jako autory + + for cl in Clanek.objects.all(): + rr = cl.reseni_set.all() + if len(rr) == 1: continue + # Vice nez jedno reseni, jdeme je sjednotit. + resitele = [] + vzor_hodnoceni = rr[0].hodnoceni_set.first() + ostatni_hodnoceni = [] + for r in rr: + # Overime, ze nemame kolizi v datech: + h = r.hodnoceni_set.first() + if h.cislo_body != vzor_hodnoceni.cislo_body or h.body != vzor_hodnoceni.body: + raise ValueError(f'Clanek {cl.id} ma vice nekonzistentnich reseni') + if h.id != vzor_hodnoceni.id: + ostatni_hodnoceni.append(h) + resitele.extend(r.resitele.all()) + rr[0].resitele.set(resitele) + rr[0].save() + vzor_hodnoceni.save() + # Ted mame spravne databazi, jeste potrebujeme z databaze smazat po novu nepouzita hodnoceni + for h in ostatni_hodnoceni: + h.reseni.delete() + h.delete() + +def tema_to_Tema(apps, schema_editor): + Problem = apps.get_model('seminar', 'Problem') + Tema = apps.get_model('seminar', 'Tema') + TemaVCisleNode = apps.get_model('seminar', 'TemaVCisleNode') + Text = apps.get_model('seminar', 'Text') + TextNode = apps.get_model('seminar', 'TextNode') + + temata = Problem.objects.filter(Q(typ = 'tema') | Q(typ='serial')) + for t in temata: + # Vymyslíme správně ročník: + if t.cislo_zadani_old is None and t.cislo_reseni_old is None: + rocnik = None + elif t.cislo_zadani_old is None: + rocnik = t.cislo_reseni_old.rocnik + elif t.cislo_reseni_old is None: + rocnik = t.cislo_zadani_old.rocnik + elif t.cislo_reseni_old.rocnik == t.cislo_zadani_old.rocnik: + rocnik = t.cislo_zadani_old.rocnik + else: + raise ValueError("Nelze mít téma přes více ročníků! (Téma: {}".format(t.nazev)) + + tnew = Tema.objects.create( + problem_ptr = t, + tema_typ = t.typ, + rocnik = rocnik, + ) + t.save() # DULEZITE!!! Jinak Tema.objects.create() přepíše všechny atributy Problému + + # Nody: + tnode = TemaVCisleNode(tema = tnew) + poskladej_strom(apps, tnode, t.text_zadani, t.text_reseni) + tnode.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0087_fix_polymorphism'), + ] + + operations = [ + # ashes to Ashes, dust to Dust.... + migrations.RunPython(uloha_to_Uloha, migrations.RunPython.noop), + migrations.RunPython(tema_to_Tema, migrations.RunPython.noop), + migrations.RunPython(clanek_to_Clanek, migrations.RunPython.noop), + migrations.RunPython(fix_Clanek_Reseni, migrations.RunPython.noop), + migrations.RunPython(Clanek_Treenody, migrations.RunPython.noop), + migrations.RunPython(konfery_rucne, migrations.RunPython.noop), + ] diff --git a/seminar/migrations/0059_vytvorit_pohadkanode.py b/seminar/migrations/0059_vytvorit_pohadkanode.py new file mode 100644 index 00000000..2a78c7ee --- /dev/null +++ b/seminar/migrations/0059_vytvorit_pohadkanode.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-29 03:26 +from __future__ import unicode_literals + +from django.db import migrations + +def vytvor_pohadkanode(apps, schema_editor): + Pohadka = apps.get_model('seminar', 'Pohadka') + PohadkaNode = apps.get_model('seminar', 'PohadkaNode') + Text = apps.get_model('seminar', 'Text') + TextNode = apps.get_model('seminar', 'TextNode') + + for p in Pohadka.objects.all(): + t = Text.objects.create(na_web = p.text) + t.save() + tn = TextNode.objects.create(text = t) + tn.save() + pn = PohadkaNode.objects.create(pohadka = p, first_child = tn) + pn.save() + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', 'fix_0058'), + ] + + operations = [ + migrations.RunPython(vytvor_pohadkanode, migrations.RunPython.noop), + ] diff --git a/seminar/migrations/0060_spoj_stromy.py b/seminar/migrations/0060_spoj_stromy.py new file mode 100644 index 00000000..d0826ca1 --- /dev/null +++ b/seminar/migrations/0060_spoj_stromy.py @@ -0,0 +1,128 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-29 03:26 +from __future__ import unicode_literals + +from django.db import migrations + +from django.db.models import Q + +def nastav_koren(koren, node): + node.root = koren + node.save() + + if node.succ: + nastav_koren(koren, node.succ) + if node.first_child: + nastav_koren(koren, node.first_child) + +def pridej_potomka(rodic, potomek): + # Daný vrchol bude posledním potomkem rodiče + uz_ma_deti = False + posledni = None + + # Přidávaný potomek by neměl mít následovníka -- přidáváme potomka, ne podles. + if potomek.succ: + raise ValueError("Potomek má následovníka, to je velmi podezřelé!") + + # Najdeme aktuálně posledního potomka: + if rodic.first_child: + uz_ma_deti = True + posledni = rodic.first_child + while posledni.succ: + posledni = posledni.succ + + # Nastavíme kořen: + nastav_koren(rodic.root, potomek) + + # Připojíme vrchol: + if uz_ma_deti: + posledni.succ = potomek + posledni.save() + else: + rodic.first_child = potomek + rodic.save() + +def pokacej_les(apps, schema_editor): + # Teď je potřeba všechny TreeNody příslušející k zadaným problémům připojit + # do hlavního stromu + # Tohle je jednoduchá verze: nejdřív témátka a seriály, pak úložky a pohádky, + # pak články a konfery, pak vzoráky, všechno setříděné podle kódu (FIXME?) + + # Kopírování je častým zdrojem chyb! + Cislo = apps.get_model('seminar', 'Cislo') + Tema = apps.get_model('seminar', 'Tema') + Konfera = apps.get_model('seminar', 'Konfera') + Clanek = apps.get_model('seminar', 'Clanek') + Uloha = apps.get_model('seminar', 'Uloha') + Problem = apps.get_model('seminar', 'Problem') + Pohadka = apps.get_model('seminar', 'Pohadka') + + for c in Cislo.objects.all().reverse(): + cnode = c.cislonode + + # Témata a seriály: + relevantni_temata = Tema.objects.filter(Q(cislo_zadani_old = c) | Q(cislo_reseni_old = c)).order_by('kod') + # Téma dáme do prvního čísla, kde se vyskytne + for t in relevantni_temata: + tnodes = t.temavcislenode_set.all() + # Migrujeme, TvCN je jen jedno dohromady + assert(len(tnodes) == 1) + tnode = tnodes[0] + # Zkontrolujeme a preskocime cislo_reseni + if t.cislo_zadani_old and t.cislo_reseni_old: + assert(t.cislo_zadani_old.rocnik == t.cislo_reseni_old.rocnik + and t.cislo_zadani_old.cislo <= t.cislo_reseni_old.cislo) + if t.cislo_reseni_old == c: + # Už by mělo být přidané do čísla zadání + continue + # Patří sem (buď je to jediné číslo, nebo je to číslo zadání) + pridej_potomka(cnode, tnode) + + # Úložky (zadání) a pohádky + for u in Uloha.objects.filter(cislo_zadani = c).order_by('kod'): + unode = u.ulohazadaninode + pohadky_pred = Pohadka.objects.filter(uloha_old = u.problem_ptr, pred = True) + pohadky_po = Pohadka.objects.filter(uloha_old = u.problem_ptr, pred = False) + for p in pohadky_pred: + pnode = p.pohadkanode + pridej_potomka(cnode, pnode) + pridej_potomka(cnode, unode) + for p in pohadky_po: + pnode = p.pohadkanode + pridej_potomka(cnode, pnode) + + # Pohádky, které nejsou u úlohy jsou špatně: + if Pohadka.objects.exclude(uloha_old__typ='uloha').count(): + raise ValueError("Existuje pohádka, která není u úlohy") + + # Články + for cl in Clanek.objects.filter(cislo = c).order_by('kod'): + # Zmena: Clanky nemaji vlastni Node, ale pouziva se ReseniNode v text_cely + reseni = cl.reseni_set.all() + if len(reseni) != 1: + raise ValueError('Clanek ma vic reseni') + resnode = reseni[0].text_cely + pridej_potomka(cnode, resnode) + + # Konfery + for k in Konfera.objects.all(): + knode = k.konferanode + if k.reseni and knode.root is None: + # Takováhle konfera nejspíš neexistuje + raise NotImplementedError("Konfery neumím zapojit do stromu") + + # Vzoráky + for u in Uloha.objects.filter(cislo_reseni = c).order_by('kod'): + unode = u.ulohavzoraknode + pridej_potomka(cnode, unode) + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0059_vytvorit_pohadkanode'), + ] + + operations = [ + migrations.RunPython(pokacej_les, migrations.RunPython.noop), + ] diff --git a/seminar/migrations/0061_kill_frankenstein.py b/seminar/migrations/0061_kill_frankenstein.py new file mode 100644 index 00000000..0a367edf --- /dev/null +++ b/seminar/migrations/0061_kill_frankenstein.py @@ -0,0 +1,153 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-29 03:29 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0060_spoj_stromy'), + ] + + operations = [ + migrations.RemoveField( + model_name='novinky', + name='autor_old', + ), + migrations.RemoveField( + model_name='organizator', + name='foto', + ), + migrations.RemoveField( + model_name='organizator', + name='organizuje_do_roku', + ), + migrations.RemoveField( + model_name='organizator', + name='organizuje_od_roku', + ), + migrations.RemoveField( + model_name='organizator', + name='prezdivka', + ), + migrations.RemoveField( + model_name='organizator', + name='user', + ), + migrations.RemoveField( + model_name='pohadka', + name='autor_old', + ), + migrations.RemoveField( + model_name='pohadka', + name='uloha_old', + ), + migrations.RemoveField( + model_name='problem', + name='autor_old', + ), + migrations.RemoveField( + model_name='problem', + name='body', + ), + migrations.RemoveField( + model_name='problem', + name='cislo_reseni_old', + ), + migrations.RemoveField( + model_name='problem', + name='cislo_zadani_old', + ), + migrations.RemoveField( + model_name='problem', + name='opravovatel', + ), + migrations.RemoveField( + model_name='problem', + name='text_reseni', + ), + migrations.RemoveField( + model_name='problem', + name='text_zadani', + ), + migrations.RemoveField( + model_name='problem', + name='typ', + ), + migrations.RemoveField( + model_name='reseni', + name='body', + ), + migrations.RemoveField( + model_name='reseni', + name='cislo_body', + ), + migrations.RemoveField( + model_name='reseni', + name='problem_old', + ), + migrations.RemoveField( + model_name='reseni', + name='resitel', + ), + migrations.RemoveField( + model_name='resitel', + name='datum_narozeni', + ), + migrations.RemoveField( + model_name='resitel', + name='datum_prihlaseni', + ), + migrations.RemoveField( + model_name='resitel', + name='datum_souhlasu_udaje', + ), + migrations.RemoveField( + model_name='resitel', + name='datum_souhlasu_zasilani', + ), + migrations.RemoveField( + model_name='resitel', + name='email', + ), + migrations.RemoveField( + model_name='resitel', + name='jmeno', + ), + migrations.RemoveField( + model_name='resitel', + name='mesto', + ), + migrations.RemoveField( + model_name='resitel', + name='pohlavi_muz', + ), + migrations.RemoveField( + model_name='resitel', + name='prijmeni', + ), + migrations.RemoveField( + model_name='resitel', + name='psc', + ), + migrations.RemoveField( + model_name='resitel', + name='stat', + ), + migrations.RemoveField( + model_name='resitel', + name='telefon', + ), + migrations.RemoveField( + model_name='resitel', + name='ulice', + ), + migrations.RemoveField( + model_name='resitel', + name='user', + ), + ] diff --git a/seminar/migrations/0062_redukce_modelu_pohadky.py b/seminar/migrations/0062_redukce_modelu_pohadky.py new file mode 100644 index 00000000..b4e5f11e --- /dev/null +++ b/seminar/migrations/0062_redukce_modelu_pohadky.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-30 01:16 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0061_kill_frankenstein'), + ] + + operations = [ + migrations.AlterModelOptions( + name='pohadka', + options={'ordering': ['vytvoreno'], 'verbose_name': 'Pohádka', 'verbose_name_plural': 'Pohádky'}, + ), + migrations.RemoveField( + model_name='pohadka', + name='pred', + ), + migrations.RemoveField( + model_name='pohadka', + name='text', + ), + migrations.RemoveField( + model_name='pohadka', + name='uloha', + ), + ] diff --git a/seminar/migrations/0063_procisteni_migraci.py b/seminar/migrations/0063_procisteni_migraci.py new file mode 100644 index 00000000..3dce57ad --- /dev/null +++ b/seminar/migrations/0063_procisteni_migraci.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-05-30 01:32 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0062_redukce_modelu_pohadky'), + ] + + operations = [ + migrations.AlterField( + model_name='cislo', + name='verejna_vysledkovka', + # Změnil se help_text -- byly v něm tabulátory kvůli zlomu v modelech + field=models.BooleanField(default=False, help_text='Je-li false u veřejného čísla, není výsledkovka zatím veřejná.', verbose_name='zveřejněna výsledkovka'), + ), + migrations.AlterField( + model_name='prijemce', + name='osoba', + # Bylo: ForeignKey + field=models.OneToOneField(help_text='Které osobě či na jakou adresu se mají zasílat čísla', on_delete=django.db.models.deletion.CASCADE, to='seminar.Osoba', verbose_name='komu'), + ), + migrations.AlterField( + model_name='reseni', + name='cas_doruceni', + # Bylo: editable=False + field=models.DateTimeField(blank=True, default=django.utils.timezone.now, verbose_name='čas_doručení'), + ), + ] diff --git a/seminar/migrations/0064_auto_20190610_2358.py b/seminar/migrations/0064_auto_20190610_2358.py new file mode 100644 index 00000000..78e62862 --- /dev/null +++ b/seminar/migrations/0064_auto_20190610_2358.py @@ -0,0 +1,162 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.21 on 2019-06-10 21:58 +from __future__ import unicode_literals + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0063_procisteni_migraci'), + ] + + operations = [ + migrations.AlterField( + model_name='cislo', + name='rocnik', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='cisla', to='seminar.Rocnik', verbose_name='ročník'), + ), + migrations.AlterField( + model_name='clanek', + name='cislo', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Cislo', verbose_name='číslo'), + ), + migrations.AlterField( + model_name='hodnoceni', + name='cislo_body', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='hodnoceni', to='seminar.Cislo', verbose_name='číslo pro body', null=True), + ), + migrations.AlterField( + model_name='hodnoceni', + name='problem', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Problem', verbose_name='problém'), + ), + migrations.AlterField( + model_name='konfery_ucastnici', + name='konfera', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Konfera', verbose_name='konfera'), + ), + migrations.AlterField( + model_name='konfery_ucastnici', + name='resitel', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Resitel', verbose_name='řešitel'), + ), + migrations.AlterField( + model_name='nastaveni', + name='aktualni_cislo', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Cislo', verbose_name='poslední vydané číslo'), + ), + migrations.AlterField( + model_name='nastaveni', + name='aktualni_rocnik', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Rocnik', verbose_name='aktuální ročník'), + ), + migrations.AlterField( + model_name='novinky', + name='autor', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Organizator', verbose_name='Autor novinky'), + ), + migrations.AlterField( + model_name='organizator', + name='osoba', + field=models.OneToOneField(help_text='osobní údaje organizátora', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='org', to='seminar.Osoba', verbose_name='osoba'), + ), + migrations.AlterField( + model_name='osoba', + name='user', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL, verbose_name='uživatel'), + ), + migrations.AlterField( + model_name='pohadka', + name='autor', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Organizator', verbose_name='Autor pohádky'), + ), + migrations.AlterField( + model_name='problem', + name='autor', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='autor_problemu_problem', to='seminar.Organizator', verbose_name='autor problému'), + ), + migrations.AlterField( + model_name='problem', + name='garant', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='garant_problemu_problem', to='seminar.Organizator', verbose_name='garant zadaného problému'), + ), + migrations.AlterField( + model_name='problem', + name='nadproblem', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='nadproblem_problem', to='seminar.Problem', verbose_name='nadřazený problém'), + ), + migrations.AlterField( + model_name='reseni', + name='text_cely', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='reseni_cely_set', to='seminar.ReseniNode', verbose_name='Plná verze textu řešení'), + ), + migrations.AlterField( + model_name='reseni_resitele', + name='resitele', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Resitel', verbose_name='řešitel'), + ), + migrations.AlterField( + model_name='resitel', + name='osoba', + field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Osoba', verbose_name='osoba'), + ), + migrations.AlterField( + model_name='resitel', + name='skola', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Skola', verbose_name='škola'), + ), + migrations.AlterField( + model_name='skola', + name='kontaktni_osoba', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='seminar.Osoba', verbose_name='Kontaktní osoba'), + ), + migrations.AlterField( + model_name='soustredeni', + name='rocnik', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='soustredeni', to='seminar.Rocnik', verbose_name='ročník'), + ), + migrations.AlterField( + model_name='soustredeni_organizatori', + name='organizator', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Organizator', verbose_name='organizátor'), + ), + migrations.AlterField( + model_name='soustredeni_organizatori', + name='soustredeni', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Soustredeni', verbose_name='soustředění'), + ), + migrations.AlterField( + model_name='soustredeni_ucastnici', + name='resitel', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Resitel', verbose_name='řešitel'), + ), + migrations.AlterField( + model_name='soustredeni_ucastnici', + name='soustredeni', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Soustredeni', verbose_name='soustředění'), + ), + migrations.AlterField( + model_name='tema', + name='rocnik', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='seminar.Rocnik', verbose_name='ročník'), + ), + migrations.AlterField( + model_name='uloha', + name='cislo_deadline', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='deadlinove_ulohy', to='seminar.Cislo', verbose_name='číslo deadlinu'), + ), + migrations.AlterField( + model_name='uloha', + name='cislo_reseni', + field=models.ForeignKey(blank=True, help_text='Číslo s řešením úlohy, jen pro úlohy', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='resene_ulohy', to='seminar.Cislo', verbose_name='číslo řešení'), + ), + migrations.AlterField( + model_name='uloha', + name='cislo_zadani', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='zadane_ulohy', to='seminar.Cislo', verbose_name='číslo zadání'), + ), + ] diff --git a/seminar/migrations/0065_treenode_polymorphic_ctype.py b/seminar/migrations/0065_treenode_polymorphic_ctype.py new file mode 100644 index 00000000..88917d77 --- /dev/null +++ b/seminar/migrations/0065_treenode_polymorphic_ctype.py @@ -0,0 +1,31 @@ +# Generated by Django 2.2.4 on 2019-08-13 19:36 + +from django.db import migrations, models +import django.db.models.deletion + +def vyrob_treenodum_ctypes(apps, schema_editor): + # Kód zkopírovaný z dokumentace: https://django-polymorphic.readthedocs.io/en/stable/migrating.html + # NOTE: Tahle migrace je špatně, 0087 ji opravuje. Možno squashnout pryč. + TreeNode = apps.get_model('seminar', 'TreeNode') + ContentType = apps.get_model('contenttypes', 'ContentType') + + new_ct = ContentType.objects.get_for_model(TreeNode) + TreeNode.objects.filter(polymorphic_ctype__isnull=True).update(polymorphic_ctype=new_ct) + + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('seminar', '0057_reseni_to_reseni_hodnoceni'), + ] + + operations = [ + migrations.AddField( + model_name='treenode', + name='polymorphic_ctype', + field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_seminar.treenode_set+', to='contenttypes.ContentType'), + ), + migrations.RunPython(vyrob_treenodum_ctypes, migrations.RunPython.noop, elidable=True), + ] diff --git a/seminar/migrations/0066_problem_polymorphic_ctype.py b/seminar/migrations/0066_problem_polymorphic_ctype.py new file mode 100644 index 00000000..3aab4605 --- /dev/null +++ b/seminar/migrations/0066_problem_polymorphic_ctype.py @@ -0,0 +1,29 @@ +# Generated by Django 2.2.4 on 2019-08-13 19:45 + +from django.db import migrations, models +import django.db.models.deletion + +def vyrob_problemum_ctypes(apps, schema_editor): + # Kód zkopírovaný z dokumentace: https://django-polymorphic.readthedocs.io/en/stable/migrating.html + # NOTE: Tahle migrace je špatně, 0087 ji opravuje. Možno squashnout pryč. + Problem = apps.get_model('seminar', 'Problem') + ContentType = apps.get_model('contenttypes', 'ContentType') + + new_ct = ContentType.objects.get_for_model(Problem) + Problem.objects.filter(polymorphic_ctype__isnull=True).update(polymorphic_ctype=new_ct) + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('seminar', '0065_treenode_polymorphic_ctype'), + ] + + operations = [ + migrations.AddField( + model_name='problem', + name='polymorphic_ctype', + field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_seminar.problem_set+', to='contenttypes.ContentType'), + ), + migrations.RunPython(vyrob_problemum_ctypes, migrations.RunPython.noop, elidable=True), + ] diff --git a/seminar/migrations/0066b_orgtextnode.py b/seminar/migrations/0066b_orgtextnode.py new file mode 100644 index 00000000..ecf509bb --- /dev/null +++ b/seminar/migrations/0066b_orgtextnode.py @@ -0,0 +1,31 @@ + +# Generated by Django 2.2.4 on 2019-08-13 19:45 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('seminar', '0066_problem_polymorphic_ctype'), + ] + + operations = [ + migrations.CreateModel( + name='OrgTextNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('org_verejny', models.BooleanField(default=True, help_text='Pokud ano, bude org pod článkem podepsaný', verbose_name='Org je veřejný?')), + ('organizator', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='seminar.Organizator', verbose_name='Organizátor')), + ], + options={ + 'verbose_name': 'Organizátorský článek (Node)', + 'verbose_name_plural': 'Organizátorské články (Node)', + 'db_table': 'seminar_nodes_orgtextnode', + }, + bases=('seminar.treenode',), + ), + + ] diff --git a/seminar/migrations/0066c_reseninode.py b/seminar/migrations/0066c_reseninode.py new file mode 100644 index 00000000..8e3bd3cd --- /dev/null +++ b/seminar/migrations/0066c_reseninode.py @@ -0,0 +1,34 @@ +# Generated by Django 2.2.4 on 2019-08-13 19:45 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('seminar', '0050_auto_20190510_2228'), + ] + + operations = [ + migrations.CreateModel( + name='ReseniNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('reseni', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Reseni', verbose_name='reseni')), + ], + options={ + 'verbose_name': 'Otištěné řešení (Node)', + 'verbose_name_plural': 'Otištěná řešení (Node)', + 'db_table': 'seminar_nodes_otistene_reseni', + }, + bases=('seminar.treenode',), + ), + migrations.AddField( + model_name='reseni', + name='text_cely', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='reseni_cely_set', to='seminar.ReseniNode', verbose_name='Plná verze textu řešení'), + ), + + ] diff --git a/seminar/migrations/0067_auto_20190814_0805.py b/seminar/migrations/0067_auto_20190814_0805.py new file mode 100644 index 00000000..04d333a0 --- /dev/null +++ b/seminar/migrations/0067_auto_20190814_0805.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.4 on 2019-08-14 06:05 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0064_auto_20190610_2358'), + ] + + operations = [ + migrations.AlterField( + model_name='konfera', + name='nazev', + field=models.CharField(help_text='Název konfery', max_length=100, verbose_name='název konfery'), + ), + ] diff --git a/seminar/migrations/0068_treenode_nazev.py b/seminar/migrations/0068_treenode_nazev.py new file mode 100644 index 00000000..c0024c8d --- /dev/null +++ b/seminar/migrations/0068_treenode_nazev.py @@ -0,0 +1,107 @@ +# Generated by Django 2.2.5 on 2019-09-26 19:35 + +from django.db import migrations, models + +# Migrace nejspíš neumí volat metody modelů: +# https://stackoverflow.com/questions/28777338/django-migrations-runpython-not-able-to-call-model-methods#37685925 + +def fix_RocnikNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'RocnikNode') + for obj in Objects.objects.all(): + obj.nazev = str(obj.rocnik)+" (RocnikNode)" + obj.save() + +def fix_CisloNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'CisloNode') + for obj in Objects.objects.all(): + obj.nazev = str(obj.cislo)+" (CisloNode)" + obj.save() + +def fix_MezicisloNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'MezicisloNode') + for obj in Objects.objects.all(): + if obj.prev: + if (obj.prev.get_real_instance_class() != CisloNode and + obj.prev.get_real_instance_class() != MezicisloNode): + raise ValueError("Předchůdce není číslo!") + posledni = obj.prev.cislo + obj.nazev = "Mezičíslo po čísle"+str(posledni)+" (MezicisloNode)" + elif obj.root: + if obj.root.get_real_instance_class() != RocnikNode: + raise ValueError("Kořen stromu není ročník!") + rocnik = obj.root.rocnik + obj.nazev = "První mezičíslo ročníku "+" (MezicisloNode)" + else: + print("!!!!! Nějaké neidentifikované mezičíslo !!!!!") + obj.nazev = "Neidentifikovatelné mezičíslo! (MezicisloNode)" + obj.save() + +def fix_TemaVCisleNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'TemaVCisleNode') + for obj in Objects.objects.all(): + obj.nazev = str(obj.tema)+" (TemaVCisleNode)" + obj.save() + +def fix_KonferaNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'KonferaNode') + for obj in Objects.objects.all(): + obj.nazev = str(obj.konfera)+" (KonferaNode)" + obj.save() + +def fix_ClanekNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'ClanekNode') + for obj in Objects.objects.all(): + obj.nazev = str(obj.clanek)+" (ClanekNode)" + obj.save() + +def fix_UlohaZadaniNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'UlohaZadaniNode') + for obj in Objects.objects.all(): + obj.nazev = str(obj.uloha)+" (UlohaZadaniNode)" + obj.save() + +def fix_PohadkaNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'PohadkaNode') + for obj in Objects.objects.all(): + obj.nazev = str(obj.pohadka)+" (PohadkaNode)" + obj.save() + +def fix_UlohaVzorakNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'UlohaVzorakNode') + for obj in Objects.objects.all(): + obj.nazev = str(obj.uloha)+" (UlohaVzorakNode)" + obj.save() + +def fix_TextNode_names(apps,schema_editor): + Objects = apps.get_model('seminar', 'TextNode') + for obj in Objects.objects.all(): + obj.nazev = str(obj.text)+" (TextNode)" + obj.save() + +def fix_all_names(apps,schema_editor): + fix_RocnikNode_names(apps,schema_editor) + fix_CisloNode_names(apps,schema_editor) + fix_MezicisloNode_names(apps,schema_editor) + fix_TemaVCisleNode_names(apps,schema_editor) + fix_KonferaNode_names(apps,schema_editor) + fix_ClanekNode_names(apps,schema_editor) + fix_UlohaZadaniNode_names(apps,schema_editor) + fix_PohadkaNode_names(apps,schema_editor) + fix_UlohaVzorakNode_names(apps,schema_editor) + fix_TextNode_names(apps,schema_editor) + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0067_auto_20190814_0805'), + ] + + operations = [ + migrations.AddField( + model_name='treenode', + name='nazev', + field=models.TextField(help_text='Tento název se zobrazuje v nabídkách pro výběr vhodného TreeNode', null=True, verbose_name='název tohoto node'), + ), + migrations.RunPython(fix_all_names, migrations.RunPython.noop), + ] diff --git a/seminar/migrations/0069_auto_20191120_2115.py b/seminar/migrations/0069_auto_20191120_2115.py new file mode 100644 index 00000000..04c6d1dc --- /dev/null +++ b/seminar/migrations/0069_auto_20191120_2115.py @@ -0,0 +1,28 @@ +# Generated by Django 2.2.7 on 2019-11-20 20:15 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0068_treenode_nazev'), + ] + + operations = [ + migrations.AlterModelOptions( + name='cislo', + options={'ordering': ['-rocnik__rocnik', '-poradi'], 'verbose_name': 'Číslo', 'verbose_name_plural': 'Čísla'}, + ), + migrations.RenameField( + model_name='cislo', + old_name='cislo', + new_name='poradi', + ), + migrations.AlterField( + model_name='problem', + name='nadproblem', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='podproblem', to='seminar.Problem', verbose_name='nadřazený problém'), + ), + ] diff --git a/seminar/migrations/0070_auto_20191120_2357.py b/seminar/migrations/0070_auto_20191120_2357.py new file mode 100644 index 00000000..3bd5466f --- /dev/null +++ b/seminar/migrations/0070_auto_20191120_2357.py @@ -0,0 +1,23 @@ +# Generated by Django 2.2.7 on 2019-11-20 22:57 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0069_auto_20191120_2115'), + ] + + operations = [ + migrations.AddField( + model_name='tema', + name='abstrakt', + field=models.TextField(blank=True, verbose_name='Abstrakt na rozcestník'), + ), + migrations.AddField( + model_name='tema', + name='obrazek', + field=models.ImageField(null=True, upload_to='', verbose_name='Obrázek na rozcestník'), + ), + ] diff --git a/seminar/migrations/0071_remove_nastaveni_aktualni_rocnik.py b/seminar/migrations/0071_remove_nastaveni_aktualni_rocnik.py new file mode 100644 index 00000000..d20c1501 --- /dev/null +++ b/seminar/migrations/0071_remove_nastaveni_aktualni_rocnik.py @@ -0,0 +1,17 @@ +# Generated by Django 2.2.7 on 2019-11-21 17:38 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0070_auto_20191120_2357'), + ] + + operations = [ + migrations.RemoveField( + model_name='nastaveni', + name='aktualni_rocnik', + ), + ] diff --git a/seminar/migrations/0072_auto_20191204_2257.py b/seminar/migrations/0072_auto_20191204_2257.py new file mode 100644 index 00000000..f96b670a --- /dev/null +++ b/seminar/migrations/0072_auto_20191204_2257.py @@ -0,0 +1,23 @@ +# Generated by Django 2.2.7 on 2019-12-04 21:57 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0071_remove_nastaveni_aktualni_rocnik'), + ] + + operations = [ + migrations.AddField( + model_name='treenode', + name='srolovatelne', + field=models.BooleanField(blank=True, help_text='Bude na stránce témátka možnost tuto položku skrýt', null=True, verbose_name='Srolovatelné'), + ), + migrations.AddField( + model_name='treenode', + name='zajimave', + field=models.BooleanField(default=False, help_text='Zobrazí se daná věc na rozcestníku témátek', verbose_name='Zajímavé'), + ), + ] diff --git a/seminar/migrations/0073_copy_osoba_email_to_user_email.py b/seminar/migrations/0073_copy_osoba_email_to_user_email.py new file mode 100644 index 00000000..3b280209 --- /dev/null +++ b/seminar/migrations/0073_copy_osoba_email_to_user_email.py @@ -0,0 +1,22 @@ +# Generated by Django 2.2.9 on 2020-01-15 21:28 + +from django.db import migrations + +def copy_mails(apps, schema_editor): + Osoba = apps.get_model('seminar', 'Osoba') + + for o in Osoba.objects.all(): + if o.user is not None: + u = o.user + u.email = o.email + u.save() + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0072_auto_20191204_2257'), + ] + + operations = [ + migrations.RunPython(copy_mails, migrations.RunPython.noop) + ] diff --git a/seminar/migrations/0074_auto_20200228_1401.py b/seminar/migrations/0074_auto_20200228_1401.py new file mode 100644 index 00000000..447d5aab --- /dev/null +++ b/seminar/migrations/0074_auto_20200228_1401.py @@ -0,0 +1,24 @@ +# Generated by Django 2.2.9 on 2020-02-28 13:01 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0073_copy_osoba_email_to_user_email'), + ] + + operations = [ + migrations.AddField( + model_name='prilohareseni', + name='res_poznamka', + field=models.TextField(blank=True, help_text='Poznámka k příloze řešení, např. co daný soubor obsahuje', verbose_name='poznámka řešitele'), + ), + migrations.AlterField( + model_name='hodnoceni', + name='problem', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='hodnoceni', to='seminar.Problem', verbose_name='problém'), + ), + ] diff --git a/seminar/migrations/0075_auto_20200228_2010.py b/seminar/migrations/0075_auto_20200228_2010.py new file mode 100644 index 00000000..2e703e4e --- /dev/null +++ b/seminar/migrations/0075_auto_20200228_2010.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.9 on 2020-02-28 19:10 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0074_auto_20200228_1401'), + ] + + operations = [ + migrations.AlterField( + model_name='hodnoceni', + name='body', + field=models.DecimalField(decimal_places=1, max_digits=8, null=True, verbose_name='body'), + ), + ] diff --git a/seminar/migrations/0076_auto_20200228_2013.py b/seminar/migrations/0076_auto_20200228_2013.py new file mode 100644 index 00000000..04aaea1e --- /dev/null +++ b/seminar/migrations/0076_auto_20200228_2013.py @@ -0,0 +1,19 @@ +# Generated by Django 2.2.9 on 2020-02-28 19:13 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0075_auto_20200228_2010'), + ] + + operations = [ + migrations.AlterField( + model_name='hodnoceni', + name='cislo_body', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='hodnoceni', to='seminar.Cislo', verbose_name='číslo pro body'), + ), + ] diff --git a/seminar/migrations/0077_auto_20200318_2146.py b/seminar/migrations/0077_auto_20200318_2146.py new file mode 100644 index 00000000..5f5f2e26 --- /dev/null +++ b/seminar/migrations/0077_auto_20200318_2146.py @@ -0,0 +1,32 @@ +# Generated by Django 2.2.9 on 2020-03-18 20:46 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0066b_orgtextnode'), + ] + + operations = [ + migrations.CreateModel( + name='CastNode', + fields=[ + ('treenode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.TreeNode')), + ('nadpis', models.CharField(help_text='Nadpis podvěšené části obsahu', max_length=100, verbose_name='Nadpis')), + ], + options={ + 'verbose_name': 'Část (Node)', + 'verbose_name_plural': 'Části (Node)', + 'db_table': 'seminar_nodes_cast', + }, + bases=('seminar.treenode',), + ), + migrations.AlterField( + model_name='treenode', + name='first_child', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='father_of_first', to='seminar.TreeNode', verbose_name='první potomek'), + ), + ] diff --git a/seminar/migrations/0079_clanek_resitelsky.py b/seminar/migrations/0079_clanek_resitelsky.py new file mode 100644 index 00000000..88ad06eb --- /dev/null +++ b/seminar/migrations/0079_clanek_resitelsky.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.9 on 2020-03-25 19:24 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0076_auto_20200228_2013'), + ] + + operations = [ + migrations.AddField( + model_name='clanek', + name='resitelsky', + field=models.BooleanField(default=True, verbose_name='Jde o řešitelský článek?'), + ), + ] diff --git a/seminar/migrations/0080_zruseni_claneknode_a_konferanode.py b/seminar/migrations/0080_zruseni_claneknode_a_konferanode.py new file mode 100644 index 00000000..ddf3cc8e --- /dev/null +++ b/seminar/migrations/0080_zruseni_claneknode_a_konferanode.py @@ -0,0 +1,103 @@ +# Generated by Django 2.2.12 on 2020-04-01 20:54 +# Fixed by Pavel, 2020-01-04 20:56 UTC +# This is quite possibly a bug in Django. + +from django.db import migrations, models +import django.db.models.deletion + +def vyrob_dummy_problemy(apps, schema_editor): + Problem = apps.get_model('seminar', 'Problem') + Konfera = apps.get_model('seminar', 'Konfera') + for k in Konfera.objects.all(): + pr = Problem.objects.create(nazev=k.nazev, + garant=k.organizator) + pr.save() + k.problem_ptr = pr + k.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('seminar', '0079_clanek_resitelsky'), + ] + + operations = [ + migrations.DeleteModel( + name='Konfery_Ucastnici', + ), + migrations.RemoveField( + model_name='konfera', + name='ucastnici', + ), + migrations.RemoveField( + model_name='konfera', + name='id', + ), + migrations.RemoveField( + model_name='clanek', + name='cislo', + ), + migrations.RemoveField( + model_name='clanek', + name='resitelsky', + ), + migrations.RemoveField( + model_name='reseni', + name='text_zkraceny', + ), + migrations.DeleteModel( # nejdříve musím smazat objekt ukazující na konferu, + name='KonferaNode', # pak až změnit klíč konferám (viz další operace) + ), + migrations.AddField( + model_name='konfera', + name='problem_ptr', + field=models.OneToOneField(auto_created=True, null=False, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='seminar.Problem'), + preserve_default=False, + ), + migrations.RemoveField( + model_name='konfera', + name='nazev', + ), + migrations.RemoveField( + model_name='konfera', + name='organizator', + ), + migrations.RemoveField( + model_name='konfera', + name='poznamka', + ), + migrations.RemoveField( + model_name='konfera', + name='reseni', + ), + migrations.AlterField( + model_name='reseni', + name='text_cely', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='reseni_cely_set', to='seminar.ReseniNode', verbose_name='Plná verze textu řešení'), + ), + migrations.DeleteModel( + name='ClanekNode', + ), + migrations.CreateModel( + name='Konfery_Ucastnici', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('poznamka', models.TextField(blank=True, help_text='Neveřejná poznámka k účasti (plain text)', verbose_name='neveřejná poznámka')), + ('konfera', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Konfera', verbose_name='konfera')), + ('resitel', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='seminar.Resitel', verbose_name='řešitel')), + ], + options={ + 'verbose_name': 'Účast na konfeře', + 'verbose_name_plural': 'Účasti na konfeře', + 'db_table': 'seminar_konfery_ucastnici', + 'ordering': ['konfera', 'resitel'], + }, + ), + migrations.AddField( + model_name='konfera', + name='ucastnici', + field=models.ManyToManyField(help_text='Seznam účastníků konfery', through='seminar.Konfery_Ucastnici', to='seminar.Resitel', verbose_name='účastníci konfery'), + ), + ] diff --git a/seminar/migrations/0081_auto_20200408_2221.py b/seminar/migrations/0081_auto_20200408_2221.py new file mode 100644 index 00000000..6cf908bb --- /dev/null +++ b/seminar/migrations/0081_auto_20200408_2221.py @@ -0,0 +1,24 @@ +# Generated by Django 2.2.9 on 2020-04-08 20:21 + +from django.db import migrations, models +import seminar.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0080_zruseni_claneknode_a_konferanode'), + ] + + operations = [ + migrations.AddField( + model_name='cislo', + name='titulka_nahled', + field=models.ImageField(blank=True, help_text='Obrázek titulní strany, generuje se automaticky', null=True, upload_to='', verbose_name='Obrázek titulní strany'), + ), + migrations.AlterField( + model_name='cislo', + name='pdf', + field=models.FileField(blank=True, help_text='PDF čísla, které si mohou řešitelé stáhnout', null=True, upload_to=seminar.models.cislo_pdf_filename, verbose_name='pdf'), + ), + ] diff --git a/seminar/migrations/0082_auto_20200506_1951.py b/seminar/migrations/0082_auto_20200506_1951.py new file mode 100644 index 00000000..3132c434 --- /dev/null +++ b/seminar/migrations/0082_auto_20200506_1951.py @@ -0,0 +1,19 @@ +# Generated by Django 2.2.12 on 2020-05-06 17:51 + +from django.db import migrations, models +import seminar.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0081_auto_20200408_2221'), + ] + + operations = [ + migrations.AlterField( + model_name='cislo', + name='titulka_nahled', + field=models.ImageField(blank=True, help_text='Obrázek titulní strany, generuje se automaticky', null=True, upload_to=seminar.models.cislo_png_filename, verbose_name='Obrázek titulní strany'), + ), + ] diff --git a/seminar/migrations/0083_auto_20200506_1952.py b/seminar/migrations/0083_auto_20200506_1952.py new file mode 100644 index 00000000..0c7fcf38 --- /dev/null +++ b/seminar/migrations/0083_auto_20200506_1952.py @@ -0,0 +1,19 @@ +# Generated by Django 2.2.12 on 2020-05-06 17:52 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0082_auto_20200506_1951'), + ] + + operations = [ + migrations.AlterField( + model_name='treenode', + name='first_child', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='father_of_first', to='seminar.TreeNode', verbose_name='první potomek'), + ), + ] diff --git a/seminar/migrations/0084_clanek_cislo.py b/seminar/migrations/0084_clanek_cislo.py new file mode 100644 index 00000000..7a211fa6 --- /dev/null +++ b/seminar/migrations/0084_clanek_cislo.py @@ -0,0 +1,56 @@ +# Generated by Django 2.2.13 on 2020-06-17 19:06 + +from django.db import migrations, models +import django.db.models.deletion +from seminar.treelib import get_parent + +import logging +logger = logging.getLogger(__name__) + +def najdi_cislo(apps, schema_editor): + Clanek = apps.get_model('seminar', 'Clanek') + Hodnoceni = apps.get_model('seminar', 'Hodnoceni') + Reseni = apps.get_model('seminar', 'Reseni') + ReseniNode = apps.get_model('seminar', 'ReseniNode') + CisloNode = apps.get_model('seminar', 'CisloNode') + ContentType = apps.get_model('contenttypes', 'ContentType') + + for c in Clanek.objects.all(): + reseni = c.reseni_set + if (reseni.count() != 1): # Pozor, reseni_set je Manager, takže se na něj musí trošku jinak + logger.warn(f"Více než jedno řešení pro článek {c}") + c.cislo = None + c.save() + continue + r = reseni.first() + aktualniNode = r.text_cely # Hlavní ReseniNode pro řešení + while aktualniNode is not None: + #if isinstance(aktualniNode, CisloNode): # Nejde, protože aktualniNode se tváří jako obecný TreeNode... + # Ale v dokumentaci k django-polymorphic se píše, že tam jsou nastavené nějaké fieldy na známé hodnoty :-) + # https://django-polymorphic.readthedocs.io/en/stable/migrating.html + cislonode_ct = ContentType.objects.get_for_model(CisloNode) + akt_ct = aktualniNode.polymorphic_ctype + if akt_ct == cislonode_ct: + # Zneužíváme tu opačnou vazbu k treenode_ptr, protože + # aktualniNode je "jen" TreeNode a ne CisloNode + c.cislo = aktualniNode.cislonode.cislo + c.save() + break + aktualniNode = get_parent(aktualniNode) + + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0083_auto_20200506_1952'), + ] + + operations = [ + migrations.AddField( + model_name='clanek', + name='cislo', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vydane_clanky', to='seminar.Cislo', verbose_name='číslo vydání'), + ), + migrations.RunPython(najdi_cislo, migrations.RunPython.noop), + ] diff --git a/seminar/migrations/0085_nepovinna_prezdivka.py_old b/seminar/migrations/0085_nepovinna_prezdivka.py_old new file mode 100644 index 00000000..4a8f02e0 --- /dev/null +++ b/seminar/migrations/0085_nepovinna_prezdivka.py_old @@ -0,0 +1,34 @@ +# Generated by Django 2.2.13 on 2020-06-24 22:57 + +# V současné době nepoužíván + +from django.db import migrations, models + +def smaz_prezdivku(apps, schema_editor): + Osoba = apps.get_model('seminar', 'Osoba') + + for o in Osoba.objects.filter(prezdivka=''): + o.prezdivka = None + o.save() + +def pridej_prezdivku(apps, schema_editor): + Osoba = apps.get_model('seminar', 'Osoba') + + for o in Osoba.objects.filter(prezdivka=None): + o.prezdivka = '' + o.save() + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0084_clanek_cislo'), + ] + + operations = [ + migrations.AlterField( + model_name='osoba', + name='prezdivka', + field=models.CharField(blank=True, max_length=256, verbose_name='přezdívka'), + ), + migrations.RunPython(smaz_prezdivku, pridej_prezdivku), + ] diff --git a/seminar/migrations/0086_auto_20200819_0959.py b/seminar/migrations/0086_auto_20200819_0959.py new file mode 100644 index 00000000..7b6b85a3 --- /dev/null +++ b/seminar/migrations/0086_auto_20200819_0959.py @@ -0,0 +1,17 @@ +# Generated by Django 2.2.15 on 2020-08-19 07:59 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0084_clanek_cislo'), + ] + + operations = [ + migrations.AlterModelOptions( + name='organizator', + options={'ordering': ['-organizuje_do', 'osoba__jmeno', 'osoba__prijmeni'], 'verbose_name': 'Organizátor', 'verbose_name_plural': 'Organizátoři'}, + ), + ] diff --git a/seminar/migrations/0087_fix_polymorphism.py b/seminar/migrations/0087_fix_polymorphism.py new file mode 100644 index 00000000..9b95f66f --- /dev/null +++ b/seminar/migrations/0087_fix_polymorphism.py @@ -0,0 +1,50 @@ +# Generated by Django 2.2.16 on 2020-09-04 12:06 + +from django.db import migrations +from logging import getLogger + +log = getLogger(__name__) + +# Oprava migrací 0065 a 0066, kde jsem špatně pochopil django-polymorphic + +# Pomocná funkce -- děláme to samé pro obě polymorfní hierarchie +def fix_ctypes(parent: str, children, apps, schema_editor): + Parent = apps.get_model('seminar', parent) + ContentType = apps.get_model('contenttypes', 'ContentType') + + # Nejdřív všechno smažeme: + Parent.objects.update(polymorphic_ctype=None) + + # Opravíme děti + for clsname in children: + Model = apps.get_model('seminar', clsname) + ct = ContentType.objects.get_for_model(Model) + Model.objects.update(polymorphic_ctype=ct) + + + # Ostatní instance mají mít explicitně content type pro rodiče + new_ct = ContentType.objects.get_for_model(Parent) + for obj in Parent.objects.filter(polymorphic_ctype__isnull=True): + # Po úpravě pořadí migrací se tohle stane pro každý problém. Není to správně, ale warning moc otravuje… + log.info(f"{parent} \"{obj}\" neměl content type -- nejspíš to je instance přímo {parent}!") + obj.polymorphic_ctype=new_ct + obj.save() + +def fix_treenode(apps, schema_editor): + children = ['RocnikNode', 'CisloNode', 'MezicisloNode', 'TemaVCisleNode', + 'OrgTextNode', 'UlohaZadaniNode', 'UlohaVzorakNode', 'PohadkaNode', + 'TextNode', 'CastNode', 'ReseniNode'] + fix_ctypes("TreeNode", children, apps, schema_editor) + +def fix_problem(apps, schema_editor): + children = ['Tema', 'Clanek', 'Uloha'] # FIXME: Konfera z nějakého důvodu tenhle field vůbec nemá, asi je to špatně. + fix_ctypes("Problem", children, apps, schema_editor) + +class Migration(migrations.Migration): + dependencies = [ + ('seminar', '0077_auto_20200318_2146'), + ] + operations = [ + migrations.RunPython(fix_treenode, migrations.RunPython.noop), + migrations.RunPython(fix_problem, migrations.RunPython.noop), + ] diff --git a/seminar/migrations/0088_perm_org_a_ucastnik.py b/seminar/migrations/0088_perm_org_a_ucastnik.py new file mode 100644 index 00000000..dc76343a --- /dev/null +++ b/seminar/migrations/0088_perm_org_a_ucastnik.py @@ -0,0 +1,36 @@ +# Generated by Django 2.2.15 on 2020-09-05 10:10 +from django.db import migrations + + +def add_perms(apps, schema_editor): + ContentType = apps.get_model('contenttypes', 'ContentType') + User = apps.get_model('auth', 'User') + Permission = apps.get_model('auth', 'Permission') + Resitel = apps.get_model('seminar', 'Resitel') + + c = ContentType.objects.get_for_model(User) + org_perm = Permission.objects.filter(codename__exact='org').first() + if not org_perm: + org_perm = Permission.objects.create(codename='org', name='org', content_type=c) + resitel_perm = Permission.objects.filter(codename__exact='resitel').first() + if not resitel_perm: + resitel_perm = Permission.objects.create(codename='resitel', name='resitel', content_type=c) + for r in Resitel.objects.all(): + u = r.osoba.user + if u: + u.user_permissions.add(resitel_perm) + for org in User.objects.all(): + if org and org.is_staff: + org.user_permissions.add(org_perm) + org.user_permissions.remove(resitel_perm) + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0086_auto_20200819_0959'), + ] + + operations = [ + migrations.RunPython(add_perms, migrations.RunPython.noop), + ] diff --git a/seminar/migrations/0089_cislo_datum_preddeadline.py b/seminar/migrations/0089_cislo_datum_preddeadline.py new file mode 100644 index 00000000..0771991b --- /dev/null +++ b/seminar/migrations/0089_cislo_datum_preddeadline.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.16 on 2020-10-13 19:40 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0088_perm_org_a_ucastnik'), + ] + + operations = [ + migrations.AddField( + model_name='cislo', + name='datum_preddeadline', + field=models.DateField(blank=True, help_text='Datum pro příjem řešení, která se otisknou v dalším čísle', null=True, verbose_name='datum předdeadline'), + ), + ] diff --git a/seminar/migrations/0090_auto_20201110_1958.py b/seminar/migrations/0090_auto_20201110_1958.py new file mode 100644 index 00000000..97949f58 --- /dev/null +++ b/seminar/migrations/0090_auto_20201110_1958.py @@ -0,0 +1,19 @@ +# Generated by Django 2.2.12 on 2020-11-10 18:58 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0089_cislo_datum_preddeadline'), + ] + + operations = [ + migrations.AlterField( + model_name='textnode', + name='text', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.Text', verbose_name='text'), + ), + ] diff --git a/seminar/migrations/0091_resitel_zasilat_cislo_emailem.py b/seminar/migrations/0091_resitel_zasilat_cislo_emailem.py new file mode 100644 index 00000000..92f8367a --- /dev/null +++ b/seminar/migrations/0091_resitel_zasilat_cislo_emailem.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.17 on 2020-12-01 19:53 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0090_auto_20201110_1958'), + ] + + operations = [ + migrations.AddField( + model_name='resitel', + name='zasilat_cislo_emailem', + field=models.BooleanField(default=False, help_text='True pokud chce řešitel dostávat číslo emailem', verbose_name='zasílat číslo emailem'), + ), + ] diff --git a/seminar/migrations/0092_auto_20210309_2049.py b/seminar/migrations/0092_auto_20210309_2049.py new file mode 100644 index 00000000..3dbb7358 --- /dev/null +++ b/seminar/migrations/0092_auto_20210309_2049.py @@ -0,0 +1,19 @@ +# Generated by Django 2.2.15 on 2021-03-09 19:49 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0091_resitel_zasilat_cislo_emailem'), + ] + + operations = [ + migrations.AlterField( + model_name='tema', + name='rocnik', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='temata', to='seminar.Rocnik', verbose_name='ročník'), + ), + ] diff --git a/seminar/migrations/0093_auto_20210330_2105.py b/seminar/migrations/0093_auto_20210330_2105.py new file mode 100644 index 00000000..06132eca --- /dev/null +++ b/seminar/migrations/0093_auto_20210330_2105.py @@ -0,0 +1,28 @@ +# Generated by Django 2.2.12 on 2021-03-30 19:05 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0092_auto_20210309_2049'), + ] + + operations = [ + migrations.DeleteModel( + name='VysledkyCelkemKCislu', + ), + migrations.DeleteModel( + name='VysledkyKCislu', + ), + migrations.DeleteModel( + name='VysledkyKCisluOdjakziva', + ), + migrations.DeleteModel( + name='VysledkyKCisluZaRocnik', + ), + migrations.DeleteModel( + name='VysledkyZaCislo', + ), + ] diff --git a/seminar/migrations/0094_auto_20210701_0149.py b/seminar/migrations/0094_auto_20210701_0149.py new file mode 100644 index 00000000..8a6b0515 --- /dev/null +++ b/seminar/migrations/0094_auto_20210701_0149.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.24 on 2021-06-30 23:49 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0093_auto_20210330_2105'), + ] + + operations = [ + migrations.AlterField( + model_name='osoba', + name='prezdivka', + field=models.CharField(blank=True, max_length=256, null=True, verbose_name='přezdívka'), + ), + ] diff --git a/seminar/migrations/0095_fix_polymorphism.py b/seminar/migrations/0095_fix_polymorphism.py new file mode 100644 index 00000000..bf22c178 --- /dev/null +++ b/seminar/migrations/0095_fix_polymorphism.py @@ -0,0 +1,26 @@ +# Generated by Django 2.2.17 on 2021-07-01 00:44 + +from django.db import migrations + +def fix_all(apps, schema_editor): + ContentType = apps.get_model('contenttypes', 'ContentType') + for modelname in [ + # Problémy: + 'Tema', 'Uloha', 'Clanek', + # Konfery neexistuji, takze ani neni co nastavovat... + # TreeNody: + 'RocnikNode', 'CisloNode', 'MezicisloNode', 'TemaVCisleNode', 'OrgTextNode', 'UlohaZadaniNode', 'PohadkaNode', 'UlohaVzorakNode', 'TextNode', 'CastNode', 'ReseniNode', + ]: + Model = apps.get_model('seminar', modelname) + ct = ContentType.objects.get_for_model(Model) + Model.objects.update(polymorphic_ctype=ct) + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0094_auto_20210701_0149'), + ] + + operations = [ + migrations.RunPython(fix_all, migrations.RunPython.noop), + ] diff --git a/seminar/migrations/0096_fix_zamereni.py b/seminar/migrations/0096_fix_zamereni.py new file mode 100644 index 00000000..84dac0f6 --- /dev/null +++ b/seminar/migrations/0096_fix_zamereni.py @@ -0,0 +1,34 @@ +# Generated by Django 2.2.24 on 2021-07-28 20:17 + +from django.db import migrations + +def fix_zamereni(apps, schema_editor): + ContentType = apps.get_model('contenttypes', 'ContentType') + Problem = apps.get_model('seminar', 'Problem') + ProblemCT = ContentType.objects.get_for_model(Problem) + TaggedItem = apps.get_model('taggit', 'TaggedItem') + + typy_problemu = [ + 'Clanek', + 'Tema', + 'Uloha', + 'Konfera', + ] + for typ in typy_problemu: + Model = apps.get_model('seminar', typ) + ModelCT = ContentType.objects.get_for_model(Model) + # Neumím jednoduše zjistit, které objekty jsou které, tak je prostě procyklím + for obj in Model.objects.all(): + TaggedItem.objects.filter(object_id=obj.problem_ptr.id, content_type=ProblemCT).update(content_type=ModelCT) + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0095_fix_polymorphism'), + ('taggit', '0003_taggeditem_add_unique_index'), + ] + + operations = [ + migrations.RunPython(fix_zamereni), + ] diff --git a/seminar/migrations/0097_auto_20210903_0112.py b/seminar/migrations/0097_auto_20210903_0112.py new file mode 100644 index 00000000..5704c808 --- /dev/null +++ b/seminar/migrations/0097_auto_20210903_0112.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.24 on 2021-09-02 23:12 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0096_fix_zamereni'), + ] + + operations = [ + migrations.AlterField( + model_name='tema', + name='obrazek', + field=models.ImageField(blank=True, null=True, upload_to='', verbose_name='Obrázek na rozcestník'), + ), + ] diff --git a/seminar/migrations/0098_auto_20210906_0305.py b/seminar/migrations/0098_auto_20210906_0305.py new file mode 100644 index 00000000..5071d57c --- /dev/null +++ b/seminar/migrations/0098_auto_20210906_0305.py @@ -0,0 +1,24 @@ +# Generated by Django 2.2.24 on 2021-09-06 01:05 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0097_auto_20210903_0112'), + ] + + operations = [ + migrations.AlterField( + model_name='hodnoceni', + name='body', + field=models.DecimalField(blank=True, decimal_places=1, max_digits=8, null=True, verbose_name='body'), + ), + migrations.AlterField( + model_name='hodnoceni', + name='cislo_body', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='hodnoceni', to='seminar.Cislo', verbose_name='číslo pro body'), + ), + ] diff --git a/seminar/migrations/fix_0058.py b/seminar/migrations/fix_0058.py new file mode 100644 index 00000000..ac36d0a0 --- /dev/null +++ b/seminar/migrations/fix_0058.py @@ -0,0 +1,14 @@ +from django.db import migrations + +sql = "update seminar_problemy set typ = 'uloha' where typ like 'b_uloha_';" + +class Migration(migrations.Migration): + + dependencies = [ + ('seminar', '0058_problem_to_uloha_tema_clanek'), + ] + + operations = [ + migrations.RunSQL(sql, sql), + ] + diff --git a/seminar/models.py b/seminar/models.py index 26e1e230..fdd4de38 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -1,20 +1,26 @@ # -*- coding: utf-8 -*- import os import random +import subprocess +import pathlib +import tempfile +import logging +from django.contrib.sites.shortcuts import get_current_site from django.db import models from django.contrib import auth from django.utils import timezone from django.conf import settings -from django.utils.encoding import python_2_unicode_compatible -from django.utils.encoding import force_unicode +from django.utils.encoding import force_text from django.utils.text import slugify -from django.core.urlresolvers import reverse +from django.urls import reverse, reverse_lazy from django.core.cache import cache -from django.core.exceptions import ObjectDoesNotExist +from django.core.exceptions import ObjectDoesNotExist, ValidationError +from django.contrib.contenttypes.models import ContentType from django.utils.text import get_valid_filename from imagekit.models import ImageSpecField, ProcessedImageField from imagekit.processors import ResizeToFit, Transpose +from django.utils.functional import cached_property from django_countries.fields import CountryField from solo.models import SingletonModel @@ -22,1043 +28,1853 @@ from taggit.managers import TaggableManager from reversion import revisions as reversion -from seminar.utils import roman +from seminar.utils import roman, FirstTagParser # Pro získání úryvku z TextNode +from seminar import treelib -from unidecode import unidecode +from unidecode import unidecode # Používám pro získání ID odkazu (ještě je to někde po někom zakomentované) +from polymorphic.models import PolymorphicModel -class SeminarModelBase(models.Model): +from django.core.mail import EmailMessage +from seminar.utils import aktivniResitele - class Meta: - abstract = True +logger = logging.getLogger(__name__) - def verejne(self): - return False +class SeminarModelBase(models.Model): - def get_absolute_url(self): - return self.verejne_url() # TODO "absolute" + class Meta: + abstract = True - def admin_url(self): - model_name = self.__class__.__name__.lower() - return reverse('admin:seminar_%s_change'%(model_name, ), args=(self.id, )) + def verejne(self): + return False - def verejne_url(self): - return None + # def get_absolute_url(self): + # return "https://" + str(get_current_site(None)) + self.verejne_url() -# -# Mělo by být částečně vytaženo z Aesopa -# viz https://ovvp.mff.cuni.cz/wiki/aesop/export-skol. -# + def admin_url(self): + model_name = self.__class__.__name__.lower() + return reverse('admin:seminar_{}_change'.format(model_name), args=(self.id, )) -@reversion.register(ignore_duplicates=True) -@python_2_unicode_compatible -class Skola(SeminarModelBase): - - class Meta: - db_table = 'seminar_skoly' - verbose_name = u'Škola' - verbose_name_plural = u'Školy' - ordering = ['mesto', 'nazev'] - - # Interní ID - id = models.AutoField(primary_key = True) + # def verejne_url(self): + # return None - # Aesopi ID "izo:..." nebo "aesop:..." - # NULL znamená v exportu do aesopa "ufo" - aesop_id = models.CharField(u'Aesop ID', max_length=32, blank=True, default='', - help_text=u'Aesopi ID typu "izo:..." nebo "aesop:..."') +@reversion.register(ignore_duplicates=True) +class Osoba(SeminarModelBase): + + class Meta: + db_table = 'seminar_osoby' + verbose_name = 'Osoba' + verbose_name_plural = 'Osoby' + ordering = ['prijmeni','jmeno'] + + id = models.AutoField(primary_key = True) - # Staré (do 2015) MAMOPER.MM_RIESITELIA.ID z DAKOSu -- jen u importovaných záznamů - import_dakos_id = models.CharField(u'importované DKSROOT.V_SKOLA.ID', max_length=32, blank=True, default='', - help_text=u'DKSROOT.V_SKOLA.ID z DAKOS importu, jen historický význam') + jmeno = models.CharField('jméno', max_length=256) - # IZO školy (jen české školy) - izo = models.CharField(u'IZO', max_length=32, blank=True, - help_text=u'IZO školy (jen české školy)') + prijmeni = models.CharField('příjmení', max_length=256) - # Celý název školy - nazev = models.CharField(u'název', max_length=256, - help_text=u'Celý název školy') + prezdivka = models.CharField('přezdívka', blank=True, null=True, max_length=256) - # Zkraceny nazev pro zobrazení ve výsledkovce, volitelné. - # Není v Aesopovi, musíme vytvářet sami. - kratky_nazev = models.CharField(u'zkrácený název', max_length=256, blank=True, - help_text="Zkrácený název pro zobrazení ve výsledkovce") + # User, pokud má na webu účet + user = models.OneToOneField(settings.AUTH_USER_MODEL, blank=True, null=True, + verbose_name='uživatel', on_delete=models.DO_NOTHING) - # Ulice může být jen číslo - ulice = models.CharField(u'ulice', max_length=256) + # Pohlaví. Že ho neznáme se snad nestane (a ušetří to práci při programování) + pohlavi_muz = models.BooleanField('pohlaví (muž)', default=False) - mesto = models.CharField(u'město', max_length=256) + email = models.EmailField('e-mail', max_length=256, blank=True, default='') - psc = models.CharField(u'PSČ', max_length=32) + telefon = models.CharField('telefon', max_length=256, blank=True, default='') - # ISO 3166-1 dvojznakovy kod zeme velkym pismem (CZ, SK) - # Ekvivalentní s CharField(max_length=2, default='CZ', ...) - stat = CountryField(u'stát', default='CZ', - help_text=u'ISO 3166-1 kód země velkými písmeny (CZ, SK, ...)') + datum_narozeni = models.DateField('datum narození', blank=True, null=True) - # Jaké vzdělání škpla poskytuje? - je_zs = models.BooleanField(u'základní stupeň', default=True) - je_ss = models.BooleanField(u'střední stupeň', default=True) + # NULL dokud nedali souhlas + datum_souhlasu_udaje = models.DateField('datum souhlasu (údaje)', blank=True, null=True, + help_text='Datum souhlasu se zpracováním osobních údajů') - poznamka = models.TextField(u'neveřejná poznámka', blank=True, - help_text=u'Neveřejná poznámka ke škole (plain text)') + # NULL dokud nedali souhlas + datum_souhlasu_zasilani = models.DateField('datum souhlasu (spam)', blank=True, null=True, + help_text='Datum souhlasu se zasíláním MFF materiálů') - def __str__(self): - return force_unicode(u'%s, %s, %s' % (self.nazev, - self.ulice, - self.mesto)) + # Alespoň odhad (rok či i měsíc) + datum_registrace = models.DateField('datum registrace do semináře', default=timezone.now) + # Ulice může být i jen číslo + ulice = models.CharField('ulice', max_length=256, blank=True, default='') -@reversion.register(ignore_duplicates=True) -@python_2_unicode_compatible -class Resitel(SeminarModelBase): + mesto = models.CharField('město', max_length=256, blank=True, default='') - class Meta: - db_table = 'seminar_resitele' - verbose_name = u'Řešitel' - verbose_name_plural = u'Řešitelé' - ordering = ['prijmeni', 'jmeno'] + psc = models.CharField('PSČ', max_length=32, blank=True, default='') - # Interní ID - id = models.AutoField(primary_key = True) + # ISO 3166-1 dvojznakovy kod zeme velkym pismem (CZ, SK) + # Ekvivalentní s CharField(max_length=2, default='CZ', ...) + stat = CountryField('stát', default='CZ', + help_text='ISO 3166-1 kód země velkými písmeny (CZ, SK, ...)') - jmeno = models.CharField(u'jméno', max_length=256) + poznamka = models.TextField('neveřejná poznámka', blank=True, + help_text='Neveřejná poznámka k osobě (plain text)') - prijmeni = models.CharField(u'příjmení', max_length=256) + foto = ProcessedImageField(verbose_name='Fotografie osoby', + upload_to='image_osoby/velke/%Y/', null = True, blank = True, + help_text = 'Vlož fotografii osoby o libovolné velikosti', + processors=[ + Transpose(Transpose.AUTO), + ResizeToFit(500, 500, upscale=False) + ], + options={'quality': 95}) + foto_male = ImageSpecField(source='foto', + processors=[ + ResizeToFit(200, 200, upscale=False) + ], + options={'quality': 95}) - # User, pokud má na webu účet - user = models.OneToOneField(settings.AUTH_USER_MODEL, blank=True, null=True, verbose_name=u'uživatel') + # má OneToOneField nejvýše s: + # Resitel + # Prijemce + # Organizator - # Pohlaví. Že ho neznáme se snad nestane (a ušetří to práci při programování) - pohlavi_muz = models.BooleanField(u'pohlaví (muž)', default=False) + def plne_jmeno(self): + return '{} {}'.format(self.jmeno, self.prijmeni) - skola = models.ForeignKey(Skola, blank=True, null=True, verbose_name=u'škola') + def inicial_krestni(self): + jmena = self.jmeno.split() + return " ".join(['{}.'.format(jmeno[0]) for jmeno in jmena]) - # Očekávaný rok maturity a vyřazení z aktivních řešitelů - rok_maturity = models.IntegerField(u'rok maturity', blank=True, null=True) - - email = models.EmailField(u'e-mail', max_length=256, blank=True, default='') - - telefon = models.CharField(u'telefon', max_length=256, blank=True, default='') - - datum_narozeni = models.DateField(u'datum narození', blank=True, null=True) - - # NULL dokud nedali souhlas - datum_souhlasu_udaje = models.DateField(u'datum souhlasu (údaje)', blank=True, null=True, - help_text=u'Datum souhlasu se zpracováním osobních údajů') - - # NULL dokud nedali souhlas - datum_souhlasu_zasilani = models.DateField(u'datum souhlasu (spam)', blank=True, null=True, - help_text=u'Datum souhlasu se zasíláním MFF materiálů') - - # Alespoň odhad (rok či i měsíc) - datum_prihlaseni = models.DateField(u'datum přihlášení', default=timezone.now) - - ZASILAT_DOMU = 'domu' - ZASILAT_DO_SKOLY = 'do_skoly' - ZASILAT_NIKAM = 'nikam' - ZASILAT_CHOICES = [ - (ZASILAT_DOMU, u'Domů'), - (ZASILAT_DO_SKOLY, u'Do školy'), - (ZASILAT_NIKAM, u'Nikam'), - ] - zasilat = models.CharField(u'kam zasílat', max_length=32, choices=ZASILAT_CHOICES, blank=False, default=ZASILAT_DOMU) - - # Ulice může být i jen číslo - ulice = models.CharField(u'ulice', max_length=256, blank=True, default='') - - mesto = models.CharField(u'město', max_length=256, blank=True, default='') - - psc = models.CharField(u'PSČ', max_length=32, blank=True, default='') - - # ISO 3166-1 dvojznakovy kod zeme velkym pismem (CZ, SK) - # Ekvivalentní s CharField(max_length=2, default='CZ', ...) - stat = CountryField(u'stát', default='CZ', - help_text=u'ISO 3166-1 kód země velkými písmeny (CZ, SK, ...)') - - poznamka = models.TextField(u'neveřejná poznámka', blank=True, - help_text=u'Neveřejná poznámka k řešiteli (plain text)') - - # Staré (do 2015) MAMOPER.MM_RIESITELIA.ID z DAKOS -- jen u importovaných záznamů - import_mamoper_id = models.CharField(u'importované MM_RIESITELIA.ID', max_length=32, blank=True, default='', - help_text=u'MAMOPER.MM_RIESITELIA.ID z DAKOS importu, jen historický význam') - - def plne_jmeno(self): - return force_unicode(u'%s %s' % (self.jmeno, self.prijmeni)) - - def inicial_krestni(self): - return force_unicode(u'%s.' % (self.jmeno[0])) - - def __str__(self): - return force_unicode(self.plne_jmeno()) - - def export_row(self): - "Slovnik pro pouziti v OVVP (OPMK) exportu" - return { - 'id': self.id, - 'name': self.jmeno, - 'surname': self.prijmeni, - 'gender': 'M' if self.pohlavi_muz else 'F', - 'born': self.datum_narozeni.isoformat() if self.datum_narozeni else '', - 'email': self.email, - 'end-year': self.rok_maturity or '', - - # TODO(gavento): Adresa skoly, kdyz preferuje zasilani tam? - 'street': self.ulice, - 'town': self.mesto, - 'postcode': self.psc, - 'country': self.stat, - - 'spam-flag': 'Y' if self.datum_souhlasu_zasilani else '', - 'spam-date': self.datum_souhlasu_zasilani.isoformat() if self.datum_souhlasu_zasilani else '', - - 'school': self.skola.aesop_id if self.skola else '', - 'school-name': str(self.skola) if self.skola else 'Skola neni znama', - } - - def rocnik(self, rocnik): - """Vrati skolni rocnik resitele pro zadany Rocnik. - Vraci '' pro neznamy rok maturity resitele, Z* pro ekvivalent ZŠ.""" - if self.rok_maturity is None: - return '' - rozdil = 5 - (self.rok_maturity - rocnik.prvni_rok) - if rozdil >= 1: - return str(rozdil) - else: - return 'Z' + str(rozdil + 9) - - def get_titul(self, celkove_body): - "Vrati titul podle zadaneho poctu bodu." - # Tituly na produkci zrušeny. - return '' - if celkove_body < 10: - return '' - elif celkove_body < 20: - return 'Bc.' - elif celkove_body < 50: - return 'Mgr.' - elif celkove_body < 100: - return 'Dr.' - elif celkove_body < 200: - return 'Doc.' - elif celkove_body < 500: - return 'Prof.' - else: - return 'Akad.' + def __str__(self): + return self.plne_jmeno() + # Overridujeme save Osoby, aby když si změní e-mail, aby se projevil i v + # Userovi (a tak se dal poslat mail s resetem hesla) + def save(self, *args, **kwargs): + if self.user is not None: + u = self.user + # U svatého tučňáka, prosím ať tohle funguje. + # (Takhle se kódit asi nemá...) + u.email = self.email + u.save() + super().save() +# +# Mělo by být částečně vytaženo z Aesopa +# viz https://ovvp.mff.cuni.cz/wiki/aesop/export-skol. +# @reversion.register(ignore_duplicates=True) -@python_2_unicode_compatible -class Rocnik(SeminarModelBase): +class Skola(SeminarModelBase): - class Meta: - db_table = 'seminar_rocniky' - verbose_name = u'Ročník' - verbose_name_plural = u'Ročníky' - ordering = ['-rocnik'] + class Meta: + db_table = 'seminar_skoly' + verbose_name = 'Škola' + verbose_name_plural = 'Školy' + ordering = ['mesto', 'nazev'] - # Interní ID - id = models.AutoField(primary_key = True) + # Interní ID + id = models.AutoField(primary_key = True) - prvni_rok = models.IntegerField(u'první rok', db_index=True, unique=True) + # Aesopi ID "izo:..." nebo "aesop:..." + # NULL znamená v exportu do aesopa "ufo" + aesop_id = models.CharField('Aesop ID', max_length=32, blank=True, default='', + help_text='Aesopi ID typu "izo:..." nebo "aesop:..."') - rocnik = models.IntegerField(u'číslo ročníku', db_index=True, unique=True) + # IZO školy (jen české školy) + izo = models.CharField('IZO', max_length=32, blank=True, + help_text='IZO školy (jen české školy)') - exportovat = models.BooleanField(u'export do AESOPa', db_column='exportovat', default=False, - help_text=u'Exportuje se jen podle tohoto flagu (ne veřejnosti), a to jen čísla s veřejnou výsledkovkou') + # Celý název školy + nazev = models.CharField('název', max_length=256, + help_text='Celý název školy') - def __str__(self): - return force_unicode(u'%s (%d/%d)' % (self.rocnik, self.prvni_rok, self.prvni_rok+1)) + # Zkraceny nazev pro zobrazení ve výsledkovce, volitelné. + # Není v Aesopovi, musíme vytvářet sami. + kratky_nazev = models.CharField('zkrácený název', max_length=256, blank=True, + help_text="Zkrácený název pro zobrazení ve výsledkovce") - def roman(self): - return force_unicode(roman(int(self.rocnik))) + # Ulice může být jen číslo + ulice = models.CharField('ulice', max_length=256) - def verejne(self): - return len(self.verejna_cisla()) > 0 - verejne.boolean = True - verejne.short_description = u'Veřejný (jen dle čísel)' - - def verejna_cisla(self): - vc = [c for c in self.cisla.all() if c.verejne()] - vc.sort(key=lambda c: c.cislo) - return vc + mesto = models.CharField('město', max_length=256) - def posledni_verejne_cislo(self): - vc = self.verejna_cisla() - return vc[-1] if vc else None + psc = models.CharField('PSČ', max_length=32) - def verejne_vysledkovky_cisla(self): - vc = list(self.cisla.filter(verejna_vysledkovka=True)) - vc.sort(key=lambda c: c.cislo) - return vc + # ISO 3166-1 dvojznakovy kod zeme velkym pismem (CZ, SK) + # Ekvivalentní s CharField(max_length=2, default='CZ', ...) + stat = CountryField('stát', default='CZ', + help_text='ISO 3166-1 kód země velkými písmeny (CZ, SK, ...)') - def posledni_zverejnena_vysledkovka_cislo(self): - vc = self.verejne_vysledkovky_cisla() - return vc[-1] if vc else None + # Jaké vzdělání škpla poskytuje? + je_zs = models.BooleanField('základní stupeň', default=True) + je_ss = models.BooleanField('střední stupeň', default=True) - def druhy_rok(self): - return self.prvni_rok + 1 + poznamka = models.TextField('neveřejná poznámka', blank=True, + help_text='Neveřejná poznámka ke škole (plain text)') + + kontaktni_osoba = models.ForeignKey(Osoba, verbose_name='Kontaktní osoba', + blank=True, null=True, on_delete=models.SET_NULL) - def verejne_url(self): - return reverse('seminar_rocnik', kwargs={'rocnik': self.rocnik}) + def __str__(self): + return '{}, {}, {}'.format(self.nazev, self.ulice, self.mesto) - @classmethod - def cached_rocnik(cls, r_id): - name = 'rocnik_%s' % (r_id, ) - c = cache.get(name) - if c is None: - c = cls.objects.get(id=r_id) - cache.set(name, c, 300) - return c - +class Prijemce(SeminarModelBase): + class Meta: + db_table = 'seminar_prijemce' + verbose_name = 'příjemce' + verbose_name_plural = 'příjemce' + -def cislo_pdf_filename(self, filename): - rocnik = str(self.rocnik.rocnik) - return os.path.join('cislo', 'pdf', rocnik, '{}-{}.pdf'.format(rocnik, self.cislo)) + # Interní ID + id = models.AutoField(primary_key = True) -@reversion.register(ignore_duplicates=True) -@python_2_unicode_compatible -class Cislo(SeminarModelBase): - - class Meta: - db_table = 'seminar_cisla' - verbose_name = u'Číslo' - verbose_name_plural = u'Čísla' - ordering = ['-rocnik__rocnik', '-cislo'] - - # Interní ID - id = models.AutoField(primary_key = True) - - rocnik = models.ForeignKey(Rocnik, verbose_name=u'ročník', related_name='cisla', db_index=True) - - cislo = models.CharField(u'název čísla', max_length=32, db_index=True, - help_text=u'Většinou jen "1", vyjímečně "7-8", lexikograficky určuje pořadí v ročníku!') - - datum_vydani = models.DateField(u'datum vydání', blank=True, null=True, - help_text=u'Datum vydání finální verze') - - datum_deadline = models.DateField(u'datum deadline', blank=True, null=True, - help_text=u'Datum pro příjem řešení úloh zadaných v tomto čísle') - - datum_deadline_soustredeni = models.DateField( - u'datum deadline soustředění', - blank=True, null=True, - help_text=u'Datum pro příjem řešení pro účast na soustředění') - - verejne_db = models.BooleanField(u'číslo zveřejněno', - db_column='verejne', default=False) - - verejna_vysledkovka = models.BooleanField( - u'zveřejněna výsledkovka', - default=False, - help_text=u'Je-li false u veřejného čísla,\ - není výsledkovka zatím veřejná.') - - poznamka = models.TextField(u'neveřejná poznámka', blank=True, - help_text=u'Neveřejná poznámka k číslu (plain text)') - - pdf = models.FileField(u'pdf', upload_to=cislo_pdf_filename, null=True, blank=True, - help_text=u'Pdf čísla, které si mohou řešitelé stáhnout') - - FAZE_ADMIN = u'admin' - FAZE_TEX = u'tex' - FAZE_NAHRANO = u'nahrano' - FAZE_CHOICES = [ - (FAZE_ADMIN, u'Úpravy na webu'), - (FAZE_TEX, u'Úpravy v TeXu'), - (FAZE_NAHRANO, u'Nahráno na web'), - ] - faze = models.CharField( - u'Fáze vytváření obsahu', - max_length=32, - default=FAZE_ADMIN, - choices=FAZE_CHOICES, - help_text=( - u'Během fáze "{}" se obsah čísla vytváří (a případně ' - u'komentuje) ve webovém rozhraní. Během fáze "{}" už obsah ve ' - u'webovém rozhraní editovat nelze a návrhy na úpravy se píší ' - u'do korekturovátka a zanášejí do gitu. Z něj se pak vygeneruje ' - u'verze pro web a číslo se přepne do fáze "{}", což jen znamená, ' - u'že už nejde automaticky stáhnout obsah pro založení čísla v ' - u'TeXu.' - ).format(FAZE_CHOICES[0][1], FAZE_CHOICES[1][1], FAZE_CHOICES[2][1]) - ) - - def kod(self): - return u'%s.%s' % (self.rocnik.rocnik, self.cislo) - kod.short_description = u'Kód čísla' - - def __str__(self): - # Potenciální DB HOG, pokud by se ročník necachoval - r = Rocnik.cached_rocnik(self.rocnik_id) - return force_unicode(u'%s.%s' % (r.rocnik, self.cislo, )) - - def verejne(self): - return self.verejne_db - verejne.boolean = True - - def verejne_url(self): - return reverse('seminar_cislo', kwargs={'rocnik': self.rocnik.rocnik, 'cislo': self.cislo}) - - def nasledujici(self): - u"Vrací None, pokud je toto poslední" - return self.relativni_v_rocniku(1) - - def predchozi(self): - u"Vrací None, pokud je toto první" - return self.relativni_v_rocniku(-1) - - def relativni_v_rocniku(self, rel_index): - u"Číslo o `index` dále v ročníku. None pokud neexistuje." - cs = self.rocnik.cisla.order_by('cislo').all() - i = list(cs).index(self) + rel_index - if (i < 0) or (i >= len(cs)): - return None - return cs[i] - - @classmethod - def get(cls, rocnik, cislo): - try: - r = Rocnik.objects.get(rocnik=rocnik) - c = r.cisla.get(cislo=cislo) - except ObjectDoesNotExist: - return None - return c + poznamka = models.TextField('neveřejná poznámka', blank=True, + help_text='Neveřejná poznámka k příemci čísel (plain text)') + osoba = models.OneToOneField(Osoba, verbose_name='komu', blank=False, null=False, + help_text='Které osobě či na jakou adresu se mají zasílat čísla', + on_delete=models.CASCADE) -@reversion.register(ignore_duplicates=True) -@python_2_unicode_compatible -class Problem(SeminarModelBase): - - class Meta: - db_table = 'seminar_problemy' - verbose_name = u'Problém' - verbose_name_plural = u'Problémy' - ordering = ['nazev'] - - # Interní ID - id = models.AutoField(primary_key = True) - - # Název - nazev = models.CharField(u'název', max_length=256) - - TYP_ULOHA = 'uloha' - TYP_TEMA = 'tema' - TYP_SERIAL = 'serial' - TYP_KONFERA = 'konfera' - TYP_ORG_CLANEK = 'org-clanek' - TYP_RES_CLANEK = 'res-clanek' - TYP_CHOICES = [ - (TYP_ULOHA, u'Úloha'), - (TYP_TEMA, u'Téma'), - (TYP_SERIAL, u'Seriál'), - (TYP_KONFERA, u'Konfera'), - (TYP_ORG_CLANEK, u'Organizátorský článek'), - (TYP_RES_CLANEK, u'Řešitelský článek'), - ] - typ = models.CharField(u'typ problému', max_length=32, choices=TYP_CHOICES, blank=False, default=TYP_ULOHA) - - STAV_NAVRH = 'navrh' - STAV_ZADANY = 'zadany' - STAV_SMAZANY = 'smazany' - STAV_CHOICES = [ - (STAV_NAVRH, u'Návrh'), - (STAV_ZADANY, u'Zadaný'), - (STAV_SMAZANY, u'Smazaný'), - ] - stav = models.CharField(u'stav problému', max_length=32, choices=STAV_CHOICES, blank=False, default=STAV_NAVRH) - - zamereni = TaggableManager(verbose_name=u'zaměření', help_text='Zaměření M/F/I/O problému, příp. další tagy', blank=True) - - text_org = models.TextField(u'org poznámky (HTML)', blank=True, - help_text=u'Neveřejný návrh úlohy, návrh řešení, text zadání, poznámky ...') - - text_zadani = models.TextField(u'veřejné zadání (HTML)', blank=True, - help_text=u'Veřejný text zadání (HTML)') - - text_reseni = models.TextField(u'veřejné řešení (HTML)', blank=True, - help_text=u'Veřejný text řešení (HTML, u témat i příspěvky a komentáře)') - - autor = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=u'autor problému', related_name='autor_uloh', null=True, blank=True) - - opravovatel = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=u'opravovatel', null=True, blank=True, - related_name='opravovatel_uloh') - - kod = models.CharField(u'lokální kód', max_length=32, blank=True, default='', - help_text=u'Číslo/kód úlohy v čísle nebo kód tématu/článku/seriálu v ročníku') - - cislo_zadani = models.ForeignKey(Cislo, verbose_name=u'číslo zadání', blank=True, null=True, related_name=u'zadane_problemy') - - cislo_reseni = models.ForeignKey(Cislo, verbose_name=u'číslo řešení', blank=True, null=True, related_name=u'resene_problemy', - help_text=u'Číslo s řešením úlohy, jen pro úlohy') - - body = models.DecimalField(max_digits=8, decimal_places=1, verbose_name=u'maximum bodů', blank=True, null=True) - - timestamp = models.DateTimeField(u'vytvořeno', default=timezone.now, blank=True, editable=False) - - # Staré (do 2014) ID problému z DAKOSU -- jen u importovaných záznamů - import_dakos_id = models.CharField(u'importované ID s typem', max_length=32, blank=True, default='', - help_text=(u'ID z importu z DAKOSU s prefixem podle původu: "AZAD:xxx (MAMOPER.MM_AZAD), "' + - u'"DOZ:xxx" (MAMOPER.MM_DOZ), "ZAD:rocnik.cislo.uloha.typ" (MAMOPER.MM_ZADANIA), "ULOHA:xxx" (MAMOPER.MM_ULOHY)')) - - def __str__(self): - return force_unicode(u'%s' % (self.nazev, )) - - def kod_v_rocniku(self): - if self.stav == 'zadany': - if self.typ == self.TYP_ULOHA: - return force_unicode(u"%s.u%s" % (self.cislo_zadani.cislo, self.kod,)) - if self.typ == self.TYP_TEMA: - return force_unicode(u"t%s" % (self.kod,)) - else: - return force_unicode(self.kod) - return u'' - - def nazev_typu(self): - return dict(self.TYP_CHOICES)[self.typ] - - def verejne(self): - return (self.cislo_zadani and self.cislo_zadani.verejne()) - verejne.boolean = True - - def verejne_url(self): - return reverse('seminar_problem', kwargs={'pk': self.id}) - - def admin_url(self): - if self.stav == Problem.STAV_ZADANY: - return reverse('admin:seminar_problemzadany_change', args=(self.id, )) - else: - return reverse('admin:seminar_problemnavrh_change', args=(self.id, )) - - def body_v_zavorce(self): - """Vrať string s body v závorce jsou-li u problému vyplněné, jinak '' - - Je-li desetinná část nulová, nezobrazuj ji. - """ - pocet_bodu = None - if self.body: - b = self.body - pocet_bodu = int(b) if int(b) == b else b - return u"({}\u2009b)".format(pocet_bodu) if self.body else "" + # FIXME: možná chceme něco jako vazbu na osobu XOR školu a počet kusů k zaslání + # FIXME: a možná taky posílání na mail a možná taky přes něj chceme posílat i řešitelům + def __str__(self): + return self.osoba.plne_jmeno() + @reversion.register(ignore_duplicates=True) -@python_2_unicode_compatible -class Reseni(SeminarModelBase): - - class Meta: - db_table = 'seminar_reseni' - verbose_name = u'Řešení' - verbose_name_plural = u'Řešení' - ordering = ['problem_id', 'resitel__prijmeni', 'resitel__jmeno',] - - # Interní ID - id = models.AutoField(primary_key = True) - - problem = models.ForeignKey(Problem, verbose_name=u'problém', related_name='reseni') - - resitel = models.ForeignKey(Resitel, verbose_name=u'řešitel', related_name='reseni') - - body = models.DecimalField(max_digits=8, decimal_places=1, verbose_name=u'body', blank=True, null=True) - - cislo_body = models.ForeignKey(Cislo, verbose_name=u'číslo pro body', related_name='bodovana_reseni', blank=True, null=True) - - timestamp = models.DateTimeField(u'vytvořeno', default=timezone.now, blank=True, editable=False) - - FORMA_PAPIR = 'papir' - FORMA_EMAIL = 'email' - FORMA_UPLOAD = 'upload' - FORMA_CHOICES = [ - (FORMA_PAPIR, u'Papírové řešení'), - (FORMA_EMAIL, u'Emailem'), - (FORMA_UPLOAD, u'Upload přes web'), - ] - forma = models.CharField(u'forma řešení', max_length=16, choices=FORMA_CHOICES, blank=False, default=FORMA_EMAIL) - - poznamka = models.TextField(u'neveřejná poznámka', blank=True, - help_text=u'Neveřejná poznámka k řešení (plain text)') - - def __str__(self): - return force_unicode(u"%s: %s (%sb)" % (self.resitel.plne_jmeno(), self.problem.nazev, self.body)) - # NOTE: Potenciální DB HOG (bez select_related) +class Resitel(SeminarModelBase): - def save(self, *args, **kwargs): - if ((self.cislo_body is None) and (self.problem.cislo_reseni) and - (self.problem.typ == Problem.TYP_ULOHA)): - self.cislo_body = self.problem.cislo_reseni - super(Reseni, self).save(*args, **kwargs) + class Meta: + db_table = 'seminar_resitele' + verbose_name = 'Řešitel' + verbose_name_plural = 'Řešitelé' + ordering = ['osoba'] + + # Interní ID + id = models.AutoField(primary_key = True) + + osoba = models.OneToOneField(Osoba, blank=False, null=True, verbose_name='osoba', + on_delete=models.SET_NULL) # FIXME opravit po prvni migraci + + + skola = models.ForeignKey(Skola, blank=True, null=True, verbose_name='škola', + on_delete=models.SET_NULL) + + # Očekávaný rok maturity a vyřazení z aktivních řešitelů + rok_maturity = models.IntegerField('rok maturity', blank=True, null=True) + + ZASILAT_DOMU = 'domu' + ZASILAT_DO_SKOLY = 'do_skoly' + ZASILAT_NIKAM = 'nikam' + ZASILAT_CHOICES = [ + (ZASILAT_DOMU, 'Domů'), + (ZASILAT_DO_SKOLY, 'Do školy'), + (ZASILAT_NIKAM, 'Nikam'), + ] + + zasilat = models.CharField('kam zasílat', max_length=32, choices=ZASILAT_CHOICES, blank=False, default=ZASILAT_DOMU) + + zasilat_cislo_emailem = models.BooleanField('zasílat číslo emailem', help_text='True pokud chce řešitel dostávat číslo emailem', default=False) + + poznamka = models.TextField('neveřejná poznámka', blank=True, + help_text='Neveřejná poznámka k řešiteli (plain text)') + + + def export_row(self): + "Slovnik pro pouziti v AESOP exportu" + return { + 'id': self.id, + 'name': self.osoba.jmeno, + 'surname': self.osoba.prijmeni, + 'gender': 'M' if self.osoba.pohlavi_muz else 'F', + 'born': self.osoba.datum_narozeni.isoformat() if self.osoba.datum_narozeni else '', + 'email': self.osoba.email, + 'end-year': self.rok_maturity or '', + + 'street': self.osoba.ulice, + 'town': self.osoba.mesto, + 'postcode': self.osoba.psc, + 'country': self.osoba.stat, + + 'spam-flag': 'Y' if self.osoba.datum_souhlasu_zasilani else '', + 'spam-date': self.osoba.datum_souhlasu_zasilani.isoformat() if self.osoba.datum_souhlasu_zasilani else '', + + 'school': self.skola.aesop_id if self.skola else '', + 'school-name': str(self.skola) if self.skola else 'Skola neni znama', + } + + def rocnik(self, rocnik): + """Vrati skolni rocnik resitele pro zadany Rocnik. + Vraci '' pro neznamy rok maturity resitele, Z* pro ekvivalent ZŠ.""" + if self.rok_maturity is None: + return '' + rozdil = 5 - (self.rok_maturity - rocnik.prvni_rok) + if rozdil >= 1: + return str(rozdil) + else: + return 'Z' + str(rozdil + 9) + + def vsechny_body(self): + "Spočítá body odjakživa." + vsechna_reseni = self.reseni_set.all() + vsechna_hodnoceni = Hodnoceni.objects.filter( + reseni__in=vsechna_reseni) + return sum(h.body for h in list(vsechna_hodnoceni) if h.body is not None) + + + def get_titul(self, body=None): + "Vrati titul jako řetězec." + + # Nejprve si zadefinujeme titul + from enum import Enum + from functools import total_ordering + @total_ordering + class Titul(Enum): + """ Třída reprezentující možné tituly. Hodnoty jsou dvojice (dolní hranice, stringifikace). """ + nic = (0, '') + bc = (20, 'Bc.') + mgr = (50, 'Mgr.') + dr = (100, 'Dr.') + doc = (200, 'Doc.') + prof = (500, 'Prof.') + akad = (1000, 'Akad.') + + def __lt__(self, other): + return True if self.value[0] < other.value[0] else False + def __eq__(self, other): # Měla by být implicitní, ale klidně explicitně. + return True if self.value[0] == other.value[0] else False + + def __str__(self): + return self.value[1] + + @classmethod + def z_bodu(cls, body): + aktualni = cls.nic + # TODO: ověřit, že to funguje + for titul in cls: # Kdyžtak použít __members__.items() + if titul.value[0] <= body: + aktualni = titul + else: + break + return aktualni + + # Hledáme body v databázi + # V listopadu 2020 jsme se na filosofické schůzce shodli o změně hranic titulů: + # - body z 25. ročníku a dříve byly shledány dvakrát hodnotnějšími + # - proto se započítávají dvojnásobně a byly posunuté hranice titulů + # - staré tituly se ale nemají odebrat, pokud řešitel v t.č. minulém (26.) ročníku měl titul, má ho mít pořád. + hodnoceni_do_25_rocniku = Hodnoceni.objects.filter(cislo_body__rocnik__rocnik__lte=25,reseni__in=self.reseni_set.all()) + novejsi_hodnoceni = Hodnoceni.objects.filter(reseni__in=self.reseni_set.all()).difference(hodnoceni_do_25_rocniku) + + def body_z_hodnoceni(hh : list): + return sum(h.body for h in hh if h.body is not None) + + stare_body = body_z_hodnoceni(hodnoceni_do_25_rocniku) + if body is None: + nove_body = body_z_hodnoceni(novejsi_hodnoceni) + else: + # Zjistíme, kolik bodů jsou staré, tedy hodnotnější + nove_body = max(0, body - stare_body) # Všechny body nad počet původních hodnotnějších + stare_body = min(stare_body, body) # Skutečný počet hodnotnějších bodů + logicke_body = 2*stare_body + nove_body + + + # Titul se určí následovně: + # - Pokud se řeší body, které jsou starší, než do 26 ročníku (včetně), dáváme tituly postaru. + # - Jinak dáváme tituly po novu... + # - ... ale titul se nesmí odebrat, pokud se zmenšil. + def titul_do_26_rocniku(body): + """ Původní hranice bodů za tituly """ + if body < 10: + return Titul.nic + elif body < 20: + return Titul.bc + elif body < 50: + return Titul.mgr + elif body < 100: + return Titul.dr + elif body < 200: + return Titul.doc + elif body < 500: + return Titul.prof + else: + return Titul.akad + + hodnoceni_do_26_rocniku = Hodnoceni.objects.filter(cislo_body__rocnik__rocnik__lte=26,reseni__in=self.reseni_set.all()) + novejsi_body = body_z_hodnoceni( + Hodnoceni.objects.filter(reseni__in=self.reseni_set.all()) + .difference(hodnoceni_do_26_rocniku) + ) + starsi_body = body_z_hodnoceni(hodnoceni_do_26_rocniku) + if body is not None: + # Ještě z toho vybereme ty správně staré body + novejsi_body = max(0, body - starsi_body) + starsi_body = min(starsi_body, body) + + # Titul pro 26. ročník + stary_titul = titul_do_26_rocniku(starsi_body) + # Titul podle aktuálních pravidel + novy_titul = Titul.z_bodu(logicke_body) + + if novejsi_body == 0: + # Žádné nové body -- titul podle starých pravidel + return str(stary_titul) + return str(max(novy_titul, stary_titul)) + + + def __str__(self): + return self.osoba.plne_jmeno() -def aux_generate_filename(self, filename): - """Pomocná funkce generující ošetřený název souboru v adresáři s datem""" - clean = get_valid_filename( - unidecode(filename.replace('/', '-').replace('\0', '')) - ) - datedir = timezone.now().strftime('%Y-%m') - fname = "%s_%s" % ( - timezone.now().strftime('%Y-%m-%d-%H:%M'), - clean) - return os.path.join(datedir, fname) -# Django neumí jednoduše serializovat partial nebo třídu s __call__ -# (https://docs.djangoproject.com/en/1.8/topics/migrations/), -# neprojdou pak migrace. Takže rozlišení funkcí generujících názvy souboru -# podle adresáře řešíme takto. +@reversion.register(ignore_duplicates=True) +class Rocnik(SeminarModelBase): + class Meta: + db_table = 'seminar_rocniky' + verbose_name = 'Ročník' + verbose_name_plural = 'Ročníky' + ordering = ['-rocnik'] + + # Interní ID + id = models.AutoField(primary_key = True) + + prvni_rok = models.IntegerField('první rok', db_index=True, unique=True) + + rocnik = models.IntegerField('číslo ročníku', db_index=True, unique=True) + + exportovat = models.BooleanField('export do AESOPa', db_column='exportovat', default=False, + help_text='Exportuje se jen podle tohoto flagu (ne veřejnosti),' + ' a to jen čísla s veřejnou výsledkovkou') + + # má OneToOneField s: + # RocnikNode + + def __str__(self): + return '{} ({}/{})'.format(self.rocnik, self.prvni_rok, self.prvni_rok+1) + + # Ročník v římských číslech + def roman(self): + return roman(int(self.rocnik)) + + def verejne(self): + return len(self.verejna_cisla()) > 0 + verejne.boolean = True + verejne.short_description = 'Veřejný (jen dle čísel)' + + def verejna_cisla(self): + vc = [c for c in self.cisla.all() if c.verejne()] + vc.sort(key=lambda c: c.poradi) + return vc + + def posledni_verejne_cislo(self): + vc = self.verejna_cisla() + return vc[-1] if vc else None + + def verejne_vysledkovky_cisla(self): + vc = list(self.cisla.filter(verejna_vysledkovka=True)) + vc.sort(key=lambda c: c.poradi) + return vc + + def posledni_zverejnena_vysledkovka_cislo(self): + vc = self.verejne_vysledkovky_cisla() + return vc[-1] if vc else None + + def druhy_rok(self): + return self.prvni_rok + 1 + + def verejne_url(self): + return reverse('seminar_rocnik', kwargs={'rocnik': self.rocnik}) + + @classmethod + def cached_rocnik(cls, r_id): + name = 'rocnik_%s' % (r_id, ) + c = cache.get(name) + if c is None: + c = cls.objects.get(id=r_id) + cache.set(name, c, 300) + return c + + def save(self, *args, **kwargs): + super().save(*args, **kwargs) + # *Node.save() aktualizuje název *Nodu. + try: + self.rocniknode.save() + except ObjectDoesNotExist: + # Neexistující *Node nemá smysl aktualizovat. + pass -def generate_filename_konfera(self, filename): - return os.path.join( - settings.SEMINAR_KONFERY_DIR, - aux_generate_filename(self, filename) - ) +def cislo_pdf_filename(self, filename): + rocnik = str(self.rocnik.rocnik) + return pathlib.Path('cislo', 'pdf', rocnik, '{}-{}.pdf'.format(rocnik, self.poradi)) +def cislo_png_filename(self, filename): + rocnik = str(self.rocnik.rocnik) + return pathlib.Path('cislo', 'png', rocnik, '{}-{}.png'.format(rocnik, self.poradi)) -def generate_filename(self, filename): - return os.path.join( - settings.SEMINAR_RESENI_DIR, - aux_generate_filename(self, filename) - ) +@reversion.register(ignore_duplicates=True) +class Cislo(SeminarModelBase): + class Meta: + db_table = 'seminar_cisla' + verbose_name = 'Číslo' + verbose_name_plural = 'Čísla' + ordering = ['-rocnik__rocnik', '-poradi'] + + # Interní ID + id = models.AutoField(primary_key = True) + + rocnik = models.ForeignKey(Rocnik, verbose_name='ročník', related_name='cisla', + db_index=True,on_delete=models.PROTECT) + + poradi = models.CharField('název čísla', max_length=32, db_index=True, + help_text='Většinou jen "1", vyjímečně "7-8", lexikograficky určuje pořadí v ročníku!') + + datum_vydani = models.DateField('datum vydání', blank=True, null=True, + help_text='Datum vydání finální verze') + + datum_deadline_soustredeni = models.DateField( + 'datum deadline soustředění', + blank=True, null=True, + help_text='Datum pro příjem řešení pro účast na soustředění') + + datum_preddeadline = models.DateField('datum předdeadline', blank=True, null=True, + help_text='Datum pro příjem řešení, která se otisknou v dalším čísle') + + datum_deadline = models.DateField('datum deadline', blank=True, null=True, + help_text='Datum pro příjem řešení úloh zadaných v tomto čísle') + + verejne_db = models.BooleanField('číslo zveřejněno', + db_column='verejne', default=False) + + verejna_vysledkovka = models.BooleanField( + 'zveřejněna výsledkovka', + default=False, + help_text='Je-li false u veřejného čísla, ' + 'není výsledkovka zatím veřejná.') + + poznamka = models.TextField('neveřejná poznámka', blank=True, + help_text='Neveřejná poznámka k číslu (plain text)') + + pdf = models.FileField('pdf', upload_to=cislo_pdf_filename, null=True, blank=True, + help_text='PDF čísla, které si mohou řešitelé stáhnout') + + titulka_nahled = models.ImageField('Obrázek titulní strany', upload_to=cislo_png_filename, null=True, blank=True, + help_text='Obrázek titulní strany, generuje se automaticky') + + # má OneToOneField s: + # CisloNode + + def kod(self): + return '%s.%s' % (self.rocnik.rocnik, self.poradi) + kod.short_description = 'Kód čísla' + + def __str__(self): + # Potenciální DB HOG, pokud by se ročník necachoval + r = Rocnik.cached_rocnik(self.rocnik_id) + return '{}.{}'.format(r.rocnik, self.poradi) + + def verejne(self): + return self.verejne_db + verejne.boolean = True + + def verejne_url(self): + return reverse('seminar_cislo', kwargs={'rocnik': self.rocnik.rocnik, 'cislo': self.poradi}) + + def absolute_url(self): + return "https://" + str(get_current_site(None)) + self.verejne_url() + + def nasledujici(self): + "Vrací None, pokud je toto poslední" + return self.relativni_v_rocniku(1) + + def predchozi(self): + "Vrací None, pokud je toto první" + return self.relativni_v_rocniku(-1) + + def relativni_v_rocniku(self, rel_index): + "Číslo o `index` dále v ročníku. None pokud neexistuje." + cs = self.rocnik.cisla.order_by('cislo').all() + i = list(cs).index(self) + rel_index + if (i < 0) or (i >= len(cs)): + return None + return cs[i] + + def vygeneruj_nahled(self): + VYSKA = 594 + sirka = int(VYSKA*210/297) + if not self.pdf: + return + + + # Pokud obrázek neexistuje nebo není aktuální, vytvoř jej + if not self.titulka_nahled or os.path.getmtime(self.titulka_nahled.path) < os.path.getmtime(self.pdf.path): + png_filename = pathlib.Path(tempfile.mkdtemp(), 'nahled.png') + + subprocess.run([ + "gs", + "-sstdout=%stderr", + "-dSAFER", + "-dNOPAUSE", + "-dBATCH", + "-dNOPROMPT", + "-sDEVICE=png16m", + "-r300x300", + "-dFirstPage=1d", + "-dLastPage=1d", + "-sOutputFile=" + str(png_filename), + "-f%s" % self.pdf.path + ], + check=True, + capture_output=True + ) + + with open(png_filename,'rb') as f: + self.titulka_nahled.save('',f,True) + + png_filename.unlink() + png_filename.parent.rmdir() + + + + @classmethod + def get(cls, rocnik, cislo): + try: + r = Rocnik.objects.get(rocnik=rocnik) + c = r.cisla.get(poradi=cislo) + except ObjectDoesNotExist: + return None + return c + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.__original_verejne = self.verejne_db + + def posli_cislo_mailem(self): + # parametry e-mailu + odkaz = self.absolute_url() + + poslat_z_mailu = 'zadani@mam.mff.cuni.cz' + predmet = 'Vyšlo číslo {}'.format(self.kod()) + text_mailu = 'Ahoj,\n' \ + 'na adrese {} najdete nejnovější číslo.\n' \ + 'Vaše M&M\n'.format(odkaz) + + # Prijemci e-mailu + emaily = map(lambda r: r.osoba.email, filter(lambda r: r.zasilat_cislo_emailem, aktivniResitele(self))) + + if not settings.POSLI_MAILOVOU_NOTIFIKACI: + print("Poslal bych upozornění na tyto adresy: ", " ".join(emaily)) + return + + email = EmailMessage( + subject=predmet, + body=text_mailu, + from_email=poslat_z_mailu, + bcc=list(emaily) + #bcc = příjemci skryté kopie + ) + + email.send() + + def save(self, *args, **kwargs): + super().save(*args, **kwargs) + self.vygeneruj_nahled() + # Při zveřejnění pošle mail + if self.verejne_db and not self.__original_verejne: + self.posli_cislo_mailem() + # *Node.save() aktualizuje název *Nodu. + try: + self.cislonode.save() + except ObjectDoesNotExist: + # Neexistující *Node nemá smysl aktualizovat, ale je potřeba ho naopak vyrobit + logger.warning(f'Číslo {self} nemělo ČísloNode, vyrábím…') + CisloNode.objects.create(cislo=self) + + def clean(self): + # Finální deadline má být až poslední a je povinný, pokud nějaký deadline existuje. + # Existence: + if self.datum_deadline is None and (self.datum_preddeadline is not None or self.datum_deadline_soustredeni is not None): + raise ValidationError({'datum_deadline': "Číslo musí mít finální deadline, pokud má nějaké deadliny"}) + if self.datum_deadline is not None: + if self.datum_preddeadline is not None and self.datum_preddeadline > self.datum_deadline: + raise ValidationError({'datum_preddeadline': "Předdeadline musí předcházet finálnímu deadlinu"}) + if self.datum_deadline_soustredeni is not None and self.datum_deadline_soustredeni > self.datum_deadline: + raise ValidationError({'datum_deadline_soustredeni': "Soustřeďkový deadline musí předcházet finálnímu deadlinu"}) @reversion.register(ignore_duplicates=True) -@python_2_unicode_compatible -class PrilohaReseni(SeminarModelBase): +class Organizator(SeminarModelBase): +# zmena dedicnosti z models.Model na SeminarModelBase, potencialni vznik bugu + + osoba = models.OneToOneField(Osoba, verbose_name='osoba', related_name='org', + help_text='osobní údaje organizátora', null=True, blank=False, + on_delete=models.SET_NULL) #FIXME opravit po migraci + + vytvoreno = models.DateTimeField( + 'Vytvořeno', + default=timezone.now, + blank=True, + editable=False + ) + + organizuje_od = models.DateTimeField('Organizuje od', blank=True, null=True) + + organizuje_do = models.DateTimeField('Organizuje do', blank=True, null=True) + + studuje = models.CharField('Studium aj.', max_length = 256, + null = True, blank = True, + help_text="Např. 'Studuje Obecnou fyziku (Bc.), 3. ročník', " + "'Vystudovala Diskrétní modely a algoritmy (Mgr.)' nebo " + "'Přednáší na MFF'") + + strucny_popis_organizatora = models.TextField('Stručný popis organizátora', + null = True, blank = True) + + skola = models.CharField('Škola, kterou studuje', max_length = 256, null=True, blank=True, + help_text="Škola, např. MFF, VŠCHT, VUT, ... prostě aby se nemuselo psát do studuje" + "školu, ale jen obor, možnost zobrazit zvlášť") + + def clean(self): + if self.organizuje_od and self.organizuje_do and (self.organizuje_od > self.organizuje_do): + raise ValidationError("Organizátor nemůže skončit s organizováním dříve než začal!") + super().clean() + + def __str__(self): + if self.osoba.prezdivka: + return "{} '{}' {}".format(self.osoba.jmeno, + self.osoba.prezdivka, + self.osoba.prijmeni) + else: + return "{} {}".format(self.osoba.jmeno, self.osoba.prijmeni) + + class Meta: + verbose_name = 'Organizátor' + verbose_name_plural = 'Organizátoři' + # Řadí aktivní orgy na začátek, pod tím v pořadí od nejstarších neaktivní orgy. + # TODO: Chtěl bych spíš mít nejstarší orgy dole. + # TODO: Zohledňovat přezdívky? + # TODO: Sjednotit s tím, jak se řadí organizátoři v seznau orgů na webu + ordering = ['-organizuje_do', 'osoba__jmeno', 'osoba__prijmeni'] - class Meta: - db_table = 'seminar_priloha_reseni' - verbose_name = u'Příloha řešení' - verbose_name_plural = u'Přílohy řešení' - ordering = ['reseni', 'timestamp'] +@reversion.register(ignore_duplicates=True) +class Soustredeni(SeminarModelBase): - # Interní ID - id = models.AutoField(primary_key = True) + class Meta: + db_table = 'seminar_soustredeni' + verbose_name = 'Soustředění' + verbose_name_plural = 'Soustředění' + ordering = ['-rocnik__rocnik', '-datum_zacatku'] - reseni = models.ForeignKey(Reseni, verbose_name=u'řešení', related_name='prilohy') + # Interní ID + id = models.AutoField(primary_key = True) - timestamp = models.DateTimeField(u'vytvořeno', default=timezone.now, blank=True, editable=False) + rocnik = models.ForeignKey(Rocnik, verbose_name='ročník', related_name='soustredeni', + on_delete=models.PROTECT) - soubor = models.FileField(u'soubor', upload_to = generate_filename) + datum_zacatku = models.DateField('datum začátku', blank=True, null=True, + help_text='První den soustředění') - poznamka = models.TextField(u'neveřejná poznámka', blank=True, - help_text=u'Neveřejná poznámka k příloze řešení (plain text), např. o původu') + datum_konce = models.DateField('datum konce', blank=True, null=True, + help_text='Poslední den soustředění') - def __str__(self): - return force_unicode(self.soubor) + verejne_db = models.BooleanField('soustředění zveřejněno', db_column='verejne', default=False) + misto = models.CharField('místo soustředění', max_length=256, blank=True, default='', + help_text='Místo (název obce, volitelně též objektu') -@python_2_unicode_compatible -class Pohadka(SeminarModelBase): - u"""Kus pohádky před/za úlohou v čísle""" + ucastnici = models.ManyToManyField(Resitel, verbose_name='účastníci soustředění', + help_text='Seznam účastníků soustředění', through='Soustredeni_Ucastnici') - class Meta: - db_table = 'seminar_pohadky' - verbose_name = u'Pohádka' - verbose_name_plural = u'Pohádky' - ordering = ['uloha__cislo_zadani', 'uloha__kod', '-pred'] + organizatori = models.ManyToManyField(Organizator, + verbose_name='Organizátoři soustředění', + help_text='Seznam organizátorů soustředění', + through='Soustredeni_Organizatori') - # Interní ID - id = models.AutoField(primary_key=True) + text = models.TextField('text k soustředění (HTML)', blank=True, default='') - text = models.TextField(u'Text pohádky') - uloha = models.ForeignKey( - Problem, - verbose_name=u'Úloha', - related_name='pohadky' - ) + TYP_JARNI = 'jarni' + TYP_PODZIMNI = 'podzimni' + TYP_VIKEND = 'vikend' + TYP_CHOICES = [ + (TYP_JARNI, 'Jarní soustředění'), + (TYP_PODZIMNI, 'Podzimní soustředění'), + (TYP_VIKEND, 'Víkendový sraz'), + ] + typ = models.CharField('typ akce', max_length=16, choices=TYP_CHOICES, blank=False, default=TYP_PODZIMNI) - # Kusů pohádky je v čísle obvykle o 1 více, než úloh. Jeden bude za úlohou - # místo před ní. - pred = models.BooleanField(u'Před úlohou', default=True) + exportovat = models.BooleanField('export do AESOPa', db_column='exportovat', default=False, + help_text='Exportuje se jen podle tohoto flagu (ne veřejnosti)') - autor = models.ForeignKey( - settings.AUTH_USER_MODEL, - verbose_name="Autor pohádky", + def __str__(self): + return '{} ({})'.format(self.misto, self.datum_zacatku) - # Při nahrávání z TeXu není vyplnění vyžadováno, v adminu je - null=True, - blank=False - ) + def verejne(self): + return self.verejne_db + verejne.boolean = True - timestamp = models.DateTimeField( - u'Vytvořeno', - default=timezone.now, - blank=True, - editable=False - ) + def verejne_url(self): + #return reverse('seminar_soustredeni', kwargs={'pk': self.id}) + return reverse('seminar_seznam_soustredeni') - def __str__(self): - uryvek = self.text if len(self.text) < (50-3) else self.text[:50]+"..." - return force_unicode(uryvek) @reversion.register(ignore_duplicates=True) -class Prispevek(SeminarModelBase): - problem = models.ForeignKey(Problem, verbose_name='Problém') # TODO autokompleet - nazev = models.CharField('Název', max_length=200) - reseni = models.OneToOneField(Reseni, verbose_name='Řešení', - blank = True, null = True) - text_org = models.TextField('Orgovský text', blank = True, null = True) - text_resitel = models.TextField('Řešitelský text', blank = True, null = True) - zverejnit = models.BooleanField('Zveřejnit?') - - class Meta: - verbose_name = 'Příspěvek k problému' - verbose_name_plural = 'Příspěvky k problémům' - - def __unicode__(self): - if self.reseni: - return force_unicode(self.nazev) + ' (' + \ - force_unicode(self.reseni.resitel) + ') ' - else: - return force_unicode(self.nazev) + ' ' - +# Pozor na následující řádek. *Nekrmit, asi kouše!* +class Problem(SeminarModelBase,PolymorphicModel): + + class Meta: + # Není abstraktní, protože se na něj jinak nedají dělat ForeignKeys. + # TODO: Udělat to polymorfní (pomocí django-polymorphic), abychom dostali + # po těch vazbách přímo tu úlohu/témátko vč. fieldů, které nejsou součástí + # modelu Problem? + + #abstract = True + db_table = 'seminar_problemy' + verbose_name = 'Problém' + verbose_name_plural = 'Problémy' + ordering = ['nazev'] + + # Interní ID + id = models.AutoField(primary_key = True) + + # Název + nazev = models.CharField('název', max_length=256) # Zveřejnitelný na stránky + + # Problém má podproblémy + nadproblem = models.ForeignKey('self', verbose_name='nadřazený problém', + related_name='podproblem', null=True, blank=True, + on_delete=models.SET_NULL) + + STAV_NAVRH = 'navrh' + STAV_ZADANY = 'zadany' + STAV_VYRESENY = 'vyreseny' + STAV_SMAZANY = 'smazany' + STAV_CHOICES = [ + (STAV_NAVRH, 'Návrh'), + (STAV_ZADANY, 'Zadaný'), + (STAV_VYRESENY, 'Vyřešený'), + (STAV_SMAZANY, 'Smazaný'), + ] + stav = models.CharField('stav problému', max_length=32, choices=STAV_CHOICES, blank=False, default=STAV_NAVRH) + # Téma je taky Problém, takže má stavy, "zadané" témátko je aktuálně otevřené a dá se k němu něco poslat (řešení nebo článek) + + zamereni = TaggableManager(verbose_name='zaměření', + help_text='Zaměření M/F/I/O problému, příp. další tagy', blank=True) + + poznamka = models.TextField('org poznámky (HTML)', blank=True, + help_text='Neveřejný návrh úlohy, návrh řešení, text zadání, poznámky ...') + + autor = models.ForeignKey(Organizator, verbose_name='autor problému', + related_name='autor_problemu_%(class)s', null=True, blank=True, + on_delete=models.SET_NULL) + + garant = models.ForeignKey(Organizator, verbose_name='garant zadaného problému', + related_name='garant_problemu_%(class)s', null=True, blank=True, + on_delete=models.SET_NULL) + + opravovatele = models.ManyToManyField(Organizator, verbose_name='opravovatelé', + blank=True, related_name='opravovatele_%(class)s') + + kod = models.CharField('lokální kód', max_length=32, blank=True, default='', + help_text='Číslo/kód úlohy v čísle nebo kód tématu/článku/seriálu v ročníku') + + + vytvoreno = models.DateTimeField('vytvořeno', default=timezone.now, blank=True, editable=False) + + + def __str__(self): + return self.nazev + + # Implicitini implementace, jednotlivé dědící třídy si přepíšou + @cached_property + def kod_v_rocniku(self): + if self.stav == 'zadany': + if self.nadproblem: + return self.nadproblem.kod_v_rocniku+".{}".format(self.kod) + return str(self.kod) + return '' + +# def verejne(self): +# # aktuálně podle stavu problému +# # FIXME pro některé problémy možná chceme override +# # FIXME vrací veřejnost čistě problému, nezávisle na čísle, ve kterém je. +# # Je to tak správně? Podle aktuální představy ano. +# stav_verejny = False +# if self.stav == 'zadany' or self.stav == 'vyreseny': +# stav_verejny = True +# print("stav_verejny: {}".format(stav_verejny)) +# +# cislo_verejne = False +# cislonode = self.cislo_node() +# if cislonode is None: +# # problém nemá vlastní node, veřejnost posuzujeme jen podle stavu +# print("empty node") +# return stav_verejny +# else: +# cislo_zadani = cislonode.cislo +# if (cislo_zadani and cislo_zadani.verejne()): +# print("cislo: {}".format(cislo_zadani)) +# cislo_verejne = True +# print("stav_verejny: {}".format(stav_verejny)) +# print("cislo_verejne: {}".format(cislo_verejne)) +# return (stav_verejny and cislo_verejne) +# verejne.boolean = True + + def verejne_url(self): + return reverse('seminar_problem', kwargs={'pk': self.id}) + + def admin_url(self): + return reverse('admin:seminar_problem_change', args=(self.id, )) + +# FIXME - k úloze + def body_v_zavorce(self): + """Vrať string s body v závorce jsou-li u problému vyplněné, jinak '' + + Je-li desetinná část nulová, nezobrazuj ji. + """ + pocet_bodu = None + if self.body: + b = self.body + pocet_bodu = int(b) if int(b) == b else b + return "({}\u2009b)".format(pocet_bodu) if self.body else "" + +class Tema(Problem): + class Meta: + db_table = 'seminar_temata' + verbose_name = 'Téma' + verbose_name_plural = 'Témata' + + TEMA_TEMA = 'tema' + TEMA_SERIAL = 'serial' + TEMA_CHOICES = [ + (TEMA_TEMA, 'Téma'), + (TEMA_SERIAL, 'Seriál'), + ] + tema_typ = models.CharField('Typ tématu', max_length=16, choices=TEMA_CHOICES, + blank=False, default=TEMA_TEMA) + + rocnik = models.ForeignKey(Rocnik, verbose_name='ročník',related_name='temata',blank=True, null=True, + on_delete=models.PROTECT) + + abstrakt = models.TextField('Abstrakt na rozcestník', blank=True) + obrazek = models.ImageField('Obrázek na rozcestník', null=True, blank=True) + + @cached_property + def kod_v_rocniku(self): + if self.stav == 'zadany': + if self.nadproblem: + return self.nadproblem.kod_v_rocniku+".t{}".format(self.kod) + return "t{}".format(self.kod) + return '' + + def save(self, *args, **kwargs): + super().save(*args, **kwargs) + # *Node.save() aktualizuje název *Nodu. + for tvcn in self.temavcislenode_set.all(): + tvcn.save() + + def cislo_node(self): + tema_node_set = self.temavcislenode_set.all() + tema_cisla_vyskyt = [] + for tn in tema_node_set: + tema_cisla_vyskyt.append( + treelib.get_upper_node_of_type(tn, CisloNode).cislo) + tema_cisla_vyskyt.sort(key=lambda x:x.datum_vydani) + prvni_zadani = tema_cisla_vyskyt[0] + return prvni_zadani.cislonode + +class Clanek(Problem): + class Meta: + db_table = 'seminar_clanky' + verbose_name = 'Článek' + verbose_name_plural = 'Články' + + cislo = models.ForeignKey(Cislo, blank=True, null=True, on_delete=models.PROTECT, + verbose_name='číslo vydání', related_name='vydane_clanky') + + @cached_property + def kod_v_rocniku(self): + if self.stav == 'zadany': +# Nemělo by být potřeba +# if self.nadproblem: +# return self.nadproblem.kod_v_rocniku+".c{}".format(self.kod) + return "c{}".format(self.kod) + return '' + + def node(self): + return None + +class Text(SeminarModelBase): + class Meta: + db_table = 'seminar_texty' + verbose_name = 'text' + verbose_name_plural = 'texty' + + na_web = models.TextField('text na web', blank=True, + help_text='Text ke zveřejnění na webu') + + do_cisla = models.TextField('text do čísla', blank=True, + help_text='Text ke zveřejnění v čísle') + + # má OneToOneField s: + # Reseni (je u něj jako reseni_cele) + + # obrázky mají návaznost opačným směrem (vazba z druhé strany) + + def save(self, *args, **kwargs): + super().save(*args, **kwargs) + # *Node.save() aktualizuje název *Nodu. + for tn in self.textnode_set.all(): + tn.save() + + def __str__(self): + return str(self.na_web)[:20] + +class Uloha(Problem): + class Meta: + db_table = 'seminar_ulohy' + verbose_name = 'Úloha' + verbose_name_plural = 'Úlohy' + + cislo_zadani = models.ForeignKey(Cislo, verbose_name='číslo zadání', blank=True, + null=True, related_name='zadane_ulohy', on_delete=models.PROTECT) + + cislo_deadline = models.ForeignKey(Cislo, verbose_name='číslo deadlinu', blank=True, + null=True, related_name='deadlinove_ulohy', on_delete=models.PROTECT) + + cislo_reseni = models.ForeignKey(Cislo, verbose_name='číslo řešení', blank=True, + null=True, related_name='resene_ulohy', + help_text='Číslo s řešením úlohy, jen pro úlohy', + on_delete=models.PROTECT) + + max_body = models.DecimalField(max_digits=8, decimal_places=1, verbose_name='maximum bodů', + blank=True, null=True) + + # má OneToOneField s: + # UlohaZadaniNode + # UlohaVzorakNode + + @cached_property + def kod_v_rocniku(self): + if self.stav == 'zadany': + name="{}.u{}".format(self.cislo_zadani.poradi,self.kod) + if self.nadproblem: + return self.nadproblem.kod_v_rocniku+name + return name + return '' + + def save(self, *args, **kwargs): + super().save(*args, **kwargs) + # *Node.save() aktualizuje název *Nodu. + try: + self.ulohazadaninode.save() + except ObjectDoesNotExist: + # Neexistující *Node nemá smysl aktualizovat. + pass + try: + self.ulohavzoraknode.save() + except ObjectDoesNotExist: + # Neexistující *Node nemá smysl aktualizovat. + pass + + def cislo_node(self): + zadani_node = self.ulohazadaninode + return treelib.get_upper_node_of_type(zadani_node, CisloNode) @reversion.register(ignore_duplicates=True) -@python_2_unicode_compatible -class Organizator(models.Model): - user = models.OneToOneField(settings.AUTH_USER_MODEL, verbose_name='Osoba', - help_text = 'Vyber účet spřažený s organizátorem.') - prezdivka = models.CharField('Přezdívka', max_length = 32, - null = True, blank = True) - organizuje_od_roku = models.IntegerField('Organizuje od roku', - null = True, blank = True) - organizuje_do_roku = models.IntegerField('Organizuje do roku', - null = True, blank = True) - studuje = models.CharField('Studium aj.', max_length = 256, - null = True, blank = True, - help_text="Např. 'Studuje Obecnou fyziku (Bc.), 3. ročník', " - "'Vystudovala Diskrétní modely a algoritmy (Mgr.)' nebo " - "'Přednáší na MFF'") - strucny_popis_organizatora = models.TextField('Stručný popis organizátora', - null = True, blank = True) - foto = ProcessedImageField(verbose_name='Fotografie organizátora', - upload_to='image_organizatori/velke/%Y/', null = True, blank = True, - help_text = 'Vlož fotografii organizátora o libovolné velikosti', - processors=[ - Transpose(Transpose.AUTO), - ResizeToFit(500, 500, upscale=False) - ], - options={'quality': 95}) - foto_male = ImageSpecField(source='foto', - processors=[ - ResizeToFit(200, 200, upscale=False) - ], - options={'quality': 95}) - - def __str__(self): - if self.prezdivka: - return u"%s '%s' %s" % (self.user.first_name, - self.prezdivka, - self.user.last_name) - else: - return u"%s %s" % (self.user.first_name, self.user.last_name) - - class Meta: - verbose_name = 'Organizátor' - verbose_name_plural = 'Organizátoři' - # Řadí aktivní orgy na začátek, pod tím v pořadí od nejstarších neaktivní orgy. - # TODO: Chtěl bych spíš mít nejstarší orgy dole. - # TODO: Zohledňovat přezdívky? - # TODO: Sjednotit s tím, jak se řadí organizátoři v seznau orgů na webu - ordering = ['-organizuje_do_roku', 'user__first_name', 'user__last_name'] +class Reseni(SeminarModelBase): + class Meta: + db_table = 'seminar_reseni' + verbose_name = 'Řešení' + verbose_name_plural = 'Řešení' + #ordering = ['-problem', 'resitele'] # FIXME: Takhle to chceme, ale nefunguje to. + ordering = ['-cas_doruceni'] -@reversion.register(ignore_duplicates=True) -@python_2_unicode_compatible -class Soustredeni(SeminarModelBase): + # Interní ID + id = models.AutoField(primary_key = True) - class Meta: - db_table = 'seminar_soustredeni' - verbose_name = u'Soustředění' - verbose_name_plural = u'Soustředění' - ordering = ['-rocnik__rocnik', '-datum_zacatku'] + # Ke každé dvojici řešní a problém existuje nanejvýš jedno hodnocení, doplnění vazby. + problem = models.ManyToManyField(Problem, verbose_name='problém', help_text='Problém', + through='Hodnoceni') - # Interní ID - id = models.AutoField(primary_key = True) + resitele = models.ManyToManyField(Resitel, verbose_name='autoři řešení', + help_text='Seznam autorů řešení', through='Reseni_Resitele') - rocnik = models.ForeignKey(Rocnik, verbose_name=u'ročník', related_name='soustredeni') - datum_zacatku = models.DateField(u'datum začátku', blank=True, null=True, - help_text=u'První den soustředění') + cas_doruceni = models.DateTimeField('čas_doručení', default=timezone.now, blank=True) - datum_konce = models.DateField(u'datum konce', blank=True, null=True, - help_text=u'Poslední den soustředění') + FORMA_PAPIR = 'papir' + FORMA_EMAIL = 'email' + FORMA_UPLOAD = 'upload' + FORMA_CHOICES = [ + (FORMA_PAPIR, 'Papírové řešení'), + (FORMA_EMAIL, 'Emailem'), + (FORMA_UPLOAD, 'Upload přes web'), + ] + forma = models.CharField('forma řešení', max_length=16, choices=FORMA_CHOICES, blank=False, + default=FORMA_EMAIL) - verejne_db = models.BooleanField(u'soustředění zveřejněno', db_column='verejne', default=False) + text_cely = models.OneToOneField('ReseniNode', verbose_name='Plná verze textu řešení', + blank=True, null=True, related_name="reseni_cely_set", + on_delete=models.PROTECT) - misto = models.CharField(u'místo soustředění', max_length=256, blank=True, default='', - help_text=u'Místo (název obce, volitelně též objektu') + poznamka = models.TextField('neveřejná poznámka', blank=True, + help_text='Neveřejná poznámka k řešení (plain text)') - ucastnici = models.ManyToManyField(Resitel, verbose_name=u'účastníci soustředění', - help_text=u'Seznam účastníků soustředění', through='Soustredeni_Ucastnici') + zverejneno = models.BooleanField('řešení zveřejněno', default=False, + help_text='Udává, zda je řešení zveřejněno') - organizatori = models.ManyToManyField(Organizator, - verbose_name=u'Organizátoři soustředění', - help_text=u'Seznam organizátorů soustředění', - through='Soustredeni_Organizatori') + def verejne_url(self): + return str(reverse_lazy('odevzdavatko_detail_reseni', args=[self.id])) - text = models.TextField(u'text k soustředění (HTML)', blank=True, default='') + def absolute_url(self): + return "https://" + str(get_current_site(None)) + self.verejne_url() - TYP_JARNI = 'jarni' - TYP_PODZIMNI = 'podzimni' - TYP_VIKEND = 'vikend' - TYP_CHOICES = [ - (TYP_JARNI, u'Jarní soustředění'), - (TYP_PODZIMNI, u'Podzimní soustředění'), - (TYP_VIKEND, u'Víkendový sraz'), - ] - typ = models.CharField(u'typ akce', max_length=16, choices=TYP_CHOICES, blank=False, default=TYP_PODZIMNI) + # má OneToOneField s: + # Konfera - exportovat = models.BooleanField(u'export do AESOPa', db_column='exportovat', default=False, - help_text=u'Exportuje se jen podle tohoto flagu (ne veřejnosti)') + # má ForeignKey s: + # Hodnoceni - def __str__(self): - return force_unicode(u'%s (%s)' % (self.misto, self.datum_zacatku)) + def __str__(self): + return "{}({}): {}({})".format(self.resitele.first(),len(self.resitele.all()), self.problem.first() ,len(self.problem.all())) + # NOTE: Potenciální DB HOG (bez select_related) - def verejne(self): - return self.verejne_db - verejne.boolean = True +## Pravdepodobne uz nebude potreba: +# def save(self, *args, **kwargs): +# if ((self.cislo_body is None) and (self.problem.cislo_reseni) and +# (self.problem.typ == Problem.TYP_ULOHA)): +# self.cislo_body = self.problem.cislo_reseni +# super(Reseni, self).save(*args, **kwargs) - def verejne_url(self): - #return reverse('seminar_soustredeni', kwargs={'pk': self.id}) - return reverse('seminar_seznam_soustredeni') +class Hodnoceni(SeminarModelBase): + class Meta: + db_table = 'seminar_hodnoceni' + verbose_name = 'Hodnocení' + verbose_name_plural = 'Hodnocení' + + # Interní ID + id = models.AutoField(primary_key = True) -@reversion.register(ignore_duplicates=True) -@python_2_unicode_compatible -class Soustredeni_Ucastnici(models.Model): + body = models.DecimalField(max_digits=8, decimal_places=1, verbose_name='body', + blank=True, null=True) - class Meta: - db_table = 'seminar_soustredeni_ucastnici' - verbose_name = u'Účast na soustředění' - verbose_name_plural = u'Účasti na soustředění' - ordering = ['soustredeni', 'resitel'] + cislo_body = models.ForeignKey(Cislo, verbose_name='číslo pro body', + related_name='hodnoceni', blank=True, null=True, on_delete=models.PROTECT) - # Interní ID - id = models.AutoField(primary_key = True) + reseni = models.ForeignKey(Reseni, verbose_name='řešení', on_delete=models.CASCADE) - resitel = models.ForeignKey(Resitel, verbose_name=u'řešitel') + problem = models.ForeignKey(Problem, verbose_name='problém', + related_name='hodnoceni', on_delete=models.PROTECT) - soustredeni = models.ForeignKey(Soustredeni, verbose_name=u'soustředění') + def __str__(self): + return "{}, {}, {}".format(self.problem, self.reseni, self.body) - poznamka = models.TextField(u'neveřejná poznámka', blank=True, - help_text=u'Neveřejná poznámka k účasti (plain text)') - def __str__(self): - return force_unicode(u'%s na %s' % (self.resitel, self.soustredeni, )) - # NOTE: Poteciální DB HOG bez select_related -@reversion.register(ignore_duplicates=True) -@python_2_unicode_compatible -class Soustredeni_Organizatori(models.Model): +def aux_generate_filename(self, filename): + """Pomocná funkce generující ošetřený název souboru v adresáři s datem""" + clean = get_valid_filename( + unidecode(filename.replace('/', '-').replace('\0', '')) + ) + datedir = timezone.now().strftime('%Y-%m') + fname = "{}/{}".format( + timezone.now().strftime('%Y-%m-%d-%H:%M'), + clean) + return os.path.join(datedir, fname) - class Meta: - db_table = 'seminar_soustredeni_organizatori' - verbose_name = u'Účast organizátorů na soustředění' - verbose_name_plural = u'Účasti organizátorů na soustředění' - ordering = ['soustredeni', 'organizator'] +# Django neumí jednoduše serializovat partial nebo třídu s __call__ +# (https://docs.djangoproject.com/en/1.8/topics/migrations/), +# neprojdou pak migrace. Takže rozlišení funkcí generujících názvy souboru +# podle adresáře řešíme takto. - # Interní ID - id = models.AutoField(primary_key = True) +## +def generate_filename_konfera(self, filename): + return os.path.join( + settings.SEMINAR_KONFERY_DIR, + aux_generate_filename(self, filename) + ) - organizator = models.ForeignKey(Organizator, verbose_name=u'organizátor') +## +def generate_filename(self, filename): + return os.path.join( + settings.SEMINAR_RESENI_DIR, + aux_generate_filename(self, filename) + ) - soustredeni = models.ForeignKey(Soustredeni, verbose_name=u'soustředění') - poznamka = models.TextField(u'neveřejná poznámka', blank=True, - help_text=u'Neveřejná poznámka k účasti organizátora (plain text)') +@reversion.register(ignore_duplicates=True) +class PrilohaReseni(SeminarModelBase): - def __str__(self): - return force_unicode(u'%s na %s' % (self.organizator, self.soustredeni, )) - # NOTE: Poteciální DB HOG bez select_related + class Meta: + db_table = 'seminar_priloha_reseni' + verbose_name = 'Příloha řešení' + verbose_name_plural = 'Přílohy řešení' + ordering = ['reseni', 'vytvoreno'] + # Interní ID + id = models.AutoField(primary_key = True) + reseni = models.ForeignKey(Reseni, verbose_name='řešení', related_name='prilohy', + on_delete=models.CASCADE) -@reversion.register(ignore_duplicates=True) -@python_2_unicode_compatible -class Konfera(models.Model): - class Meta: - db_table = 'seminar_konfera' - verbose_name = u'Konfera' - verbose_name_plural = u'Konfery' - # Interní ID - id = models.AutoField(primary_key = True) - nazev = models.CharField(u'název konfery', max_length=40, help_text = u'Název konfery') - popis = models.TextField(u'popis konfery', blank=True, - help_text=u'Popis konfery k zobrazení na webu') - abstrakt = models.TextField(u'abstrakt', blank=True, - help_text=u'Abstrakt konfery tak, jak byl uveden ve sborníku') - organizator = models.ForeignKey(Organizator, verbose_name=u'organizátor', related_name='konfery', - on_delete = models.SET_NULL, null=True) - ucastnici = models.ManyToManyField(Resitel, verbose_name=u'účastníci konfery', - help_text=u'Seznam účastníků konfery', through='Konfery_Ucastnici') - soustredeni = models.ForeignKey(Soustredeni, verbose_name=u'soustředění', related_name='konfery', - on_delete = models.SET_NULL, null=True) - org_poznamka = models.TextField(u'neveřejná poznámka', blank=True, - help_text=u'Neveřejná poznámka ke konfeře(plain text)') - prispevek = models.ForeignKey(Problem, verbose_name=u'příspěvek do čísla', related_name='konfery', - help_text=u'Účastnický přípěvek o konfeře',on_delete = models.SET_NULL, null=True, blank=True) - TYP_VELETRH = 'veletrh' - TYP_PREZENTACE = 'prezentace' - TYP_CHOICES = [ - (TYP_VELETRH, u'Veletrh (postery)'), - (TYP_PREZENTACE, u'Prezentace (přednáška)'), - ] - typ_prezentace = models.CharField(u'typ prezentace', max_length=16, choices=TYP_CHOICES, blank=False, default=TYP_VELETRH) - prezentace = models.FileField(u'prezentace',help_text = u'Prezentace nebo fotka posteru', - upload_to = generate_filename_konfera, blank=True) - materialy = models.FileField(u'materialy',help_text = u'Další materiály ke konfeře zabalené do jednoho souboru', - upload_to = generate_filename_konfera, blank=True) - - def __str__(self): - return force_unicode(u"%s: (%s)" % (self.nazev, self.soustredeni)) + vytvoreno = models.DateTimeField('vytvořeno', default=timezone.now, blank=True, editable=False) + soubor = models.FileField('soubor', upload_to = generate_filename) + poznamka = models.TextField('neveřejná poznámka', blank=True, + help_text='Neveřejná poznámka k příloze řešení (plain text), např. o původu') + + res_poznamka = models.TextField('poznámka řešitele', blank=True, + help_text='Poznámka k příloze řešení, např. co daný soubor obsahuje') -@reversion.register(ignore_duplicates=True) -@python_2_unicode_compatible -class Konfery_Ucastnici(models.Model): + def __str__(self): + return str(self.soubor) - class Meta: - db_table = 'seminar_konfery_ucastnici' - verbose_name = u'Účast na konfeře' - verbose_name_plural = u'Účasti na konfeře' - ordering = ['konfera', 'resitel'] + def split(self): + "Vrátí cestu rozsekanou po složkách. To se hodí v templatech" + # Věřím, že tohle funguje, případně použít os.path nebo pathlib. + return self.soubor.url.split('/') - # Interní ID - id = models.AutoField(primary_key = True) - resitel = models.ForeignKey(Resitel, verbose_name=u'řešitel') +class Pohadka(SeminarModelBase): + """Kus pohádky před/za úlohou v čísle""" + + class Meta: + db_table = 'seminar_pohadky' + verbose_name = 'Pohádka' + verbose_name_plural = 'Pohádky' + ordering = ['vytvoreno'] + + # Interní ID + id = models.AutoField(primary_key=True) + + autor = models.ForeignKey( + Organizator, + verbose_name="Autor pohádky", + + # Při nahrávání z TeXu není vyplnění vyžadováno, v adminu je + null=True, + blank=False, + on_delete=models.SET_NULL + ) + + vytvoreno = models.DateTimeField( + 'Vytvořeno', + default=timezone.now, + blank=True, + editable=False + ) + + # má OneToOneField s: + # PohadkaNode + + def __str__(self): + uryvek = self.text if len(self.text) < 50 else self.text[:(50-3)]+"..." + return uryvek + + def save(self, *args, **kwargs): + super().save(*args, **kwargs) + # *Node.save() aktualizuje název *Nodu. + try: + self.pohadkanode.save() + except ObjectDoesNotExist: + # Neexistující *Node nemá smysl aktualizovat. + pass - konfera = models.ForeignKey(Konfera, verbose_name=u'konfera') +@reversion.register(ignore_duplicates=True) +class Soustredeni_Ucastnici(SeminarModelBase): +# zmena dedicnosti z models.Model na SeminarModelBase, potencialni vznik bugu - poznamka = models.TextField(u'neveřejná poznámka', blank=True, - help_text=u'Neveřejná poznámka k účasti (plain text)') + class Meta: + db_table = 'seminar_soustredeni_ucastnici' + verbose_name = 'Účast na soustředění' + verbose_name_plural = 'Účasti na soustředění' + ordering = ['soustredeni', 'resitel'] - def __str__(self): - return force_unicode(u'%s na %s' % (self.resitel, self.konfera, )) - # NOTE: Poteciální DB HOG bez select_related + # Interní ID + id = models.AutoField(primary_key = True) + resitel = models.ForeignKey(Resitel, verbose_name='řešitel', on_delete=models.PROTECT) -@python_2_unicode_compatible -class VysledkyBase(SeminarModelBase): + soustredeni = models.ForeignKey(Soustredeni, verbose_name='soustředění', + on_delete=models.PROTECT) - class Meta: - verbose_name = u'Řádek výsledkovky' - verbose_name_plural = u'Řádky výsledkovky' - ordering = ['body'] - abstract = True - managed = False + poznamka = models.TextField('neveřejná poznámka', blank=True, + help_text='Neveřejná poznámka k účasti (plain text)') - dummy_id = models.CharField(u'dummy ID pro view', max_length=32, primary_key=True, db_column='id') + def __str__(self): + return '{} na {}'.format(self.resitel, self.soustredeni) + # NOTE: Poteciální DB HOG bez select_related - cislo = models.ForeignKey(Cislo, verbose_name=u'číslo pro body', db_column='cislo_id', on_delete=models.DO_NOTHING) +@reversion.register(ignore_duplicates=True) +class Soustredeni_Organizatori(SeminarModelBase): +# zmena dedicnosti z models.Model na SeminarModelBase, potencialni vznik bugu - resitel = models.ForeignKey(Resitel, verbose_name=u'řešitel', db_column='resitel_id', on_delete=models.DO_NOTHING) + class Meta: + db_table = 'seminar_soustredeni_organizatori' + verbose_name = 'Účast organizátorů na soustředění' + verbose_name_plural = 'Účasti organizátorů na soustředění' + ordering = ['soustredeni', 'organizator'] - body = models.DecimalField(max_digits=8, decimal_places=1, db_column='body', - verbose_name=u'body za číslo') + # Interní ID + id = models.AutoField(primary_key = True) - def __str__(self): - return force_unicode(u"%s: %sb (%s)" % (self.resitel.plne_jmeno(), self.body, str(self.cislo))) - # NOTE: DB zatez pri vypisu (ale nepouzivany) + organizator = models.ForeignKey(Organizator, verbose_name='organizátor', + on_delete=models.PROTECT) + soustredeni = models.ForeignKey(Soustredeni, verbose_name='soustředění', + on_delete=models.PROTECT) -class VysledkyZaCislo(VysledkyBase): + poznamka = models.TextField('neveřejná poznámka', blank=True, + help_text='Neveřejná poznámka k účasti organizátora (plain text)') - class Meta: - db_table = 'seminar_body_za_cislo' - abstract = False - managed = False + def __str__(self): + return '{} na {}'.format(self.organizator, self.soustredeni) + # NOTE: Poteciální DB HOG bez select_related -class VysledkyKCisluZaRocnik(VysledkyBase): - class Meta: - db_table = 'seminar_body_k_cislu_rocnik' - abstract = False - managed = False +@reversion.register(ignore_duplicates=True) +class Konfera(Problem): + class Meta: + db_table = 'seminar_konfera' + verbose_name = 'Konfera' + verbose_name_plural = 'Konfery' + + anotace = models.TextField('anotace', blank=True, + help_text='Popis, o čem bude konfera.') + + abstrakt = models.TextField('abstrakt', blank=True, + help_text='Abstrakt konfery tak, jak byl uveden ve sborníku') + + # FIXME: Umíme omezit jen na účastníky daného soustřeďka? + ucastnici = models.ManyToManyField(Resitel, verbose_name='účastníci konfery', + help_text='Seznam účastníků konfery', through='Konfery_Ucastnici') + + soustredeni = models.ForeignKey(Soustredeni, verbose_name='soustředění', + related_name='konfery', on_delete = models.SET_NULL, null=True) + + TYP_VELETRH = 'veletrh' + TYP_PREZENTACE = 'prezentace' + TYP_CHOICES = [ + (TYP_VELETRH, 'Veletrh (postery)'), + (TYP_PREZENTACE, 'Prezentace (přednáška)'), + ] + typ_prezentace = models.CharField('typ prezentace', max_length=16, choices=TYP_CHOICES, + blank=False, default=TYP_VELETRH) + + prezentace = models.FileField('prezentace',help_text = 'Prezentace nebo fotka posteru', + upload_to = generate_filename_konfera, blank=True) + + materialy = models.FileField('materialy', + help_text = 'Další materiály ke konfeře zabalené do jednoho souboru', + upload_to = generate_filename_konfera, blank=True) + + def __str__(self): + return "{}: ({})".format(self.nazev, self.soustredeni) + + def cislo_node(self): + return None + +# Vazebna tabulka. Mozna se generuje automaticky. +@reversion.register(ignore_duplicates=True) +class Reseni_Resitele(models.Model): -# body = models.DecimalField(max_digits=8, decimal_places=1, db_column='body', -# verbose_name=u'body do čísla (za ročník)') + class Meta: + db_table = 'seminar_reseni_resitele' + verbose_name = 'Řešení řešitelů' + verbose_name_plural = 'Řešení řešitelů' + ordering = ['reseni', 'resitele'] + # Interní ID + id = models.AutoField(primary_key = True) -class VysledkyKCisluOdjakziva(VysledkyBase): + resitele = models.ForeignKey(Resitel, verbose_name='řešitel', on_delete=models.PROTECT) - class Meta: - db_table = 'seminar_body_k_cislu_odjakziva' - abstract = False - managed = False + reseni = models.ForeignKey(Reseni, verbose_name='řešení', on_delete=models.CASCADE) -# body = models.DecimalField(max_digits=8, decimal_places=1, db_column='body', -# verbose_name=u'body do čísla (i minulé ročníky)') + # podil - jakou merou se ktery resitel podilel na danem reseni + # - pouziti v budoucnu, pokud by resitele nemeli dostat vsichni stejne bodu za spolecne reseni + def __str__(self): + return '{} od {}'.format(self.reseni, self.resitel) + # NOTE: Poteciální DB HOG bez select_related -@python_2_unicode_compatible -class VysledkyCelkemKCislu(VysledkyBase): +@reversion.register(ignore_duplicates=True) +class Konfery_Ucastnici(models.Model): - class Meta: - db_table = 'seminar_body_celkem_k_cislu' - abstract = False - managed = False + class Meta: + db_table = 'seminar_konfery_ucastnici' + verbose_name = 'Účast na konfeře' + verbose_name_plural = 'Účasti na konfeře' + ordering = ['konfera', 'resitel'] + + # Interní ID + id = models.AutoField(primary_key = True) + + resitel = models.ForeignKey(Resitel, verbose_name='řešitel', on_delete=models.PROTECT) + + konfera = models.ForeignKey(Konfera, verbose_name='konfera', on_delete=models.CASCADE) + + poznamka = models.TextField('neveřejná poznámka', blank=True, + help_text='Neveřejná poznámka k účasti (plain text)') + + def __str__(self): + return '{} na {}'.format(self.resitel, self.konfera) + # NOTE: Poteciální DB HOG bez select_related + +class Obrazek(SeminarModelBase): + class Meta: + db_table = 'seminar_obrazky' + verbose_name = 'obrázek' + verbose_name_plural = 'obrázky' + + # Interní ID + id = models.AutoField(primary_key = True) + + na_web = models.ImageField('obrázek na web', upload_to='obrazky/%Y/%m/%d/', + null=True, blank=True) + + text = models.ForeignKey(Text, verbose_name='text', + help_text='text, ve kterém se obrázek vyskytuje', + null=False, blank=False, on_delete=models.CASCADE) + + do_cisla_barevny = models.FileField('barevný obrázek do čísla', + help_text = 'Barevná verze obrázku do čísla', + upload_to = 'obrazky/%Y/%m/%d/', blank=True, null=True) + + do_cisla_cernobily = models.FileField('černobílý obrázek do čísla', + help_text = 'Černobílá verze obrázku do čísla', + upload_to = 'obrazky/%Y/%m/%d/', blank=True, null=True) + + # TODO placement hint - chci ho tady / pred textem / za textem + +class TreeNode(PolymorphicModel): + class Meta: + db_table = "seminar_nodes_treenode" + verbose_name = "TreeNode" + verbose_name_plural = "TreeNody" + + # TODO: Nechceme radši jako root vyžadovat přímo RocnikNode? + root = models.ForeignKey('TreeNode', + related_name="potomci_set", + null = True, + blank = False, + on_delete = models.SET_NULL, # Vrcholy s null kořenem jsou sirotci bez ročníku + verbose_name="kořen stromu") + first_child = models.OneToOneField('TreeNode', + related_name='father_of_first', + null = True, + blank = True, + on_delete=models.SET_NULL, + verbose_name="první potomek") + succ = models.OneToOneField('TreeNode', + related_name="prev", + null = True, + blank = True, + on_delete=models.SET_NULL, + verbose_name="další element na stejné úrovni") + nazev = models.TextField("název tohoto node", + help_text = "Tento název se zobrazuje v nabídkách pro výběr vhodného TreeNode", + blank=False, + null=True) # Nezveřejnitelný název na stránky - pouze do adminu + zajimave = models.BooleanField(default = False, + verbose_name = "Zajímavé", + help_text = "Zobrazí se daná věc na rozcestníku témátek") + srolovatelne = models.BooleanField(null = True, blank = True, + verbose_name = "Srolovatelné", + help_text = "Bude na stránce témátka možnost tuto položku skrýt") + + def getOdkazStr(self): # String na rozcestník + return self.first_child.getOdkazStr() + + def getOdkaz(self): # ID HTML tagu, na který se bude scrollovat #{{self.getOdkaz}} + # Jsem si vědom, že tu potenciálně vznikají kolize. + # Přijdou mi natolik nepravděpodobné, že je neřeším + # Chtěl jsem ale hezké odkazy + string = unidecode(self.getOdkazStr()) + returnVal = "" + i = 0 + while len(returnVal) < 16: # Max 15 znaků + if i == len(string): + break + if string[i] == " ": + returnVal += "-" + if string[i].isalnum(): + returnVal += string[i].lower() + i += 1 + return returnVal + + def __str__(self): + if self.nazev: + return self.nazev + else: + #TODO: logování + return "Nepojmenovaný Treenode" + + def save(self, *args, **kwargs): + self.aktualizuj_nazev() + super().save(*args, **kwargs) + + def aktualizuj_nazev(self): + raise NotImplementedError("Pokus o aktualizaci názvu obecného TreeNode místo konkrétní instance") + + def get_admin_url(self): + content_type = ContentType.objects.get_for_model(self.__class__) + return reverse("admin:%s_%s_change" % (content_type.app_label, content_type.model), args=(self.id,)) + +class RocnikNode(TreeNode): + class Meta: + db_table = 'seminar_nodes_rocnik' + verbose_name = 'Ročník (Node)' + verbose_name_plural = 'Ročníky (Node)' + rocnik = models.OneToOneField(Rocnik, + on_delete = models.PROTECT, # Pokud chci mazat ročník, musím si Node pořešit ručně + verbose_name = "ročník") + + def aktualizuj_nazev(self): + self.nazev = "RocnikNode: "+str(self.rocnik) + +class CisloNode(TreeNode): + class Meta: + db_table = 'seminar_nodes_cislo' + verbose_name = 'Číslo (Node)' + verbose_name_plural = 'Čísla (Node)' + cislo = models.OneToOneField(Cislo, + on_delete = models.PROTECT, # Pokud chci mazat číslo, musím si Node pořešit ručně + verbose_name = "číslo") + + def aktualizuj_nazev(self): + self.nazev = "CisloNode: "+str(self.cislo) + + def getOdkazStr(self): + return "Číslo " + str(self.cislo) + +class MezicisloNode(TreeNode): + class Meta: + db_table = 'seminar_nodes_mezicislo' + verbose_name = 'Mezičíslo (Node)' + verbose_name_plural = 'Mezičísla (Node)' + + # TODO: Využít TreeLib + def aktualizuj_nazev(self): + from seminar.treelib import safe_pred + if safe_pred(self) is not None: + if (self.prev.get_real_instance_class() != CisloNode and + self.prev.get_real_instance_class() != MezicisloNode): + raise ValueError("Předchůdce není číslo!") + posledni = self.prev.cislo + self.nazev = "MezicisloNode: Mezičíslo po čísle"+str(posledni) + elif self.root: + if self.root.get_real_instance_class() != RocnikNode: + raise ValueError("Kořen stromu není ročník!") + rocnik = self.root.rocnik + self.nazev = "MezicisloNode: První mezičíslo ročníku "+str(rocnik) + else: + print("!!!!! Nějaké neidentifikované mezičíslo !!!!!") + self.nazev = "MezicisloNode: Neidentifikovatelné mezičíslo!" + def getOdkazStr(self): + return "Obsah dostupný pouze na webu" + +class TemaVCisleNode(TreeNode): + """ Obsahuje příspěvky k tématu v daném čísle """ + class Meta: + db_table = 'seminar_nodes_temavcisle' + verbose_name = 'Téma v čísle (Node)' + verbose_name_plural = 'Témata v čísle (Node)' + tema = models.ForeignKey(Tema, + on_delete=models.PROTECT, # Pokud chci mazat téma, musím si Node pořešit ručně + verbose_name = "téma v čísle") + + def aktualizuj_nazev(self): + self.nazev = "TemaVCisleNode: "+str(self.tema) + + def getOdkazStr(self): + return str(self.tema) + +class OrgTextNode(TreeNode): + class Meta: + db_table = 'seminar_nodes_orgtextnode' + verbose_name = 'Organizátorský článek (Node)' + verbose_name_plural = 'Organizátorské články (Node)' + + organizator = models.ForeignKey(Organizator, + null=False, + blank=False, + on_delete=models.DO_NOTHING, + verbose_name="Organizátor", + ) + org_verejny = models.BooleanField(default = True, + verbose_name = "Org je veřejný?", + help_text = "Pokud ano, bude org pod článkem podepsaný", + null=False, + ) + + def aktualizuj_nazev(self): + return f"OrgTextNode začínající následujícim: {self.first_child.nazev}" + + # FIXME!!! + #def getOdkazStr(self): + # return str(self.clanek) + + +class UlohaZadaniNode(TreeNode): + class Meta: + db_table = 'seminar_nodes_uloha_zadani' + verbose_name = 'Zadání úlohy (Node)' + verbose_name_plural = 'Zadání úloh (Node)' + uloha = models.OneToOneField(Uloha, + on_delete=models.PROTECT, # Pokud chci mazat téma, musím si Node pořešit ručně + verbose_name = "úloha", + null=True, + blank=False) + + def aktualizuj_nazev(self): + self.nazev = "UlohaZadaniNode: "+str(self.uloha) + + def getOdkazStr(self): + return str(self.uloha) + + +class PohadkaNode(TreeNode): + class Meta: + db_table = 'seminar_nodes_pohadka' + verbose_name = 'Pohádka (Node)' + verbose_name_plural = 'Pohádky (Node)' + pohadka = models.OneToOneField(Pohadka, + on_delete=models.PROTECT, # Pokud chci mazat pohádku, musím si Node pořešit ručně + verbose_name = "pohádka", + ) + + def aktualizuj_nazev(self): + self.nazev = "PohadkaNode: "+str(self.pohadka) + +class UlohaVzorakNode(TreeNode): + class Meta: + db_table = 'seminar_nodes_uloha_vzorak' + verbose_name = 'Vzorák úlohy (Node)' + verbose_name_plural = 'Vzoráky úloh (Node)' + uloha = models.OneToOneField(Uloha, + on_delete=models.PROTECT, # Pokud chci mazat téma, musím si Node pořešit ručně + verbose_name = "úloha", + null=True, + blank=False) + + def aktualizuj_nazev(self): + self.nazev = "UlohaVzorakNode: "+str(self.uloha) + + def getOdkazStr(self): + return str(self.uloha) + + +class TextNode(TreeNode): + class Meta: + db_table = 'seminar_nodes_obsah' + verbose_name = 'Text (Node)' + verbose_name_plural = 'Text (Node)' + text = models.ForeignKey(Text, + on_delete=models.CASCADE, + verbose_name = 'text') + + def aktualizuj_nazev(self): + self.nazev = "TextNode: "+str(self.text) + + def getOdkazStr(self): + return str(self.text) + +class CastNode(TreeNode): + class Meta: + db_table = 'seminar_nodes_cast' + verbose_name = 'Část (Node)' + verbose_name_plural = 'Části (Node)' + + nadpis = models.CharField('Nadpis', max_length=100, help_text = 'Nadpis podvěšené části obsahu') + + def aktualizuj_nazev(self): + self.nazev = "CastNode: "+str(self.nadpis) + + def getOdkazStr(self): + return str(self.nadpis) + +class ReseniNode(TreeNode): + class Meta: + db_table = 'seminar_nodes_otistene_reseni' + verbose_name = 'Otištěné řešení (Node)' + verbose_name_plural = 'Otištěná řešení (Node)' + reseni = models.ForeignKey(Reseni, + on_delete=models.PROTECT, + verbose_name = 'reseni') + + def aktualizuj_nazev(self): + self.nazev = "ReseniNode: "+str(self.reseni) + + def getOdkazStr(self): + return str(self.reseni) + +## FIXME: Logiku přesunout do views. +#class VysledkyBase(SeminarModelBase): +# +# class Meta: +# verbose_name = 'Řádek výsledkovky' +# verbose_name_plural = 'Řádky výsledkovky' +# ordering = ['body'] +# abstract = True +# managed = False +# +# dummy_id = models.CharField('dummy ID pro view', max_length=32, primary_key=True, +# db_column='id') +# +# cislo = models.ForeignKey(Cislo, verbose_name='číslo pro body', db_column='cislo_id', +# on_delete=models.DO_NOTHING) +# +# resitel = models.ForeignKey(Resitel, verbose_name='řešitel', db_column='resitel_id', +# on_delete=models.DO_NOTHING) +# +# body = models.DecimalField(max_digits=8, decimal_places=1, db_column='body', +# verbose_name='body za číslo') +# +# def __str__(self): +# return "%s: %sb (%s)".format(self.resitel.plne_jmeno(), self.body, +# str(self.poradi)) +# # NOTE: DB zatez pri vypisu (ale nepouzivany) - body_celkem = models.DecimalField(max_digits=8, decimal_places=1, db_column='body_celkem', - verbose_name=u'body celkem do čísla včetně minulých ročníků') - def __str__(self): - # NOTE: DB HOG (ale nepouzivany) - return force_unicode(u"%s: %sb / %sb (do %s)" % (self.resitel.plne_jmeno(), self.body, self.body_celkem, str(self.cislo))) -#mozna potreba upravit +## FIXME: Logiku přesunout do views. +#class VysledkyZaCislo(VysledkyBase): +# +# class Meta: +# db_table = 'seminar_body_za_cislo' +# abstract = False +# managed = False +# +# +## FIXME: Logiku přesunout do views. +#class VysledkyKCisluZaRocnik(VysledkyBase): +# +# class Meta: +# db_table = 'seminar_body_k_cislu_rocnik' +# abstract = False +# managed = False +# +## body = models.DecimalField(max_digits=8, decimal_places=1, db_column='body', +## verbose_name='body do čísla (za ročník)') +# +# +## FIXME: Logiku přesunout do views. +#class VysledkyKCisluOdjakziva(VysledkyBase): +# +# class Meta: +# db_table = 'seminar_body_k_cislu_odjakziva' +# abstract = False +# managed = False +# +## body = models.DecimalField(max_digits=8, decimal_places=1, db_column='body', +## verbose_name='body do čísla (i minulé ročníky)') +# +# +## FIXME: Logiku přesunout do views. +#class VysledkyCelkemKCislu(VysledkyBase): +# +# class Meta: +# db_table = 'seminar_body_celkem_k_cislu' +# abstract = False +# managed = False +# +# body_celkem = models.DecimalField(max_digits=8, decimal_places=1, db_column='body_celkem', +# verbose_name='body celkem do čísla včetně minulých ročníků') +# +# def __str__(self): +# # NOTE: DB HOG (ale nepouzivany) +# return "%s: %sb / %sb (do %s)" % (self.resitel.plne_jmeno(), self.body, self.body_celkem, str(self.poradi)) +##mozna potreba upravit @reversion.register(ignore_duplicates=True) -@python_2_unicode_compatible class Nastaveni(SingletonModel): - class Meta: - db_table = 'seminar_nastaveni' - verbose_name = u'Nastavení semináře' + class Meta: + db_table = 'seminar_nastaveni' + verbose_name = 'Nastavení semináře' + +# aktualni_rocnik = models.ForeignKey(Rocnik, verbose_name='aktuální ročník', +# null=False, on_delete=models.PROTECT) - aktualni_rocnik = models.ForeignKey(Rocnik, verbose_name=u'aktuální ročník', null=False) + aktualni_cislo = models.ForeignKey(Cislo, verbose_name='poslední vydané číslo', + null=False, on_delete=models.PROTECT) - aktualni_cislo = models.ForeignKey(Cislo, verbose_name=u'poslední vydané číslo', null=False) + @property + def aktualni_rocnik(self): + return self.aktualni_cislo.rocnik - def __str__(self): - return u'Nastavení semináře' + def __str__(self): + return 'Nastavení semináře' - def admin_url(self): - return reverse('admin:seminar_nastaveni_change', args=(self.id, )) - - def verejne(self): - return False + def admin_url(self): + return reverse('admin:seminar_nastaveni_change', args=(self.id, )) + + def verejne(self): + return False @reversion.register(ignore_duplicates=True) -@python_2_unicode_compatible class Novinky(models.Model): - datum = models.DateField(auto_now_add=True) - text = models.TextField('Text novinky', blank=True, null=True) - obrazek = models.ImageField('Obrázek', upload_to='image_novinky/%Y/%m/%d/', - null=True, blank=True) - obrazek_maly = ImageSpecField(source='obrazek', - processors=[ - ResizeToFit(350, 200, upscale=False) - ], - options={'quality': 95}) - - autor = models.ForeignKey(settings.AUTH_USER_MODEL, - verbose_name='Autor novinky') - zverejneno = models.BooleanField('Zveřejněno', default="False") - - def __str__(self): - return '[' + str(self.datum) + '] ' + self.text[0:50] - - class Meta: - verbose_name = 'Novinka' - verbose_name_plural = 'Novinky' - + class Meta: + verbose_name = 'Novinka' + verbose_name_plural = 'Novinky' + ordering = ['-datum'] + + datum = models.DateField(auto_now_add=True) + + text = models.TextField('Text novinky', blank=True, null=True) + obrazek = models.ImageField('Obrázek', upload_to='image_novinky/%Y/%m/%d/', + null=True, blank=True) + + obrazek_maly = ImageSpecField(source='obrazek', + processors=[ + ResizeToFit(350, 200, upscale=False) + ], + options={'quality': 95}) + + autor = models.ForeignKey(Organizator, verbose_name='Autor novinky', null=True, + on_delete=models.SET_NULL) + + zverejneno = models.BooleanField('Zveřejněno', default=False) + + def __str__(self): + if self.text: + return '[' + str(self.datum) + '] ' + self.text[0:50] + else: + return '[' + str(self.datum) + '] ' + + + + +# FIXME: Tohle nepatří do aplikace 'seminar' +# Nefunkční alternativa vestavěného Usera, který má jméno a mail v přidružené Osobě +# from django.contrib.auth.models import User as Django_User +# +# class Uzivatel(Django_User): +# class Meta: +# proxy = True +# +# @property +# def first_name(self): +# osoby = Osoba.objects.filter(user=self) +# if len(osoby) == 0: +# return None +# return osoby.first().krestni_jmeno +# +# @property +# def last_name(self): +# osoby = Osoba.objects.filter(user=self) +# if len(osoby) == 0: +# return None +# return osoby.first().prijmeni +# +# @property +# def email(self): +# osoby = Osoba.objects.filter(user=self) +# if len(osoby) == 0: +# return None +# return osoby.first().email diff --git a/seminar/old_tests.py b/seminar/old_tests.py new file mode 100644 index 00000000..a5e74f01 --- /dev/null +++ b/seminar/old_tests.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- + +import datetime +import random +import django.contrib.auth +from unittest import TestCase +from django.test import Client +from django.core.urlresolvers import reverse, resolve +from django.core.management import call_command + +from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Soustredeni, Nastaveni +from seminar.testutils import create_test_data +from seminar import ovvpfile +from seminar import utils + +class SeminarBasicTests(TestCase): + def setUp(self): + create_test_data(size=2) + self.client = Client() + + def tearDown(self): + call_command('flush', noinput=True, verbosity=0, interactive=False) + self.cleint = None + + def test_rocniky(self): + r19 = Rocnik.objects.get(rocnik=21) + self.assertEqual(r19.roman(), 'XXI') + + def test_render_cislo_e2e(self): + cs = Cislo.objects.all() + for c in cs[:4]: + url = c.verejne_url() + r = self.client.get(url) + assert r.status_code == 200 + assert len(r.content) >= 100 + # TODO: Validate cntent as HTML + + def test_render_problem_e2e(self): + ps = Problem.objects.all() + for p in ps[:4]: + url = p.verejne_url() + r = self.client.get(url) + assert r.status_code == 200 + assert len(r.content) >= 100 + # TODO: Validate cntent as HTML + + def test_export_e2e(self): + i_url = '/aesop-export/index.csv' + i_r = self.client.get(i_url) + assert i_r.status_code == 200 + ls = i_r.content.strip().split('\n') + + for u in [ls[0], ls[-1]]: + ex_r = self.client.get('/aesop-export/' + u) + assert ex_r.status_code == 200 + assert len(ex_r.content) >= 100 + o = ovvpfile.parse(ex_r.content) + assert o.headers['version'] == '1' + + def test_admin_url(self): + for m in [Skola, Resitel, Rocnik, Cislo, Problem, Reseni, Nastaveni]: + o = m.objects.first() + url = o.admin_url() + assert url + view = resolve(url) + assert view + + def test_verejne_url(self): + for m in [Rocnik, Cislo, Problem]: + p = Problem.objects.first() + url = p.verejne_url() + assert url + view = resolve(url) + assert view + + def test_ovvpfile(self): + filetext = "H1\ta\nH2\tb\tc\n\nx\ty\tz\n0\t1\t2\n3\t4\t5\n" + o = ovvpfile.parse(filetext) + assert len(o.headers) == 2 + assert o.headers['H2'] == 'b\tc' + + assert o.columns == ['x','y','z'] + assert len(o.rows) == 2 + assert o.rows[0]['z'] == '2' + + t = o.to_string() + assert t == filetext + + def test_roman(self): + for i in [0, 1, 23, 2015, 1999, 42, 4, 400, 78, 4321, 8765, 999]: + r = utils.roman(i) + fr = utils.from_roman(r) + assert fr == i + diff --git a/seminar/old_views.py b/seminar/old_views.py new file mode 100644 index 00000000..f904d137 --- /dev/null +++ b/seminar/old_views.py @@ -0,0 +1,71 @@ +# Tento soubor slouží k odkládání aktuálně nepotřebného kódu, který by +# se však v budoucnu mohl opět hodit. + +################################################################### + +## Prispevek byl zrusen, mozna ale bude podobny nahled na neco jineho. +#class PrispevekView(generic.DetailView): +# model = Prispevek +# template_name = 'seminar/archiv/prispevek.html' +# +# # Vlastni ziskavani objektu z databaze podle prispevku +# # pokud je prispevek neverejny zobrazi se jenom orgum +# def get_object(self, queryset=None): +# if queryset is None: +# queryset = self.get_queryset() +# problem_arg = self.kwargs.get('pk') +# prispevek_arg = self.kwargs.get('prispevek') +# queryset = queryset.filter(pk=prispevek_arg) +# +# try: +# obj = queryset.get() +# except queryset.model.DoesNotExist: +# raise Http404(_("No %(verbose_name)s found matching the query") % +# {'verbose_name': queryset.model._meta.verbose_name}) +# +# if self.request.user.is_staff or obj.zverejnit: +# return obj +# else: +# raise Http404() +# +# def get_context_data(self, **kwargs): +# context = super(PrispevekView, self).get_context_data(**kwargs) +# # snaho o ziskani titulu +# titul = '' +# try: +# resitel = context['prispevek'].reseni.resitel +# cislo = context['prispevek'].reseni.cislo_body +# body = VysledkyKCisluOdjakziva.objects.get(resitel=resitel, +# cislo=cislo).body +# titul = resitel.get_titul(body) +# except: +# pass +# context['titul'] = titul +# return context + +#################################################################### + +## Stvrzenky aktuálně nevydáváme, ale možná časem zase budeme. +#def soustredeniStvrzenkyExportView(request,soustredeni,first_num): +# first_num = int(first_num) +# soustredeni = get_object_or_404(Soustredeni,id = soustredeni) +# ucastnici = Resitel.objects.filter(soustredeni=soustredeni) +# for (idx,u) in enumerate(ucastnici): +# u.cislo_stvrzenky = first_num+idx; +# tex = render(request,'seminar/soustredeni/ucastnici.tex', {'ucastnici': ucastnici, 'datum':soustredeni.datum_zacatku }).content +# +# tempdir = tempfile.mkdtemp() +# with open(tempdir+"/ucastnici.tex","w") as texfile: +# # Pokud TeX chce ISO Latin, tak se da encode nastavit +# texfile.write(tex.decode("utf-8").encode("utf-8")) +# shutil.copy(os.path.join(settings.STATIC_ROOT, 'seminar/stvrzenka.sty'),tempdir) +# shutil.copy(os.path.join(settings.STATIC_ROOT, 'seminar/stvrzenky.tex'),tempdir) +# subprocess.call(["cslatex","stvrzenky.tex"],cwd = tempdir) +# subprocess.call(["dvipdf","stvrzenky.dvi"],cwd = tempdir) +# +# with open(tempdir+"/stvrzenky.pdf","rb") as pdffile: +# response = HttpResponse(pdffile.read(),content_type='application/pdf') +# shutil.rmtree(tempdir) +# return response + + diff --git a/seminar/permissions.py b/seminar/permissions.py new file mode 100644 index 00000000..5503832f --- /dev/null +++ b/seminar/permissions.py @@ -0,0 +1,7 @@ +from rest_framework.permissions import BasePermission + +class AllowWrite(BasePermission): + + def has_permission(self, request, view): + return request.user.has_perm('auth.org') + diff --git a/seminar/static/images/no-photo.png b/seminar/static/images/no-photo.png new file mode 100644 index 00000000..a20e8f22 Binary files /dev/null and b/seminar/static/images/no-photo.png differ diff --git a/seminar/static/images/no-picture.png b/seminar/static/images/no-picture.png new file mode 100644 index 00000000..9256f628 Binary files /dev/null and b/seminar/static/images/no-picture.png differ diff --git a/seminar/static/images/tema-bez-obrazku.png b/seminar/static/images/tema-bez-obrazku.png new file mode 100644 index 00000000..8f421df2 Binary files /dev/null and b/seminar/static/images/tema-bez-obrazku.png differ diff --git a/seminar/static/seminar/cross.png b/seminar/static/seminar/cross.png new file mode 100644 index 00000000..f3add6aa Binary files /dev/null and b/seminar/static/seminar/cross.png differ diff --git a/seminar/static/seminar/dynamic_formsets.js b/seminar/static/seminar/dynamic_formsets.js new file mode 100644 index 00000000..a0d99d0a --- /dev/null +++ b/seminar/static/seminar/dynamic_formsets.js @@ -0,0 +1,49 @@ +// Credit https://medium.com/all-about-django/adding-forms-dynamically-to-a-django-formset-375f1090c2b0 +function updateElementIndex(el, prefix, ndx) { + var id_regex = new RegExp('(' + prefix + '-\\d+)'); + var replacement = prefix + '-' + ndx; + if ($(el).attr("for")) { + $(el).attr("for", $(el).attr("for").replace(id_regex, replacement)); + } + if (el.id) { + el.id = el.id.replace(id_regex, replacement); + } + if (el.name) { + el.name = el.name.replace(id_regex, replacement); + } +} + +// Credit https://medium.com/all-about-django/adding-forms-dynamically-to-a-django-formset-375f1090c2b0 +function deleteForm(prefix, btn) { + var total = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val()); + if (total >= 1){ + btn.closest('div').remove(); + var forms = $('.attachment'); + $('#id_' + prefix + '-TOTAL_FORMS').val(forms.length); + for (var i=0, formCount=forms.length; i +

    {% block nadpis1a %}{% block nadpis1b %} Archiv čísel {% endblock %}{% endblock %}

    +
    + + {% for rocnik, url_png in object_list.items %} + +
    + +

    + Ročník {{ rocnik }} +

    + + + {# karta ročníku - zepředu obrázek prvního čísla, zezadu odkaz na jednotlivá čísla a výsledkovku #} + +
    - {% comment %} -
    - {% autoescape off %}{{ nahledy }}{% endautoescape %} -
    - {% endcomment %} +
    +
    + +
    + {{ rocnik }} +
    + +
    +
    +
    + Jednotlivá čísla: +
      + {% for cislo in rocnik.cisla.all reversed %} +
    • {{ cislo.poradi }}. číslo {% if cislo.pdf %}(pdf) {% endif %} + {% empty %} + Žádná čísla k zobrazení + {% endfor %} +
    + Výsledková listina +
    + +
    +
    +
    + + {# konec karty ročníku #} + +
    +
    -
      - {% for r in object_list %} -
    • Ročník {{ r }} {% empty %} Nejsou žádné ročníky {% endfor %} -
    +
    - -{% endblock content %} +{% endblock content %} diff --git a/seminar/templates/seminar/archiv/cislo-normal.html b/seminar/templates/seminar/archiv/cislo-normal.html new file mode 100644 index 00000000..e23da09c --- /dev/null +++ b/seminar/templates/seminar/archiv/cislo-normal.html @@ -0,0 +1,97 @@ +{% extends "seminar/archiv/base_cisla.html" %} + +{# {% block content %} +
    + +

    + {% block nadpis1a %}{% block nadpis1b %} + Číslo {{ cislo }} + {% endblock %}{% endblock %} +

    + + {% if cislo.pdf %} +

    Číslo v pdf + {% endif %} +

    Ročník {{ cislo.rocnik }} + + {% if v_cisle_zadane %} +

    Zadané problémy

    + + {% endif %} + + {% if resene_problemy %} +

    Řešené problémy

    + + {% endif %} + + {% if user.is_staff %} +
    +

    Orgovské odkazy

    + +
    + {% endif %} + + {% if cislo.verejna_vysledkovka %} +

    Výsledkovka

    + {% else %} + {% if user.is_staff %} +
    +

    Výsledkovka (neveřejná)

    + {% endif %} + {% endif %} + + {% if cislo.verejna_vysledkovka or user.is_staff %} +

    {{p.anotace}}

    {{p.obor}}
    {{p.obtiznost}}
    {{p.klicova}}
    Hodnocení: - rozhodně nechci - je mi to jedno - rozhodně chci + rozhodně nechci + je mi to jedno + rozhodně chci
     
    + + + + {% endfor %} +
    # + Jméno #} + {# problémy by měly být veřejné, když je veřejná výsledkovka #} +{# {% for p in problemy %} + {{ p.kod_v_rocniku }} + {% endfor %} + Za číslo + Za ročník + Odjakživa + {% for rv in radky_vysledkovky %} +
    {% autoescape off %}{{ rv.poradi }}{% endautoescape %} + + {% if rv.resitel.titul != "" %} + {{ rv.resitel.titul }}MM + {% endif %} + {{ rv.resitel.osoba.plne_jmeno }} + {% for b in rv.hlavni_problemy_body %} + {{ b }} + {% endfor %} + {{ rv.body_cislo }} + {{ rv.body_rocnik }} + {{ rv.body_celkem_odjakziva }} +
    + {% endif %} + + {% if not cislo.verejna_vysledkovka and user.is_staff %} +
    + {% endif %} + + +{% endblock content %} #} + diff --git a/seminar/templates/seminar/archiv/cislo.html b/seminar/templates/seminar/archiv/cislo.html index 98eb5771..1f18d4b5 100644 --- a/seminar/templates/seminar/archiv/cislo.html +++ b/seminar/templates/seminar/archiv/cislo.html @@ -1,25 +1,23 @@ -{% extends "seminar/archiv/base_cisla.html" %} +{% extends "base.html" %} +{% load render_bundle from webpack_loader %} + + {% block content %} +
    -{% block content %} -

    {% block nadpis1a %}{% block nadpis1b %} Číslo {{ cislo }} {% endblock %}{% endblock %}

    - - {% if cislo.pdf %} -

    Číslo v pdf - {% endif %} -

    Ročník {{ cislo.rocnik }} +

    Zpět na ročník {{ cislo.rocnik }}

    {% if v_cisle_zadane %}

    Zadané problémy

    {% endif %} @@ -28,69 +26,131 @@

    Řešené problémy

    {% endif %} - {% if user.is_staff %} + {% if user.je_org %}

    Orgovské odkazy

    {% endif %} + + {% if cislo.titulka_nahled %} +
    +
    +

    Titulní strana {{ cislo.poradi }}. čísla

    +
    + {% elif cislo.pdf %} +

    Číslo v pdf

    +
    + {% endif %} + + +{% comment %} + +
    + +
    + {% render_bundle 'chunk-vendors' %} + {% render_bundle 'vue_app_01' %} +{% endcomment %} + + {% if cislo.verejna_vysledkovka %}

    Výsledkovka

    + {% else %} - {% if user.is_staff %} + {% if user.je_org %}

    Výsledkovka (neveřejná)

    {% endif %} {% endif %} - {% if cislo.verejna_vysledkovka or user.is_staff %} + {% if cislo.verejna_vysledkovka or user.je_org %} {% endfor %}
    # Jméno - {# problémy by měly být veřejné, když je veřejná výsledkovka #} {% for p in problemy %} - {{ p.kod_v_rocniku }} + {# #}{{ p.kod_v_rocniku }}{# #} + + {# TODELETE #} + {% for podproblemy in podproblemy_iter.next %} + {# #}{{ podproblemy.kod_v_rocniku }}{# #} + {% endfor %} + {# TODELETE #} + {% endfor %} - Za číslo + {% if ostatni %}Ostatní {% endif %} + + {# TODELETE #} + {% for podproblemy in podproblemy_iter.next %} + {# #}{{ podproblemy.kod_v_rocniku }}{# #} + {% endfor %} + {# TODELETE #} + + + Za číslo Za ročník Odjakživa - {% for rv in vysledkovka %} + {% for rv in radky_vysledkovky %}
    {% autoescape off %}{{ rv.poradi }}{% endautoescape %} {% if rv.titul %} {{ rv.titul }}MM {% endif %} - {{ rv.resitel.plne_jmeno }} - {% for b in rv.body_ulohy %} + {{ rv.resitel.osoba.plne_jmeno }} + {% for b in rv.body_problemy_sezn %} {{ b }} + + {# TODELETE #} + {% for body_podproblemu in rv.body_podproblemy_iter.next %} + {{ body_podproblemu }} + {% endfor %} + {# TODELETE #} + {% endfor %} {{ rv.body_cislo }} - {{ rv.body_celkem_rocnik }} + {{ rv.body_rocnik }} {{ rv.body_celkem_odjakziva }}
    + + {# TODELETE #} + + {# TODELETE #} + {% endif %} - {% if not cislo.verejna_vysledkovka and user.is_staff %} + {% if not cislo.verejna_vysledkovka and user.je_org %}
    {% endif %} -
    -{% endblock content %} - +
    +{% endblock content %} diff --git a/seminar/templates/seminar/archiv/cislo_obalkovani.html b/seminar/templates/seminar/archiv/cislo_obalkovani.html index dd0b0796..e830a23e 100644 --- a/seminar/templates/seminar/archiv/cislo_obalkovani.html +++ b/seminar/templates/seminar/archiv/cislo_obalkovani.html @@ -1,4 +1,4 @@ -{% extends "seminar/archiv/base.html" %} +{% extends "base.html" %} {% block content %}

    diff --git a/seminar/templates/seminar/archiv/cislo_vysledkovka.tex b/seminar/templates/seminar/archiv/cislo_vysledkovka.tex index 7ff629d8..38eeea01 100644 --- a/seminar/templates/seminar/archiv/cislo_vysledkovka.tex +++ b/seminar/templates/seminar/archiv/cislo_vysledkovka.tex @@ -1,9 +1,9 @@ \setlength{\tabcolsep}{3pt} \begin{longtable}{|r|l|c|r|{% for p in problemy %}c@{\hskip.5em}{% endfor %}|r|r|}\hline -& & & & \multicolumn{ {{ problemy|length}} }{c|}{\textbf{Témata}} & & \\\textbf{Poř.}& \textbf{Jméno}& \textbf{R.}& \raisebox{0.7mm}{$\sum_{-1}$}& {% for p in problemy %}{% if p.typ == "uloha" %}\textbf{r{{p.kod}}}&{% elif p.typ == "tema" %}\textbf{t{{p.kod}}}&{% else %}\textbf{ {{p.kod}} }&{% endif %}{% endfor %}\raisebox{0.7mm}{$\sum_0$}&\raisebox{0.7mm}{$\sum_1$}\\\hline +& & & & \multicolumn{ {{ problemy|length}} }{c|}{\textbf{Témata}} & & \\\textbf{Poř.}& \textbf{Jméno}& \textbf{R.}& \raisebox{0.7mm}{$\sum_{-1}$}& {% for p in problemy %}\textbf{ {{ p.kod_v_rocniku }} }&{% endfor %}\raisebox{0.7mm}{$\sum_0$}&\raisebox{0.7mm}{$\sum_1$}\\\hline \endhead \hline \endfoot -{% for rv in vysledkovka %}{{rv.poradi}}&\{{rv.titulmakro}}{}{{rv.resitel.inicial_krestni}} {{rv.resitel.prijmeni}}&{{rv.resitel.rocnik|default:""}}&{{rv.body_celkem_odjakziva}}&{% for b in rv.body_ulohy %}{{b}}&{% endfor %}{{rv.body_cislo}}&{{rv.body_celkem_rocnik|default:0}}\\ +{% for rv in radky_vysledkovky %}{{rv.poradi}}&{% if rv.titul %}\titul{ {{ rv.titul}}}{% endif %}{{rv.resitel.osoba.jmeno|slice:":1"}}. {{rv.resitel.osoba.prijmeni}}&{{rv.rocnik_resitele|default:""}}&{{rv.body_celkem_odjakziva}}&{% for b in rv.body_problemy_sezn %}{{b}}&{% endfor %}{{rv.body_cislo}}&{{rv.body_rocnik|default:0}}\\ {% endfor %} \end{longtable} diff --git a/seminar/templates/seminar/archiv/obalky.tex b/seminar/templates/seminar/archiv/obalky.tex index 03c2c1c6..5f2d8e07 100644 --- a/seminar/templates/seminar/archiv/obalky.tex +++ b/seminar/templates/seminar/archiv/obalky.tex @@ -97,25 +97,29 @@ {% for r in resitele %} + {% with o=r.osoba %} + {% with s=r.osoba.skola %} {% spaceless %} {% if r.zasilat == "do_skoly" %} {% if r.stat == "CZ" %} -\obalka{{r.jmeno|sloz}}{{r.prijmeni|sloz}}{{r.skola.nazev|sloz}}{{r.skola.ulice|sloz}}{{r.skola.psc|sloz}}{{r.skola.mesto|sloz}}{{''|sloz}} +\obalka{{o.jmeno|sloz}}{{o.prijmeni|sloz}}{{s.nazev|sloz}}{{s.ulice|sloz}}{{s.psc|sloz}}{{s.mesto|sloz}}{{''|sloz}} {% else %} -\obalka{{r.jmeno|sloz}}{{r.prijmeni|sloz}}{{r.skola.nazev|sloz}}{{r.skola.ulice|sloz}}{{r.skola.psc|sloz}}{{r.skola.mesto|sloz}}{{r.stat.name|sloz}} +\obalka{{o.jmeno|sloz}}{{o.prijmeni|sloz}}{{s.nazev|sloz}}{{s.ulice|sloz}}{{s.psc|sloz}}{{s.mesto|sloz}}{{o.stat.name|sloz}} {% endif %} {% elif r.zasilat == "domu" %} {% if r.stat == "CZ" %} -\obalka{{r.jmeno|sloz}}{{r.prijmeni|sloz}}{{''|sloz}}{{r.ulice|sloz}}{{r.psc|sloz}}{{r.mesto|sloz}}{{''|sloz}} +\obalka{{o.jmeno|sloz}}{{o.prijmeni|sloz}}{{''|sloz}}{{o.ulice|sloz}}{{o.psc|sloz}}{{o.mesto|sloz}}{{''|sloz}} {% else %} -\obalka{{r.jmeno|sloz}}{{r.prijmeni|sloz}}{{''|sloz}}{{r.ulice|sloz}}{{r.psc|sloz}}{{r.mesto|sloz}}{{r.stat.name|sloz}} +\obalka{{o.jmeno|sloz}}{{o.prijmeni|sloz}}{{''|sloz}}{{o.ulice|sloz}}{{o.psc|sloz}}{{o.mesto|sloz}}{{o.stat.name|sloz}} {% endif %} {% else %} % zasilat: {{r.zasilat}} %\obalka{{r.jmeno|sloz}}{{r.prijmeni|sloz}}{{''|sloz}}{{r.ulice|sloz}}{{r.psc|sloz}}{{r.mesto|sloz}}{{r.stat.name|sloz}} {% endif %} {% endspaceless %} + {% endwith %} + {% endwith %} {% endfor %} \end{document} diff --git a/seminar/templates/seminar/archiv/odmeny.html b/seminar/templates/seminar/archiv/odmeny.html new file mode 100644 index 00000000..fab1cb7c --- /dev/null +++ b/seminar/templates/seminar/archiv/odmeny.html @@ -0,0 +1,15 @@ +{% extends "base.html" %} + +{% block content %} +

    + {% block nadpis1a %}{% block nadpis1b %} + Odměny {{ cislo }} + {% endblock %}{% endblock %} +

    +
      + {% for z in zmeny %} +
    • {{z.jmeno}}: {{z.ftitul}} → {{z.ttitul}}
    • + {% endfor %} +
    + +{% endblock content %} diff --git a/seminar/templates/seminar/archiv/prispevek.html b/seminar/templates/seminar/archiv/prispevek.html index fdf2b3f2..141ae709 100644 --- a/seminar/templates/seminar/archiv/prispevek.html +++ b/seminar/templates/seminar/archiv/prispevek.html @@ -1,4 +1,4 @@ -{% extends "seminar/archiv/base_temata.html" %} +{% extends "base.html" %} {% block title %} {{prispevek.nazev}} diff --git a/seminar/templates/seminar/archiv/problem.html b/seminar/templates/seminar/archiv/problem.html index bc921203..1aa94219 100644 --- a/seminar/templates/seminar/archiv/problem.html +++ b/seminar/templates/seminar/archiv/problem.html @@ -1,13 +1,13 @@ -{% extends "seminar/archiv/base_ulohy.html" %} +{% extends "base.html" %} {% load comments %} {% block content %} -
    +
    {% block problem %} {% endblock %} - {% if user.is_staff %} + {% if user.je_org %}

    Text - org

    diff --git a/seminar/templates/seminar/archiv/problem_tema.html b/seminar/templates/seminar/archiv/problem_tema.html new file mode 100644 index 00000000..421d73bd --- /dev/null +++ b/seminar/templates/seminar/archiv/problem_tema.html @@ -0,0 +1,19 @@ +{% extends "seminar/archiv/problem.html" %} + +{% block problem %} +

    + {% block nadpis1a %}{% block nadpis1b %} + {{ problem.nazev_typu }} {{ problem.kod_v_rocniku }}: {{ problem.nazev }} + {% endblock %}{% endblock %} +

    + +

    Zadání

    + {{ problem.text_zadani |safe }} + {% if problem.text_reseni %} +

    Řešení

    + {{ problem.text_reseni |safe }} + {% endif %} + + {# TODO vysledkovka tematu #} + +{% endblock %} diff --git a/seminar/templates/seminar/archiv/problem_uloha.html b/seminar/templates/seminar/archiv/problem_uloha.html new file mode 100644 index 00000000..df5e97f7 --- /dev/null +++ b/seminar/templates/seminar/archiv/problem_uloha.html @@ -0,0 +1,23 @@ +{% extends "seminar/archiv/problem.html" %} + +{% block problem %} +

    + {% block nadpis1a %}{% block nadpis1b %} + {{ problem.nazev_typu }} {{ problem.kod_v_rocniku }}: {{ problem.nazev }} {{ problem.body_v_zavorce }} + {% endblock %}{% endblock %} +

    + {% if problem.cislo_zadani %} +

    Zadáno v čísle {{ problem.cislo_zadani.kod }}. + {% endif %} + {% if problem.cislo_reseni %} +

    Řešeno v čísle {{ problem.cislo_reseni.kod }}. + {% endif %} + +

    Zadání

    + {{ problem.text_zadani |safe }} + {% if problem.text_reseni %} +

    Řešení

    + {{ problem.text_reseni |safe }} + {% endif %} + +{% endblock %} diff --git a/seminar/templates/seminar/archiv/rocnik.html b/seminar/templates/seminar/archiv/rocnik.html index e5289277..2af9edfa 100644 --- a/seminar/templates/seminar/archiv/rocnik.html +++ b/seminar/templates/seminar/archiv/rocnik.html @@ -1,37 +1,73 @@ -{% extends "seminar/archiv/base_cisla.html" %} +{% extends "base.html" %} {% block content %}
    -

    +

    {% block nadpis1a %}{% block nadpis1b %} - Ročník {{ rocnik.roman }} + Ročník {{ rocnik }} {% endblock %}{% endblock %} -

    + -

    Ročník číslo {{ rocnik.rocnik }} ({{ rocnik.prvni_rok }}/{{ rocnik.druhy_rok }}) - -

      - {% for c in rocnik.verejna_cisla %} -
    • Číslo {{ c.kod }} - {% if c.pdf %} - (pdf) - {% endif %} - {% endfor %} -
    - - {% if temata_v_rocniku %} + {% if rocnik.temata %}

    Témata

    {% endif %} +

    Čísla

    + +
    + {% for c in rocnik.verejna_cisla %} +
    + +
    Číslo {{ c.kod }}
    + +
    + +
    +
    + +
    + {% if c.titulka_nahled %} + {{ c.kod }} + {% else %} + {% load static %} no-picture + {% endif %} +
    + +
    +
    + +
    + +
    + + +
    +
    +
    +
    + + {% endfor %} +
    + + {% if vysledkovka %} - {% if user.is_staff %} + {% if user.je_org %} {% endif %} @@ -39,10 +75,10 @@ {% include "seminar/vysledkovka_rocnik.html" %} {% endif %} - {% if user.is_staff and vysledkovka_s_neverejnymi %} + {% if user.je_org and vysledkovka_s_neverejnymi %}

    Výsledková listina včetně neveřejných bodů

    - {% with vysledkovka_s_neverejnymi as vysledkovka %} + {% with radky_vyledkovky_s_neverejnymi as radky_vysledkovky %} {% include "seminar/vysledkovka_rocnik.html" %} {% endwith %}
    @@ -50,7 +86,3 @@
    {% endblock content %} - - - - diff --git a/seminar/templates/seminar/archiv/rocnik_vysledkovka.tex b/seminar/templates/seminar/archiv/rocnik_vysledkovka.tex index 925db3b1..61c9abbb 100644 --- a/seminar/templates/seminar/archiv/rocnik_vysledkovka.tex +++ b/seminar/templates/seminar/archiv/rocnik_vysledkovka.tex @@ -1,13 +1,12 @@ {% with lb="{" %} {% with rb="}" %} \setlength{\tabcolsep}{3pt} -\begin{longtable}{|r|l|c|r|{% for cislo in vysledkovka.cisla %}c{% if not forloop.last %}@{\hskip.5em}{% endif %}{% endfor %}|r|} -\hline -& & & & \multicolumn{{ lb }}{{ vysledkovka.cisla|length }}}{c|}{\textbf{Číslo}} & \\\textbf{Poř.} & \textbf{Jméno} & \textbf{R.} & \raisebox{0.7mm}{$\sum_{-1}$} & {% for cislo in vysledkovka.cisla %}\textbf{{ lb }}{{ cislo.cislo }}{{ rb }} & {% endfor %}\raisebox{0.7mm}{$\sum_1$} \\\hline +\begin{longtable}{|r|l|c|r|{% for cislo in cisla %}c{% if not forloop.last %}@{\hskip.5em}{% endif %}{% endfor %}|r|}\hline +& & & & \multicolumn{{ lb }}{{ cisla|length }}}{c|}{\textbf{Číslo}} & \\\textbf{Poř.} & \textbf{Jméno} & \textbf{R.} & \raisebox{0.7mm}{$\sum_{-1}$} & {% for cislo in cisla %}\textbf{{ lb }}{{ cislo.poradi }}{{ rb }} & {% endfor %}\raisebox{0.7mm}{$\sum_1$} \\\hline \endhead \hline \endfoot -{% for rv in vysledkovka.radky %}{{ rv.poradi }} & \{{rv.titulmakro}}{}{{ rv.resitel.jmeno|slice:":1" }}.~{{ rv.resitel.prijmeni }} & {% if rv.resitel.rocnik %}{{ rv.resitel.rocnik }}.{% endif %} & {{ rv.body_odjakziva }} {% for b in rv.body_cisla %} & {{ b }}{% endfor %} & {{ rv.body_rocnik }} \\ +{% for rv in radky_vysledkovky %}{{ rv.poradi }} & {% if rv.titul %}\titul{{ lb }}{{ rv.titul }}}~{% endif %}{{ rv.resitel.osoba.jmeno|slice:":1" }}.~{{ rv.resitel.osoba.prijmeni }} & {% if rv.rocnik_resitele %}{{ rv.rocnik_resitele }}{% endif %} & {{ rv.body_celkem_odjakziva }} {% for b in rv.body_cisla_sezn %} & {{ b }}{% endfor %} & {{ rv.body_rocnik }} \\ {% endfor %}\end{longtable} {% endwith %} {% endwith %} diff --git a/seminar/templates/seminar/archiv/submenu.html b/seminar/templates/seminar/archiv/submenu.html deleted file mode 100644 index f9c1d450..00000000 --- a/seminar/templates/seminar/archiv/submenu.html +++ /dev/null @@ -1,14 +0,0 @@ -{% with "/archiv" as cesta %} - - - -{% endwith %} - - diff --git a/seminar/templates/seminar/archiv/temata.html b/seminar/templates/seminar/archiv/temata.html index 21aebb22..62db7d41 100644 --- a/seminar/templates/seminar/archiv/temata.html +++ b/seminar/templates/seminar/archiv/temata.html @@ -1,4 +1,4 @@ -{% extends "seminar/archiv/base_temata.html" %} +{% extends "base.html" %} {% block content %}

    @@ -7,17 +7,13 @@ {% endblock %}{% endblock%}

    - {% for tema in object_list %} - {% with tema.cislo_zadani.rocnik.rocnik as rocnik %} - {% ifchanged rocnik %} - {% if not forloop.first %}{% endif %} -

    {{ rocnik }}. ročník

    - {% endblock content %} diff --git a/seminar/templates/seminar/archiv/tituly.tex b/seminar/templates/seminar/archiv/tituly.tex index 72b1cdde..aca444df 100644 --- a/seminar/templates/seminar/archiv/tituly.tex +++ b/seminar/templates/seminar/archiv/tituly.tex @@ -1,6 +1,5 @@ {% if broken %} -%% POZOR! %% Dva resitele maji stejne makro!!! -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +POZOR! Kolize jmen! Dva řešitelé mají stejné makro! {% endif %} {% autoescape off %} diff --git a/seminar/templates/seminar/clanky/base.html b/seminar/templates/seminar/clanky/base.html deleted file mode 100644 index 844a99d5..00000000 --- a/seminar/templates/seminar/clanky/base.html +++ /dev/null @@ -1,10 +0,0 @@ -{% extends "base.html" %} - -{% block menu_clanky %}selected{% endblock %} - -{# zmena fotky #}{% block header %}clanky{% endblock %} - -{% block submenu %} - {% include "seminar/clanky/submenu.html" %} -{% endblock %} - diff --git a/seminar/templates/seminar/clanky/organizatorske_clanky.html b/seminar/templates/seminar/clanky/organizatorske_clanky.html index 53f74009..f2e00104 100644 --- a/seminar/templates/seminar/clanky/organizatorske_clanky.html +++ b/seminar/templates/seminar/clanky/organizatorske_clanky.html @@ -1,11 +1,5 @@ {% extends 'seminar/clanky/resitelske_clanky.html' %} -{% block submenu %} - {% with "org" as selected %} - {% include "seminar/clanky/submenu.html" %} - {% endwith %} -{% endblock submenu %} - {% block nadpis1a %}{% block nadpis1b %} Organizátorské články {% endblock %}{% endblock %} diff --git a/seminar/templates/seminar/clanky/resitelske_clanky.html b/seminar/templates/seminar/clanky/resitelske_clanky.html index 1e15fcbc..610f9b25 100644 --- a/seminar/templates/seminar/clanky/resitelske_clanky.html +++ b/seminar/templates/seminar/clanky/resitelske_clanky.html @@ -1,13 +1,5 @@ {% extends 'base.html' %} -{% block menu_clanky %}selected{% endblock %} - -{% block submenu %} - {% with "resitel" as selected %} - {% include "seminar/clanky/submenu.html" %} - {% endwith %} -{% endblock submenu %} - {% block content %}

    @@ -17,15 +9,28 @@

    {% for clanek in object_list %} -{% with clanek.cislo_zadani.rocnik.rocnik as rocnik %} - {% ifchanged rocnik %} - {% if not forloop.first %}{% endif %} -

    {{ rocnik }}. ročník

    -
      - {% endifchanged %} -
    • - {{ clanek.nazev }} -{% endwith %} + {% with clanek.cislo.rocnik.rocnik as rocnik %} + {% ifchanged rocnik %} + {% if not forloop.first %}
    {% endif %} +

    {{ rocnik }}. ročník

    + diff --git a/seminar/templates/seminar/clanky/submenu.html b/seminar/templates/seminar/clanky/submenu.html deleted file mode 100644 index 6bf52df3..00000000 --- a/seminar/templates/seminar/clanky/submenu.html +++ /dev/null @@ -1,14 +0,0 @@ -{% with "/clanky" as cesta %} - - - -{% endwith %} - - diff --git a/seminar/templates/seminar/cojemam/base.html b/seminar/templates/seminar/cojemam/base.html deleted file mode 100644 index 9a9c01c0..00000000 --- a/seminar/templates/seminar/cojemam/base.html +++ /dev/null @@ -1,6 +0,0 @@ -{% extends "base.html" %} - -{% block submenu %} - {% include "seminar/cojemam/submenu.html" %} -{% endblock %} - diff --git a/seminar/templates/seminar/cojemam/organizatori.html b/seminar/templates/seminar/cojemam/organizatori.html index 4f3709a4..96b7c5be 100644 --- a/seminar/templates/seminar/cojemam/organizatori.html +++ b/seminar/templates/seminar/cojemam/organizatori.html @@ -1,4 +1,4 @@ -{% extends "seminar/cojemam/base.html" %} +{% extends "base.html" %} {% block nadpis1a %}{% block nadpis1b %} {% if aktivni %} Organizátoři @@ -7,74 +7,82 @@ {% endif %} {% endblock%}{% endblock%} -{# podbarveni menu a submenu #} -{% block menu_uvod %}selected{% endblock %} -{% block submenu %} - {% with "org" as selected %} - {% include "seminar/cojemam/submenu.html" %} - {% endwith %} -{% endblock %} - -{# zmena fotky #}{% block header %}cojemam{% endblock %} {% block content %} -
    + {% if not aktivni %} - Aktivní organizátoři
    +
    + Aktivní organizátoři

    {% endif %} + +
    {% for org in object_list %} -

    - {{org.user.first_name}} - {% if org.prezdivka %} - „{{org.prezdivka}}“ +
    + +

    + {{org.osoba.jmeno}} + {% if org.osoba.prezdivka %} + „{{org.osoba.prezdivka}}“ {% endif %} - {{org.user.last_name}} -

    - - - - - -
    -
    - {% if org.foto %} - {# #} - {{org.user.first_name}} {{org.user.last_name}} + {{org.osoba.prijmeni}} + + +
    + {% if org.osoba.email %} + {# zobrazeni e-mailu (na jednom radku, aby nevznikaly mezery navic) #} + {% for znak in org.osoba.email %}{% if znak == '@' %}@{% else %}{{znak}}{% endif %}{% endfor %} + {% endif %} +
    + + {# karta organizátora - zepředu fotka, zezadu popis, u neaktivních data kdy organizovali #} + +
    + +
    +
    + +
    + {% if org.osoba.foto %} + {{org.osoba.jmeno}} {{org.osoba.prijmeni}} + {% else %} {# pokud osoba nemá fotku, zobrazuje se defaultní obrázek #} + {% load static %} {{org.osoba.jmeno}} {{org.osoba.prijmeni}} {% endif %}
    -
    -
      - {% if aktivni %} - {% if org.organizuje_od_roku %} -
    • - Organizuje od roku {{org.organizuje_od_roku}} + + +
      + +
      + {% if aktivni %} + {% if org.strucny_popis_organizatora %} + {{org.strucny_popis_organizatora}} {% endif %} - {% else %} -
    • - Aktivní v letech {{org.organizuje_od_roku | default:"?" }}–{{org.organizuje_do_roku | default:"?" }} - {% endif %} - {% if org.studuje %} -
    • {{org.studuje}} - {% endif %} - {% if org.user.email %} -
    • Pošta: - {# zobrazeni e-mailu (na jednom radku, aby nevznikaly mezery navic) #} - {% for znak in org.user.email %}{% if znak == '@' %} <zavináč> {% elif znak == '.' %} <tečka> {% else %}{{znak}}{% endif %}{% endfor %} - {% endif %} -
    - {# {{org.strucny_popis_organizatora}} #} -
    + {% if org.organizuje_od %} + Organizuji od roku {{org.organizuje_od.year}}. + {% endif %} + {% else %} + Aktivní {{org.organizuje_od.year | default:"?" }}–{{org.organizuje_do.year | default:"?" }} + {% endif %} +
    + +

    +
    +
    + {# konec karty organizátora #} +
    +
    + + {% endfor %} - {% if aktivni%} - Vysloužilí organizátoři +
    + +{% if aktivni%} +Vysloužilí organizátoři {% else %} - Aktivní organizátoři + Aktivní organizátoři {% endif %} - - {% endblock content %} - diff --git a/seminar/templates/seminar/cojemam/submenu.html b/seminar/templates/seminar/cojemam/submenu.html deleted file mode 100644 index bb39224e..00000000 --- a/seminar/templates/seminar/cojemam/submenu.html +++ /dev/null @@ -1,16 +0,0 @@ -{% with "/co-je-MaM" as cesta %} - - - -{% endwith %} - - diff --git a/seminar/templates/seminar/formular_ok.html b/seminar/templates/seminar/formular_ok.html new file mode 100644 index 00000000..be5f949f --- /dev/null +++ b/seminar/templates/seminar/formular_ok.html @@ -0,0 +1,13 @@ +{% extends "base.html" %} + +{% block nadpis1a %}Formulář byl odeslán{% endblock %} + +{% block content %} +

    Formulář byl úspěšně odeslán

    +{% if text %} +

    {{ text | safe }}

    +{% endif %} +{% for odkaz in odkazy %} +

    {{odkaz.0}}

    +{% endfor %} +{% endblock %} diff --git a/seminar/templates/seminar/jak-resit.html b/seminar/templates/seminar/jak-resit.html new file mode 100644 index 00000000..eb7b7259 --- /dev/null +++ b/seminar/templates/seminar/jak-resit.html @@ -0,0 +1,16 @@ +{% extends 'base.html' %} + +{% load humanize %} +{% load staticfiles %} + + +{% block content %} + +
    + + + + + +
    +{% endblock %} diff --git a/seminar/templates/seminar/novinky.html b/seminar/templates/seminar/novinky.html index ccf40831..c1e5b663 100644 --- a/seminar/templates/seminar/novinky.html +++ b/seminar/templates/seminar/novinky.html @@ -1,15 +1,15 @@ {% for novinka in object_list %} {# pripravene div-y na stylovani#}
    - {% if not novinka.zverejneno and user.is_staff %} + {% if not novinka.zverejneno and user.je_org %}
    {% endif %} - {% if novinka.zverejneno or user.is_staff %} + {% if novinka.zverejneno or user.je_org %} {# datum #} -
    {{novinka.datum}}
    +
    {{novinka.datum}}
    {# text #} {{ novinka.text | safe }} {# obrazek #} @@ -25,15 +25,15 @@
    {% endif %} {# autor #} -

    {{novinka.autor.first_name}} - {% if novinka.autor.organizator.prezdivka%} - „{{novinka.autor.organizator.prezdivka}}“ +

    + {{novinka.autor.osoba.jmeno}} + {% if novinka.autor.osoba.prezdivka%} + „{{novinka.autor.osoba.prezdivka}}“ {% endif %} - {{novinka.autor.last_name}} -

    + {{novinka.autor.osoba.prijmeni}}
    {% endif %} - {% if not novinka.zverejneno and user.is_staff %} + {% if not novinka.zverejneno and user.je_org %}
    {% endif %}
    diff --git a/seminar/templates/seminar/odevzdavatko/detail.html b/seminar/templates/seminar/odevzdavatko/detail.html new file mode 100644 index 00000000..14094fb8 --- /dev/null +++ b/seminar/templates/seminar/odevzdavatko/detail.html @@ -0,0 +1,117 @@ +{% extends "base.html" %} +{% load static %} +{% load deadliny %} + +{% block content %} + +{# FIXME: Necopypastovat! Tohle je zkopírované ze static/seminar/dynamic_formsets.js #} + + + +

    Řešené problémy: {{ object.problem.all | join:", " }}

    + +

    Řešitelé: {{ object.resitele.all | join:", " }}

    + +{# https://docs.djangoproject.com/en/3.1/ref/models/instances/#django.db.models.Model.get_FOO_display #} +

    Forma: {{ object.get_forma_display }}

    + +

    Doručeno {{ object.cas_doruceni }}, deadline: {{object.cas_doruceni | deadline_html }}

    + +{# Soubory: #} +

    Přílohy:

    +{% if object.prilohy.all %} + + +{% for priloha in object.prilohy.all %} + + + + + {# TODO: Orgo-poznámka, ideálně jako formulář #} +{% endfor %} +
    SouborŘešitelova poznámkaDatum
    {{ priloha.split | last }}{{ priloha.res_poznamka }}{{ priloha.vytvoreno }}
    +{% else %} +

    Žádné přílohy

    +{% endif %} + +{# Hodnocení: #} +

    Hodnocení:

    + +{% csrf_token %} +{{ form.management_form }} +
    + +{% for subform in form %} + + + + + + +{% endfor %} +
    ProblémBodyČíslo pro body
    {{ subform.problem }}{{ subform.body }}{{ subform.cislo_body }}Smazat
    + + + Přidat hodnocení
    + + + + + + + + + + + +{% endblock %} diff --git a/seminar/templates/seminar/odevzdavatko/resitel_prehled.html b/seminar/templates/seminar/odevzdavatko/resitel_prehled.html new file mode 100644 index 00000000..229b036c --- /dev/null +++ b/seminar/templates/seminar/odevzdavatko/resitel_prehled.html @@ -0,0 +1,37 @@ +{% extends "base.html" %} +{% load static %} +{% load deadliny %} + +{% block content %} +

    Označení deadlinů

    +
      +
    • Ⓢ deadline pro účast na soustředění
    • +
    • ♲ 1. deadline
    • +
    • ✓ 2. deadline
    • +
    + +
    + +{% for rocnik, hodnoceni in podle_rocniku %} +

    Ročník {{ rocnik }}

    + + + + + + + + {% for hodn in hodnoceni %} + + + + + + + {% endfor %} +
    DoručenoProblémBodyDeadline
    {{ hodn.reseni.cas_doruceni | date:"d.m.Y H:i"}}{{ hodn.problem.nazev | zkrat_nazev_problemu }}{{ hodn.body|default_if_none:"---" }}{{ hodn.reseni.cas_doruceni | deadline_html }}
    + +
    + +{% endfor %} +{% endblock %} diff --git a/seminar/templates/seminar/odevzdavatko/seznam.html b/seminar/templates/seminar/odevzdavatko/seznam.html new file mode 100644 index 00000000..2b3f332a --- /dev/null +++ b/seminar/templates/seminar/odevzdavatko/seznam.html @@ -0,0 +1,15 @@ +{% extends "base.html" %} +{% load deadliny %} + +{% block content %} + +{% for dl, mnozina_reseni in reseni_podle_deadlinu.items %} +

    {{ dl.2 | deadline_html }}

    +
      + {% for obj in mnozina_reseni %} +
    • {{ obj }} ({{ obj.get_forma_display }} {{ obj.cas_doruceni }}) + {% endfor %} +
    +{% endfor %} + +{% endblock %} diff --git a/seminar/templates/seminar/odevzdavatko/tabulka.html b/seminar/templates/seminar/odevzdavatko/tabulka.html new file mode 100644 index 00000000..5e5794e7 --- /dev/null +++ b/seminar/templates/seminar/odevzdavatko/tabulka.html @@ -0,0 +1,45 @@ +{% extends "base.html" %} + +{% load utils %} {# Možná by mohlo být někde výš v hierarchii templatů... #} + +{% block content %} + +
    +{{ filtr.resitele }} +{{ filtr.problemy }} +Od: {{ filtr.reseni_od }} +Do: {{ filtr.reseni_do }} +🔨? {{ filtr.neobodovane }} + +
    + + + + {# Prázdná buňka v levém horním rohu #} + {% for p in problemy %} + + {% endfor %} + + {% for resitel,hodnoty in radky%} + + + {% for hodn in hodnoty %} + + {% endfor %} + + {% endfor %} +
    + {# TODO: Přehled řešení k problému, odkázaný odsud? #} + {{ p }} +
    + {# TODO: Chceme mít view i na řešení konkrétního řešitele ke všem problémům? #} + {{ resitel }} + + {% if hodn %} + + {{ hodn.pocet_reseni }} řeš.
    {{ hodn.body }} b
    {{ hodn.posledni_odevzdani|kratke_datum|default_if_none:"Nikdy"|default:"???"}} +
    + {% endif %} +
    + +{% endblock %} diff --git a/seminar/templates/seminar/org/obalkovani.html b/seminar/templates/seminar/org/obalkovani.html new file mode 100644 index 00000000..fa130bc7 --- /dev/null +++ b/seminar/templates/seminar/org/obalkovani.html @@ -0,0 +1,30 @@ +{% extends "base.html" %} + +{% block content %} +

    + {% block nadpis1a %}{% block nadpis1b %} + Obálkování {{ cislo }} + {% endblock %}{% endblock %} +

    +
      + {% for reseni in object_list %} + {% ifchanged reseni.resitele %} + {% if not forloop.first %} +
    + {% endif %} +

    {% for resitel in reseni.resitele.all %}{{resitel.osoba}},{% endfor %}

    +
      + {% endifchanged %} + +
    • Celkem {{reseni.hodnoceni__body__sum}} bodů z {{reseni.hodnoceni__count}} hodnocení +
        + {% for h in reseni.hodnoceni_set.all %} +
      • {{ h.problem }}: {{ h.body }}b
      • + {% endfor %} +
      +
    • + {% endfor %} +
    + + +{% endblock content %} diff --git a/seminar/templates/seminar/org/vloz_reseni.html b/seminar/templates/seminar/org/vloz_reseni.html new file mode 100644 index 00000000..fa537cd9 --- /dev/null +++ b/seminar/templates/seminar/org/vloz_reseni.html @@ -0,0 +1,21 @@ +{% extends "base.html" %} +{% load staticfiles %} +{% block script %} + + {{form.media}} + +{% endblock %} + +{% block content %} +

    + {% block nadpis1a %}{% block nadpis1b %} + Vložit řešení + {% endblock %}{% endblock %} +

    +
    + {% csrf_token %} +{{form.as_p}} + +
    + +{% endblock %} diff --git a/seminar/templates/seminar/orgorozcestnik.html b/seminar/templates/seminar/orgorozcestnik.html new file mode 100644 index 00000000..c24ca05d --- /dev/null +++ b/seminar/templates/seminar/orgorozcestnik.html @@ -0,0 +1,94 @@ +{% extends "base.html" %} +{# FIXME: Použít ideálně reverse() ke zjišťování URL #} + +{% block content %} +

    Informace, komunikace

    + +
      +
    • wiki obsahuje různé návody a know-how
    • +
    • Riot chatování s dalšími orgy
    • +
    • Kanboard správa TODO + +
    • +
    • přidat novinku na web
    • +
    + +
    +

    Tvorba čísla

    + + +
    + +

    Moje problémy

    + +

    Témata

    +
      +{% for t in temata %} +
    • {{ t }}
    • +{% endfor %} +
    + +

    Úlohy

    +
      +{% for u in ulohy %} +
    • {{ u }}
    • +{% endfor %} +
    + +

    Články

    +
      +{% for c in clanky %} +
    • {{ c }}
    • +{% endfor %} +
    + +
    +

    Soustředění

    + + + +
    +

    Můj profil

    + + + +
    +

    Nemůžeš najít, co hledáš? Může to být v administračním rozhraní webu.

    +{% endblock content %} + diff --git a/seminar/templates/seminar/orphanage.html b/seminar/templates/seminar/orphanage.html new file mode 100644 index 00000000..8732b394 --- /dev/null +++ b/seminar/templates/seminar/orphanage.html @@ -0,0 +1,23 @@ +{% extends "seminar/archiv/base.html" %} +{% load staticfiles %} +{% load sekizai_tags %} + +{# toto z nejakeho duvodu nefunguje #} +{% addtoblock css %} +dfsdfs + +{% endaddtoblock "css" %} + +{% block custom_css %} + +{% endblock custom_css %} + +{% load comments %} + +{% block content %} +
      +{% for obj in object_list %} +
    • {{obj}} (id {{obj.id}})
    • +{% endfor %} +
    +{% endblock content %} diff --git a/seminar/templates/seminar/pracuje_se.html b/seminar/templates/seminar/pracuje_se.html index f081edea..edb98cd5 100644 --- a/seminar/templates/seminar/pracuje_se.html +++ b/seminar/templates/seminar/pracuje_se.html @@ -11,8 +11,7 @@ Na této stránce velmi intenzivně pracujeme. Za dočasnou nedostupnost se omlouváme. Zkuste přejít na titulní stránku - nebo se podívat na aktuální zadání. + nebo se podívat na aktuální zadání.

    {% endblock %} - diff --git a/seminar/templates/seminar/profil/edit.html b/seminar/templates/seminar/profil/edit.html new file mode 100644 index 00000000..9f94090e --- /dev/null +++ b/seminar/templates/seminar/profil/edit.html @@ -0,0 +1,105 @@ +{% extends "base.html" %} +{% load staticfiles %} + +{% block script %} + +{% endblock %} + + + +{% block content %} +

    + {% block nadpis1a %}{% block nadpis1b %} + Změna osobních údajů + {% endblock %}{% endblock %} +

    +
    + {% csrf_token %} + {{form.non_field_errors}} + +
    + +

    + Přihlašovací údaje +

    + + {% include "seminar/profil/prihlaska_field.html" with field=form.username %} +
    + +
    + +

    + Osobní údaje +

    + + {% include "seminar/profil/prihlaska_field.html" with field=form.jmeno %} + {% include "seminar/profil/prihlaska_field.html" with field=form.prijmeni %} + {% include "seminar/profil/prihlaska_field.html" with field=form.pohlavi_muz%} + {% include "seminar/profil/prihlaska_field.html" with field=form.email %} + {% include "seminar/profil/prihlaska_field.html" with field=form.telefon %} + {% include "seminar/profil/prihlaska_field.html" with field=form.datum_narozeni %} +
    + +
    + +

    + Bydliště +

    + + {% include "seminar/profil/prihlaska_field.html" with field=form.ulice %} + {% include "seminar/profil/prihlaska_field.html" with field=form.mesto %} + {% include "seminar/profil/prihlaska_field.html" with field=form.psc %} + {% include "seminar/profil/prihlaska_field.html" with field=form.stat %} + {% include "seminar/profil/prihlaska_field.html" with field=form.stat_text id="id_li_stat_text"%} +
    + +
    + +

    + Škola +

    + + {% include "seminar/profil/prihlaska_field.html" with field=form.skola %} + + + {% include "seminar/profil/prihlaska_field.html" with field=form.skola_nazev id="id_li_skola_nazev" %} + {% include "seminar/profil/prihlaska_field.html" with field=form.skola_adresa id="id_li_skola_adresa" %} + {% include "seminar/profil/prihlaska_field.html" with field=form.rok_maturity %} +
    Vyplň prosím celý název a adresu školy.
    + +
    + +

    + Pošta +

    + + {% include "seminar/profil/prihlaska_field.html" with field=form.zasilat %} + {% include "seminar/profil/prihlaska_field.html" with field=form.zasilat_cislo_emailem %} +
    + +
    + +

    + Zasílání propagačních materiálů +

    + + {% include "seminar/profil/prihlaska_field.html" with field=form.spam %} +
    + +
    + + +
    + +{% endblock %} diff --git a/seminar/templates/seminar/profil/gdpr.html b/seminar/templates/seminar/profil/gdpr.html new file mode 100644 index 00000000..3e85de78 --- /dev/null +++ b/seminar/templates/seminar/profil/gdpr.html @@ -0,0 +1,50 @@ +

    +TL;DR: +K tomu, abychom mohli zpracovávat Tvá data (uložit si tvou adresu, zobrazit Tvé jméno ve výsledkové listině, opravit Tvá řešení) od Tebe potřebujeme souhlas. +Pokud se zpracováváním souhlasíš dle níže uvedených podmínek, zaškrtni políčko níže. +

    +
    +

    +Získáváme od Tebe údaje vyplněné v přihlášce do semináře (jméno, příjmení, poštovní a e-mailovou adresu, školu, kterou navštěvuješ a rok maturity), případně v přihlášce na soustředění (navíc datum narození, telefonní číslo). Také uchováváme všechna řešení, která nám pošleš, a jejich hodnocení. +

    +

    +Slibujeme Ti, že Tvá osobní data nezneužijeme k ničemu, co by nesouviselo s M&M nebo s dalšími aktivitami Matfyzu, a nikdy je nepředáme nikomu cizímu. Údaje využíváme k zajištění chodu semináře a také je sdílíme s ostatními propagačními akcemi Matfyzu, abychom mohli vyhodnocovat úspěšnost akcí. Pokud budeš mít zájem, budeme Ti také posílat zajímavé zprávy a novinky týkajíci se Matfyzu. +

    +

    +Veřejně vystavujeme pouze výsledkové listiny, které také uchováváme pro archivní účely. Pokud ale z nějakého důvodu nebudeš chtít mít své jméno či školu uvedené ve výsledkové listině, není problém to zařídit, napiš nám. Z tištěných materiálů samozřejmě údaje už odstranit nemůžeme. +

    +

    +Na soustředěních a dalších akcích semináře navíc pořizujeme fotografie a videozáznamy a používáme je ke zpravodajským a propagačním účelům. Pro propagační účely si od Tebe vyžádáme samostatný souhlas na začátku akce. +

    +

    +Souhlas se zpracováním osobních údajů pro potřeby chodu semináře +

    +

    +Tímto uděluji souhlas Univerzitě Karlově, se sídlem Ovocný trh 560/5, 116 36 Praha 1, IČO 00216208 (dále jen UK), která je správcem osobních údajů všech fakult a součástí UK, ke zpracování osobních údajů pro potřeby Korespondenčního semináře M&M a Matematicko-fyzikální fakulty UK (dále jen M&M a MFF UK). +

    +

    +Tento souhlas uděluji pro všechny výše uvedené osobní údaje, a to po dobu účasti v semináři a 10 let poté, a dále souhlasím s uchováváním potřebných dat pro archivní účely i po této lhůtě (vystavené výsledkové listiny aj.). +

    +

    +MFF UK tyto údaje zpracovává za účelem evidence řešitelů a účastníků M&M, k zajištění celoročního fungování semináře, analýze účinnosti jednotlivých propagačních akcí MFF UK a zpravodajským účelům. Osobám, které o to projeví zájem v nastavení svého účtu, bude MFF UK také zasílat propagační materiály. +

    +

    +Údaje nebudou předány třetí osobě ani využívány k jiným účelům, než ke kterým byly poskytnuty. +

    +

    +Tento souhlas uděluji ze své vlastní a svobodné vůle a beru na vědomí, že jej mohu kdykoliv odvolat zasláním e-mailu na adresu mam@matfyz.cz. Stejně tak může být požadováno vymazání i z archivních údajů M&M, pokud to bude technicky možné. Beru na vědomí, že údaje z tištěných publikací není možné zpětně odstranit. +

    +

    +Dále máte právo: +

    +
      +
    • požádat o informaci, jaké osobní údaje jsou o vás zpracovávány, +
    • požadovat opravu osobních údajů, pokud jsou neplatné nebo zastaralé, +
    • požadovat, aby nebyly vaše osobní údaje zpracovávány do doby, než bude vyřešena oprávněnost výše uvedených požadavků, +
    • požadovat, aby byly vaše osobní údaje předány jinému správci, +
    • podat stížnost u dozorového úřadu. +
    +

    +V případě jakéhokoliv dotazu nebo uplatnění svých práv můžete kontaktovat pověřence pro ochranu osobních údajů na e-mailové adrese gdpr@cuni.cz. +

    +
    diff --git a/seminar/templates/seminar/profil/login.html b/seminar/templates/seminar/profil/login.html new file mode 100644 index 00000000..94374520 --- /dev/null +++ b/seminar/templates/seminar/profil/login.html @@ -0,0 +1,40 @@ +{% extends "base.html" %} +{% load staticfiles %} + + +{% block content %} +

    + {% block nadpis1a %}{% block nadpis1b %} + Přihlášení + {% endblock %}{% endblock %} +

    +{# Obšlehnuto z Admina :-) #} +{% if user.is_authenticated %} +

    K této stránce nejspíš nemáte přístup. Můžete se zkusit přihlásit jako uživatel, který přístup má.

    +{% endif %} +
    + {% csrf_token %} + + {{ form.as_table }} +
    + {# Django si posílá jméno další stránky jako obsah formuláře a výchozí hodnota (mi přišlo, že) nejde změnit... #} + + +
    + +
    +

    + Zapomněl jsem heslo +

    + +
    + +

    + Ješte nejsi zaregistrován? +

    + +
    + +
    + +{% endblock %} diff --git a/seminar/templates/seminar/profil/logout.html b/seminar/templates/seminar/profil/logout.html new file mode 100644 index 00000000..d845dc3a --- /dev/null +++ b/seminar/templates/seminar/profil/logout.html @@ -0,0 +1,18 @@ +{% extends "base.html" %} +{% load staticfiles %} + + +{% block content %} +

    + {% block nadpis1a %}{% block nadpis1b %} + Odhlášení + {% endblock %}{% endblock %} +

    + +Byl jsi úspěšně odhlášen +{# Tohle by se asi mělo udělat přes kontext (title), ale kašlu na to, stejně je to jen jednojazyčná stránka #} + +{# TODO: odkaz na znovupřihlášení? #} + +{% endblock %} + diff --git a/seminar/templates/seminar/profil/nahraj_reseni.html b/seminar/templates/seminar/profil/nahraj_reseni.html new file mode 100644 index 00000000..ebb6b6d6 --- /dev/null +++ b/seminar/templates/seminar/profil/nahraj_reseni.html @@ -0,0 +1,131 @@ +{% extends "base.html" %} +{% load staticfiles %} +{% block script %} + +{% endblock %} + +{% block content %} +

    + {% block nadpis1a %}{% block nadpis1b %} + Vložit řešení + {% endblock %}{% endblock %} +

    +
    + {% csrf_token %} + + + {% for field in form %} + + + {% endfor %} + +
    + + + {{ field }} +
    + + +
    + +{{ prilohy.management_form }} + +

    Soubory s řešením

    + +

    Maximální součet velikostí příloh je cca 49 MB.

    + +
    +{% for form in prilohy.forms %} +
    + {{ form.non_field_errors }} + {# {{ form.errors }} FIXME: možná tohle chceme zobrazovat? #} + + + {% for field in form.visible_fields %} + + + + + + + {% endfor %} + + + +
    + + + + {{ field }} + {{ field.help_text|safe }} + {{ field.errors }} + +
    +
    +{% endfor %} +
    + + + + + +
    +

    Odevzdat řešení

    + +
    + + + + +{% endblock %} diff --git a/seminar/templates/seminar/profil/prihlaska.html b/seminar/templates/seminar/profil/prihlaska.html new file mode 100644 index 00000000..423e93d9 --- /dev/null +++ b/seminar/templates/seminar/profil/prihlaska.html @@ -0,0 +1,123 @@ +{% extends "base.html" %} +{% load staticfiles %} + +{% block script %} + +{% endblock %} + + + +{% block content %} +

    + {% block nadpis1a %}{% block nadpis1b %} + Přihláška do semináře + {% endblock %}{% endblock %} +

    + +

    Tučně popsaná pole jsou povinná.

    + +
    + {% csrf_token %} + {{form.non_field_errors}} + + +
    +

    + Přihlašovací údaje +

    + + {% include "seminar/profil/prihlaska_field.html" with field=form.username %} +{# {% include "seminar/profil/prihlaska_field.html" with field=form.password %}#} +{# {% include "seminar/profil/prihlaska_field.html" with field=form.password_check %}#} +
    + +
    + +

    + Osobní údaje +

    + + {% include "seminar/profil/prihlaska_field.html" with field=form.jmeno %} + {% include "seminar/profil/prihlaska_field.html" with field=form.prijmeni %} + {% include "seminar/profil/prihlaska_field.html" with field=form.pohlavi_muz%} + {% include "seminar/profil/prihlaska_field.html" with field=form.email %} + {% include "seminar/profil/prihlaska_field.html" with field=form.telefon %} + {% include "seminar/profil/prihlaska_field.html" with field=form.datum_narozeni %} +
    + +
    + +

    + Bydliště +

    + + {% include "seminar/profil/prihlaska_field.html" with field=form.ulice %} + {% include "seminar/profil/prihlaska_field.html" with field=form.mesto %} + {% include "seminar/profil/prihlaska_field.html" with field=form.psc %} + {% include "seminar/profil/prihlaska_field.html" with field=form.stat %} + {% include "seminar/profil/prihlaska_field.html" with field=form.stat_text id="id_li_stat_text"%} +
    + +
    + +

    + Škola +

    + + {% include "seminar/profil/prihlaska_field.html" with field=form.skola %} + + + {% include "seminar/profil/prihlaska_field.html" with field=form.skola_nazev id="id_li_skola_nazev" %} + {% include "seminar/profil/prihlaska_field.html" with field=form.skola_adresa id="id_li_skola_adresa" %} + {% include "seminar/profil/prihlaska_field.html" with field=form.rok_maturity %} +
    Vyplň prosím celý název a adresu školy.
    + +
    + +

    + Pošta +

    + + {% include "seminar/profil/prihlaska_field.html" with field=form.zasilat %} + {% include "seminar/profil/prihlaska_field.html" with field=form.zasilat_cislo_emailem %} +
    +
    + +

    + GDPR +

    + {% include "seminar/profil/gdpr.html" %} + + {% include "seminar/profil/prihlaska_field.html" with field=form.gdpr %} +
    + +
    + +

    + Zasílání propagačních materiálů +

    + + {% include "seminar/profil/prihlaska_field.html" with field=form.spam %} +
    + + + +
    + + +
    + + + +{% endblock %} diff --git a/seminar/templates/seminar/profil/prihlaska_field.html b/seminar/templates/seminar/profil/prihlaska_field.html new file mode 100644 index 00000000..21851eeb --- /dev/null +++ b/seminar/templates/seminar/profil/prihlaska_field.html @@ -0,0 +1,20 @@ + + + + + + + + {{ field }} + {{ field.help_text|safe }} + + + + +{% if field.errors %} + + {{ field.errors }} + +{% endif %} diff --git a/seminar/templates/seminar/profil/resitel.html b/seminar/templates/seminar/profil/resitel.html new file mode 100644 index 00000000..54a4a865 --- /dev/null +++ b/seminar/templates/seminar/profil/resitel.html @@ -0,0 +1,19 @@ +{% extends "base.html" %} +{% load staticfiles %} + + +{% block content %} +

    + {% block nadpis1a %}{% block nadpis1b %} + Stránka řešitele - {{ object.osoba.jmeno }} {{ object.osoba.prijmeni }} + {% endblock %}{% endblock %} +

    + +Odhlásit se
    +Upravit údaje
    +Poslat řešení
    +Již odevzdaná řešení
    + + +{% endblock %} + diff --git a/seminar/templates/seminar/registrace/nove_heslo.html b/seminar/templates/seminar/registrace/nove_heslo.html new file mode 100644 index 00000000..243f1373 --- /dev/null +++ b/seminar/templates/seminar/registrace/nove_heslo.html @@ -0,0 +1,22 @@ +{% extends "base.html" %} +{% block title %}Zadej nové heslo{% endblock %} + +{% block content %} +

    + {% block nadpis1a %}{% block nadpis1b %} + Zadej nové heslo + {% endblock %}{% endblock %} +

    + +

    Zadej dvakrát nové heslo. Tak ověříme, že bylo zadáno správně.

    + + +
    + {% csrf_token %} + + {{ form.as_table }} +
    + +
    + +{% endblock %} diff --git a/seminar/templates/seminar/registrace/nove_nastaveno.html b/seminar/templates/seminar/registrace/nove_nastaveno.html new file mode 100644 index 00000000..0d782c89 --- /dev/null +++ b/seminar/templates/seminar/registrace/nove_nastaveno.html @@ -0,0 +1,15 @@ +{% extends "base.html" %} +{% block title %}Heslo bylo nastaveno{% endblock %} + +{% block content %} +

    + {% block nadpis1a %}{% block nadpis1b %} + Heslo bylo nastaveno + {% endblock %}{% endblock %} +

    + +

    Vaše heslo bylo nastaveno. Nyní se můžete přihlásit.

    + +

    Přihlášení

    + +{% endblock %} diff --git a/seminar/templates/seminar/registrace/password_reset_email.html b/seminar/templates/seminar/registrace/password_reset_email.html new file mode 100644 index 00000000..282b0b8a --- /dev/null +++ b/seminar/templates/seminar/registrace/password_reset_email.html @@ -0,0 +1,8 @@ +Ahoj! + +Obdrželi jsme od tebe žádost o obnovu hesla uživatele {{ user }} na webu M&M. +Pro zadání nového hesla přejdi na následující stránku: +{{ protocol}}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %} + +S pozdravem +organizátoři M&M \ No newline at end of file diff --git a/seminar/templates/seminar/registrace/password_reset_subject.txt b/seminar/templates/seminar/registrace/password_reset_subject.txt new file mode 100644 index 00000000..52fadd6d --- /dev/null +++ b/seminar/templates/seminar/registrace/password_reset_subject.txt @@ -0,0 +1 @@ +Změna hesla na webu M&M diff --git a/seminar/templates/seminar/registrace/reset_hesla.html b/seminar/templates/seminar/registrace/reset_hesla.html new file mode 100644 index 00000000..a35db5c6 --- /dev/null +++ b/seminar/templates/seminar/registrace/reset_hesla.html @@ -0,0 +1,17 @@ +{% extends "base.html" %} +{% block title %}Zapomněl jsi své heslo?{% endblock %} + +{% block content %} +

    + {% block nadpis1a %}{% block nadpis1b %} + Zapomněl jsi své heslo? + {% endblock %}{% endblock %} +

    + +
    + {% csrf_token %} + {{ form.as_p }} + +
    + +{% endblock %} diff --git a/seminar/templates/seminar/registrace/reset_poslan.html b/seminar/templates/seminar/registrace/reset_poslan.html new file mode 100644 index 00000000..3f9567cd --- /dev/null +++ b/seminar/templates/seminar/registrace/reset_poslan.html @@ -0,0 +1,15 @@ +{% extends "base.html" %} +{% block title %}Zpráva s obnovením hesla byla odeslána{% endblock %} + +{% block content %} +

    + {% block nadpis1a %}{% block nadpis1b %} + Zpráva s obnovením hesla byla odeslána + {% endblock %}{% endblock %} +

    + +

    Návod na nastavení hesla byl odeslán na zadanou e-mailovou adresu, pokud účet s takovou adresou existuje. Měl by za okamžik dorazit.

    + +

    Pokud e-mail neobdržíte, ujistěte se, že zadaná e-mailová adresa je stejná jako ta registrovaná u vašeho účtu a zkontrolujte složku nevyžádané pošty, tzv. spamu.

    + +{% endblock %} diff --git a/seminar/templates/seminar/soustredeni/base.html b/seminar/templates/seminar/soustredeni/base.html deleted file mode 100644 index 4fb36650..00000000 --- a/seminar/templates/seminar/soustredeni/base.html +++ /dev/null @@ -1,6 +0,0 @@ -{% extends "base.html" %} - -{% block submenu %} - {% include "seminar/soustredeni/submenu.html" %} -{% endblock %} - diff --git a/seminar/templates/seminar/soustredeni/maily_ucastniku.txt b/seminar/templates/seminar/soustredeni/maily_ucastniku.txt index 8060ce2a..74c25c91 100644 --- a/seminar/templates/seminar/soustredeni/maily_ucastniku.txt +++ b/seminar/templates/seminar/soustredeni/maily_ucastniku.txt @@ -1 +1 @@ -{% for sous_ucast in object_list %}{{ sous_ucast.resitel.email }}{% if not forloop.last %}, {% endif %}{% endfor %} +{% for sous_ucast in object_list %}{{ sous_ucast.resitel.osoba.email }}{% if not forloop.last %}, {% endif %}{% endfor %} diff --git a/seminar/templates/seminar/soustredeni/seznam_soustredeni.html b/seminar/templates/seminar/soustredeni/seznam_soustredeni.html index 538843bd..9ddbcca9 100644 --- a/seminar/templates/seminar/soustredeni/seznam_soustredeni.html +++ b/seminar/templates/seminar/soustredeni/seznam_soustredeni.html @@ -1,11 +1,4 @@ -{% extends "seminar/soustredeni/base.html" %} - -{% block menu_soustredeni %}selected{% endblock %} -{% block submenu %} - {% with "probehlo" as selected %} - {% include "seminar/soustredeni/submenu.html" %} - {% endwith %} -{% endblock submenu %} +{% extends "base.html" %} {# zmena fotky #}{% block header %}soustredeni{% endblock %} @@ -17,8 +10,8 @@ {# Projdi vsechna soustredeni #} {% for soustredeni in object_list %} {# Kdyz je verejne -> zobraz #} - {% if soustredeni.verejne_db or user.is_staff %} - {% if not soustredeni.verejne_db and user.is_staff %} + {% if soustredeni.verejne_db or user.je_org %} + {% if not soustredeni.verejne_db and user.je_org %}
    {% endif %} @@ -34,8 +27,8 @@ {# Zobrazeni odkazu na galerie #} {% if soustredeni.galerie_set.all %} {% for galerie in soustredeni.galerie_set.all %} - {% if galerie.zobrazit == 0 or user.is_staff %} -
  • 0 and user.is_staff %}class="mam-org-only"{% endif %}> + {% if galerie.zobrazit == 0 or user.je_org %} +
  • 0 and user.je_org %}class="mam-org-only"{% endif %}> Fotogalerie {# TODO kdyz je titulni obrazek, tak asi i titulni obrazek #}
  • @@ -43,7 +36,7 @@ {% endfor %} {% endif %} - {% if user.is_staff %} + {% if user.je_org %} {% endif %} @@ -60,7 +53,7 @@ {% if soustredeni.text %} {% autoescape off %}{{soustredeni.text}}{% endautoescape %} {% endif %} - {% if user.is_staff %} + {% if user.je_org %}
    {# Účastníci #}

    Soustředění se zúčastnili tito účastníci:

    @@ -82,7 +75,7 @@
    {% endif %} - {% if not soustredeni.verejne_db and user.is_staff %} + {% if not soustredeni.verejne_db and user.je_org %}
    {# class="mam-org-only" #} {% endif %} {% endif %} diff --git a/seminar/templates/seminar/soustredeni/seznam_ucastniku.html b/seminar/templates/seminar/soustredeni/seznam_ucastniku.html index 346b348b..9ab638ab 100644 --- a/seminar/templates/seminar/soustredeni/seznam_ucastniku.html +++ b/seminar/templates/seminar/soustredeni/seznam_ucastniku.html @@ -25,7 +25,7 @@ {{sous_ucast.resitel}} {{sous_ucast.resitel.rok_maturity}} - {{sous_ucast.resitel.telefon}} + {{sous_ucast.resitel.osoba.telefon}} {{sous_ucast.poznamka}} @@ -35,7 +35,6 @@ Žádní účastníci nebyli... {% endfor %} - diff --git a/seminar/templates/seminar/soustredeni/submenu.html b/seminar/templates/seminar/soustredeni/submenu.html deleted file mode 100644 index a507a2fb..00000000 --- a/seminar/templates/seminar/soustredeni/submenu.html +++ /dev/null @@ -1,11 +0,0 @@ -{% with "/soustredeni" as cesta %} - - - -{% endwith %} diff --git a/seminar/templates/seminar/tematka/rozcestnik.html b/seminar/templates/seminar/tematka/rozcestnik.html new file mode 100644 index 00000000..b9d97e5f --- /dev/null +++ b/seminar/templates/seminar/tematka/rozcestnik.html @@ -0,0 +1,54 @@ +{% extends "base.html" %} + + +{% block content %} + +

    + {% block nadpis1a %}{% block nadpis1b %} + Aktuální témata + {% endblock %}{% endblock %} +

    + +

    Témata jsou texty nejen z oblasti matematiky, fyziky a informatiky, které popisují nějaký + problém a jsou doprovázeny návodnými úlohami. Vaším úkolem je zamyslet se nad daným + problémem a sepsat vaše úvahy ve formě krátkého textu.

    + +

    Jak řešit téma?

    + + +
    + +{% for tematko in tematka %} + +{# karta témátka - zepředu ilustrační, zezadu abstrakt #} +
    + +

    + Téma {{ tematko.nazev }} +

    + +
    + +
    +
    +
    + {% if tematko.obrazek %} + {{ tematko.nazev }} + {% else %} {# pokud témátko nemá fotku, zobrazuje se defaultní obrázek #} + {% load static %} {{ tematko.nazev }} + {% endif %} +
    +
    +
    +

    {{ tematko.abstrakt }}

    +
    +
    + +
    +
    +{# konec karty témátka #} +{% endfor %} + +
    + +{% endblock %} diff --git a/seminar/templates/seminar/tematka/toaletak.html b/seminar/templates/seminar/tematka/toaletak.html new file mode 100644 index 00000000..8b556c6c --- /dev/null +++ b/seminar/templates/seminar/tematka/toaletak.html @@ -0,0 +1 @@ +Stránká témátka diff --git a/seminar/templates/seminar/titulnistrana.html b/seminar/templates/seminar/titulnistrana.html index 5ba97aca..81e522d5 100644 --- a/seminar/templates/seminar/titulnistrana.html +++ b/seminar/templates/seminar/titulnistrana.html @@ -1,3 +1,12 @@ + + {% extends 'base.html' %} {% load humanize %} @@ -5,66 +14,94 @@ {% block content %} - {# Uvitaci text #} + +{% if nejblizsi_deadline %} +
    +
    +

    Do + {% if typ_deadline == 'soustredeni' %} + + deadlinu odeslání řešení + pro účast na soustředění + + {% elif typ_deadline == 'preddeadline' %} 1. deadlinu aktuálního čísla + {% else %} deadlinu aktuálního čísla + {% endif %}zbývá: + {{nejblizsi_deadline|timeuntil}}

    +
    +
    +{% endif %} + +
    + +
    + +
    +

    - {% block nadpis1a %}{% block nadpis1b %} - Vítej! - {% endblock %}{% endblock %} + {% block nadpis1a %} + Vítej + {% endblock %} + mezi námi

    -

    -M&M je korespondenční seminář. Několikrát do roka zdarma vydáváme časopis a v něm zajímavé podněty k přemýšlení. Ty na ně můžeš reagovat.
    - - M&M je taky soutěž. Můžeš vyhrát knížky, deskovky nebo dokonce dort. Můžeš se dostat na matfyz bez přijímaček. A především s námi můžeš jet na skvělé soustředění. -

    - -
    - {% if dead %} -
    -

    Do konce odeslání řešení {% if deadline_soustredeni %}(pro opravení řešení do dalšího čísla) {% endif %}zbývá:
    - {{ted|timesince:dead}}

    -
    - {% endif %} - {# Novinky #} -

    Novinky

    - {% include 'seminar/novinky.html' %} +
    + M&M je korespondenční seminář pro středoškoláky. Vydáváme časopis, v němž najdeš různá témata z matematiky, fyziky a informatiky. + Součástí témat jsou problémy a úlohy, nad kterými se můžeš zamyslet, experimentovat a bádat. +
    Zaregistruj se!
    +
    + +
    - Archiv novinek +
    + +

    + Vyřeš to! +

    + +
    + M&M je taky soutěž. Řešení, která nám pošleš, opravíme, a dostaneš za ně body. Můžeš vyhrát zajímavé ceny, dostat se + na Matfyz bez přijímaček a především, můžeš s námi jet na skvělé soustředění. +

    +
    Co můžeš vyhrát?
    {# FIXME odkaz #} + + +
    +
    +
    - - - - - - - - - - - - - - - - - - - - - - - - - +
    + {% include 'graph.svg' %} +
    + -

    Zjistit víc!

    +

    Zjisti víc!

    +
    +
    + +
    + {# Novinky #} +

    Co je nového?

    + {% include 'seminar/novinky.html' %} + + Archiv novinek + +
    + +
    - {% endblock %} diff --git a/seminar/templates/seminar/treenode.html b/seminar/templates/seminar/treenode.html new file mode 100644 index 00000000..b7976426 --- /dev/null +++ b/seminar/templates/seminar/treenode.html @@ -0,0 +1,12 @@ +{% extends "base.html" %} +{% load render_bundle from webpack_loader %} + + +{% block content %} +
    + +
    +{% render_bundle 'chunk-vendors' %} +{% render_bundle 'vue_app_01' %} + +{% endblock content %} diff --git a/seminar/templates/seminar/treenode_add_stub.html b/seminar/templates/seminar/treenode_add_stub.html new file mode 100644 index 00000000..dd3fc670 --- /dev/null +++ b/seminar/templates/seminar/treenode_add_stub.html @@ -0,0 +1,27 @@ +{% load treenodes %} +{% if kam_slug == "syn" %} + {% appendableChildren obj as dostupne_typy %} +{% else %} + {% appendableChildren obj.parent as dostupne_typy %} +{% endif %} + +{# ulohaZadani ulohaVzorak Reseni Cast Text #} +{% if dostupne_typy %} +
    Přidat {{kam}} + +
    + Nadpis: + +
    +
    Vytvořit
    +
    Vytvořit, Tady bude autocomplete na reseniNode
    +
    Vytvořit zadání
    +
    Vytvořit vzorák k: Tady bude autocomplete na problémy k aktuálnímu kontextu
    + + +
    +{% endif %}{# appendablebleChildren #} diff --git a/seminar/templates/seminar/treenode_name.html b/seminar/templates/seminar/treenode_name.html new file mode 100644 index 00000000..501effe4 --- /dev/null +++ b/seminar/templates/seminar/treenode_name.html @@ -0,0 +1,18 @@ +{% load treenodes %} +{% if obj.node|isRocnik %} + Ročník {{obj.node.rocnik}} +{% elif obj.node|isCislo %} + Číslo {{obj.node.cislo}} +{% elif obj.node|isTemaVCisle %} + Téma {{obj.node.tema.nazev}} +{% elif obj.node|isUlohaZadani %} +Úloha {{obj.node.uloha.kod_v_rocniku}} ({{obj.node.uloha.max_body}} b) +{% elif obj.node|isUlohaVzorak %} +Řešení: {{obj.node.uloha.kod_v_rocniku}} +{% elif obj.node|isCast %} + {{obj.node.nadpis}} +{% elif obj.node|isText %} +{{obj.node.text.na_web}} +{% else %} +Objekt jiného typu {{obj.node}} +{% endif %} diff --git a/seminar/templates/seminar/treenode_recursive.html b/seminar/templates/seminar/treenode_recursive.html new file mode 100644 index 00000000..6da7a96f --- /dev/null +++ b/seminar/templates/seminar/treenode_recursive.html @@ -0,0 +1,55 @@ +{% load treenodes %} +{# {{depth}} #} +
    +
    + {{obj.node}} + {{obj.node.id}} + {% if obj.node|deletable %} + + {% endif %} + {% if obj.parent and obj.parent|editableSiblings %} + + {% endif %} + {% if obj|canPodvesitPred %} + - nejsou testovací data + {% endif %} + {% if obj|canPodvesitZa %} + - nejsou testovací data + {% endif %} + + +
    +{% if False %} +
    + FIXME: není zatím implementováno + - nejsou testovací data +
    +{% endif %} +{% include "seminar/treenode_name.html" %} +{%if obj.children %} +
    + + {% with kam="před" kam_slug="syn" %} {% include "seminar/treenode_add_stub.html" %} {% endwith %} + {%for ch in obj.children %} + + {# ----------- Vypisujeme podstrom ----------#} + {%with obj=ch depth=depth|add:"1" %} {%include "seminar/treenode_recursive.html" %} {%endwith%} + {# ----------- Přidáváme mezi syny / za posledního -------- #} + {% if forloop.last %} + {% with kam="za" kam_slug="za" obj=ch %} {% include "seminar/treenode_add_stub.html" %} {% endwith %} + {% else %} + {% with kam="mezi" obj=ch kam_slug="za" %} {% include "seminar/treenode_add_stub.html" %} {% endwith %} + {% endif %} + {# ----------- Prohazujeme sousedy ----------#} +
    + {% if not forloop.last and ch|editableSiblings %} + + {% endif %} +
    + {% endfor %} +
    +{% else %} + {# ----------- Přidáváme prvního syna ----------#} + {% with kam="jako syna" kam_slug="syn" %} {% include "seminar/treenode_add_stub.html" %} {% endwith %} +{%endif%} +
    diff --git a/seminar/templates/seminar/vuetest.html b/seminar/templates/seminar/vuetest.html new file mode 100644 index 00000000..a235921d --- /dev/null +++ b/seminar/templates/seminar/vuetest.html @@ -0,0 +1,7 @@ +{% load render_bundle from webpack_loader %} + +
    + +
    +{% render_bundle 'chunk-vendors' %} +{% render_bundle 'vue_app_01' %} diff --git a/seminar/templates/seminar/vysledkovka_rocnik.html b/seminar/templates/seminar/vysledkovka_rocnik.html index f1dc1d79..db9e848a 100644 --- a/seminar/templates/seminar/vysledkovka_rocnik.html +++ b/seminar/templates/seminar/vysledkovka_rocnik.html @@ -4,23 +4,23 @@ Jméno R. Odjakživa - {% for c in vysledkovka.cisla %} + {% for c in cisla %} - {{c.rocnik.rocnik}}.{{ c.cislo }} + {{c.rocnik.rocnik}}.{{ c.poradi }} {% endfor %} Celkem -{% for rv in vysledkovka.radky %} +{% for rv in radky_vysledkovky %} {% autoescape off %}{{ rv.poradi }}{% endautoescape %} {% if rv.titul %} {{ rv.titul }}MM {% endif %} - {{ rv.resitel.plne_jmeno }} - {{ rv.resitel.rocnik }} - {{ rv.body_odjakziva }} - {% for b in rv.body_cisla %} + {{ rv.resitel.osoba.plne_jmeno }} + {{ rv.rocnik_resitele }} + {{ rv.body_celkem_odjakziva }} + {% for b in rv.body_cisla_sezn %} {{ b }} {% endfor %} {{ rv.body_rocnik }} diff --git a/seminar/templates/seminar/zadani/AktualniVysledkovka.html b/seminar/templates/seminar/zadani/AktualniVysledkovka.html index 00ace94c..9690c0ef 100644 --- a/seminar/templates/seminar/zadani/AktualniVysledkovka.html +++ b/seminar/templates/seminar/zadani/AktualniVysledkovka.html @@ -1,22 +1,15 @@ -{% extends "seminar/zadani/base.html" %} - -{% block submenu %} - {% with "vysledkova-listina" as selected %} - {% include 'seminar/zadani/submenu.html' %} - {% endwith %} -{% endblock submenu %} - +{% extends "base.html" %} {% block content %} {% with nastaveni.aktualni_rocnik as rocnik %}

    {% block nadpis1a %}{% block nadpis1b %} - Průběžné výsledky {{ vysledkovka.rocnik }}. ročníku + Průběžné výsledky {{ rocnik.rocnik }}. ročníku {% endblock %}{% endblock %}

    - {% if vysledkovka %} + {% if radky_vysledkovky %} {% include "seminar/vysledkovka_rocnik.html" %} {% else %}

    V tomto ročníku zatím žádné výsledky nejsou.

    @@ -24,14 +17,16 @@

    Staré výsledkové listiny najdete - v archivu. + v archivu.

    - {% if user.is_staff and vysledkovka_s_neverejnymi %} + {% if user.je_org and vysledkovka_s_neverejnymi %}

    Výsledky včetně neveřejných

    - {% with vysledkovka_s_neverejnymi as vysledkovka %} + {% with vysledkovka_s_neverejnymi as radky_vysledkovky %} + {% with cisla_s_neverejnymi as cisla %} {% include "seminar/vysledkovka_rocnik.html" %} + {% endwith %} {% endwith %}
    {% endif %} diff --git a/seminar/templates/seminar/zadani/AktualniZadani.html b/seminar/templates/seminar/zadani/AktualniZadani.html index 93fac9a4..89e1903d 100644 --- a/seminar/templates/seminar/zadani/AktualniZadani.html +++ b/seminar/templates/seminar/zadani/AktualniZadani.html @@ -1,88 +1,52 @@ -{% extends "seminar/zadani/base.html" %} - -{% block submenu %} - {% with "aktualni" as selected %} - {% include 'seminar/zadani/submenu.html' %} - {% endwith %} -{% endblock submenu %} +{% extends "base.html" %} {% block nadpis1a %}{% block nadpis1b %} Aktuální zadání {% endblock %}{% endblock %} {% block content %} -
    +
    {% with nastaveni.aktualni_cislo as ac %} {# Zobrazovani neverejnych zadani jen organizatorum #} -{% if user.is_staff or verejne %} -{% if user.is_staff and not verejne %}
    {% endif %} +{% if user.je_org or verejne %} + {% if user.je_org and not verejne %}
    {% endif %} + +
    +
    + Termíny pro odeslání řešení {{ac.poradi}}. série:
    + + {% if ac.datum_deadline_soustredeni %} + {{ac.datum_deadline_soustredeni}} pro účast na soustředění
    + {% endif %} - {% if ac.zadane_problemy.all %} - {% if ac.datum_deadline_soustredeni %} -
    - Termín odeslání {{ac.cislo}}. série pro účast na soustředění: - {{ac.datum_deadline_soustredeni}} -
    - {% endif %} - {% endif %} - {% if ac.zadane_problemy.all %} -
    - Termín odeslání {{ac.cislo}}. série: {{ac.datum_deadline}} -
    - {% endif %} + {% if ac.datum_preddeadline %} + {{ac.datum_preddeadline}} pro otištění v dalším čísle
    + {% endif %} + {% if ac.datum_deadline %} + {{ac.datum_deadline}} definitivní deadline
    + {% endif %} - {% if ac.pdf %} -

    Aktuální témata najdete v aktuálním čísle v PDF.

    - {% endif %} - - {% if False %} - {% for sada in jednorazove_problemy %} - {# podnadpisy, kdyz neni zakomentuje se nadpis #} - {% if not sada %}{% endif %} - {# publikace jednotlivych zadani #} - {% for problem in sada %} - {% for tag in problem.zamereni.names %} - - {% endfor %} +
    +
    - {# TODO použít {{problem.kod_v_rocniku}} ? vrací 4.u1 místo 4.1 #} -

    {{problem.cislo_zadani.cislo}}.{{problem.kod}} {{problem.nazev}} {{ problem.body_v_zavorce }}

    - {% autoescape off %}{{problem.text_zadani}}{% endautoescape %} -
    - {% endfor %} - {% empty %} - Aktuálně nejsou zadané žádné úlohy k řešení. - {% endfor %} - {% endif %} + {% if ac.titulka_nahled and ac.pdf %} + Titulní strana {{ac.poradi}}. čísla + {% endif %} -{% if user.is_staff and not verejne%}
    {% endif %} -{% else %} -

    Aktuálně nejsou zveřejněny žádné úlohy

    -{% endif %} + {% if ac.pdf %} +

    Jak seminář M&M funguje? Podívejte se na stránku Jak řešit.
    +

    Aktuální témata najdete v aktuálním čísle v PDF.


    + + {% endif %} + {% if user.je_org and not verejne%}
    {% endif %} - {% if False %} -

    Témata

    - - {% endif %} +{% else %} +

    Aktuálně nejsou zveřejněny žádné úlohy

    +{% endif %} {% endwith %} diff --git a/seminar/templates/seminar/zadani/Temata.html b/seminar/templates/seminar/zadani/Temata.html index abc7a145..1792bc65 100644 --- a/seminar/templates/seminar/zadani/Temata.html +++ b/seminar/templates/seminar/zadani/Temata.html @@ -1,11 +1,4 @@ -{% extends "seminar/zadani/base.html" %} - -{% block submenu %} - {% with "temata" as selected %} - {% include 'seminar/zadani/submenu.html' %} - {% endwith %} -{% endblock submenu %} - +{% extends "base.html" %} {% block content %} {% with nastaveni.aktualni_rocnik as ar %} @@ -27,7 +20,7 @@ textu.

    - Jak řešit téma? + Jak řešit téma?

    +
    + + + +
    +
    +

    {{ currentText }}

    + + +
    +
    + + + + + + diff --git a/vue_frontend/src/components/CisloNode.vue b/vue_frontend/src/components/CisloNode.vue new file mode 100644 index 00000000..f5992970 --- /dev/null +++ b/vue_frontend/src/components/CisloNode.vue @@ -0,0 +1,19 @@ + + + + + + diff --git a/vue_frontend/src/components/RocnikNode.vue b/vue_frontend/src/components/RocnikNode.vue new file mode 100644 index 00000000..6526a550 --- /dev/null +++ b/vue_frontend/src/components/RocnikNode.vue @@ -0,0 +1,21 @@ + + + + + + diff --git a/vue_frontend/src/components/TemaVCisleNode.vue b/vue_frontend/src/components/TemaVCisleNode.vue new file mode 100644 index 00000000..19d507c4 --- /dev/null +++ b/vue_frontend/src/components/TemaVCisleNode.vue @@ -0,0 +1,19 @@ + + + + + + diff --git a/vue_frontend/src/components/TextNode.vue b/vue_frontend/src/components/TextNode.vue new file mode 100644 index 00000000..b565d229 --- /dev/null +++ b/vue_frontend/src/components/TextNode.vue @@ -0,0 +1,188 @@ + + + + + + diff --git a/vue_frontend/src/components/TreeNode.vue b/vue_frontend/src/components/TreeNode.vue new file mode 100644 index 00000000..4c8e6b2a --- /dev/null +++ b/vue_frontend/src/components/TreeNode.vue @@ -0,0 +1,175 @@ + + + + + + diff --git a/vue_frontend/src/components/TreeNodeRoot.vue b/vue_frontend/src/components/TreeNodeRoot.vue new file mode 100644 index 00000000..674d0fda --- /dev/null +++ b/vue_frontend/src/components/TreeNodeRoot.vue @@ -0,0 +1,77 @@ + + + + + diff --git a/vue_frontend/src/components/UlohaVzorakNode.vue b/vue_frontend/src/components/UlohaVzorakNode.vue new file mode 100644 index 00000000..9d388a4e --- /dev/null +++ b/vue_frontend/src/components/UlohaVzorakNode.vue @@ -0,0 +1,139 @@ + + + + + diff --git a/vue_frontend/src/components/UlohaZadaniNode.vue b/vue_frontend/src/components/UlohaZadaniNode.vue new file mode 100644 index 00000000..32f0d93b --- /dev/null +++ b/vue_frontend/src/components/UlohaZadaniNode.vue @@ -0,0 +1,113 @@ + + + diff --git a/vue_frontend/src/main.js b/vue_frontend/src/main.js new file mode 100644 index 00000000..0c3b439d --- /dev/null +++ b/vue_frontend/src/main.js @@ -0,0 +1,12 @@ +import Vue from 'vue' +import App from './App.vue' +import router from './router' +import CKEditor from '@ckeditor/ckeditor5-vue' + +Vue.config.productionTip = false +Vue.use(CKEditor); + +new Vue({ + router, + render: h => h(App), +}).$mount('#app') diff --git a/vue_frontend/src/router/index.js b/vue_frontend/src/router/index.js new file mode 100644 index 00000000..2d76bee5 --- /dev/null +++ b/vue_frontend/src/router/index.js @@ -0,0 +1,33 @@ +import Vue from 'vue' +import Router from 'vue-router' +import TreeNodeRoot from '../components/TreeNodeRoot.vue' + +Vue.use(Router) + +export default new Router({ + mode: 'history', + linkActiveClass: 'active', + routes: [{ + path: '/temp/vue', + name: 'treenodedefault', + props: {'tnid': 23}, + component: TreeNodeRoot + }, { + path: '/temp/vue/:tnid', + name: 'treenode', + props: true, + component: TreeNodeRoot + }, { + path: '/aktualni/zadani', + name: 'treenode_zadani', + props: {'tnid': 1655}, + component: TreeNodeRoot + }, { + path: '/cislo/:cislo', + name: 'treenode_cislo', + props: {'tnsource':'inline'}, + component: TreeNodeRoot + } + ] +}) + diff --git a/vue_frontend/vue.config.js b/vue_frontend/vue.config.js new file mode 100644 index 00000000..e4fc61ce --- /dev/null +++ b/vue_frontend/vue.config.js @@ -0,0 +1,62 @@ +const BundleTracker = require("webpack-bundle-tracker"); + +const pages = { + 'vue_app_01': { + entry: './src/main.js', + chunks: ['chunk-vendors'] + }, +/* 'vue_app_02': { + entry: './src/newhampshir.js', + chunks: ['chunk-vendors'] + }, +*/ +} + +module.exports = { + pages: pages, + filenameHashing: false, + productionSourceMap: true, + publicPath: process.env.NODE_ENV === 'production' + ? '/static/seminar/vue/' + : 'http://localhost:8080/', + outputDir: '../seminar/static/seminar/vue/', + + chainWebpack: config => { + + config.optimization.minimize(false) + config.optimization + .splitChunks({ + cacheGroups: { + vendor: { + test: /[\\/]node_modules[\\/]/, + name: "chunk-vendors", + chunks: "all", + priority: 1 + }, + }, + }).minimize(false); + + Object.keys(pages).forEach(page => { + config.plugins.delete(`html-${page}`); + config.plugins.delete(`preload-${page}`); + config.plugins.delete(`prefetch-${page}`); + }) + + config + .plugin('BundleTracker') + .use(BundleTracker, [{filename: '../vue_frontend/webpack-stats.json'}]); + + config.resolve.alias + .set('__STATIC__', 'static') + + config.devServer + .public('http://localhost:8080') + .host('localhost') + .port(8080) + .hotOnly(true) + .watchOptions({poll: 1000}) + .https(false) + .headers({"Access-Control-Allow-Origin": ["*"]}) + + } +}; diff --git a/vue_frontend/yarn.lock b/vue_frontend/yarn.lock new file mode 100644 index 00000000..4df27d66 --- /dev/null +++ b/vue_frontend/yarn.lock @@ -0,0 +1,8544 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" + integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== + dependencies: + "@babel/highlight" "^7.10.4" + +"@babel/compat-data@^7.10.4", "@babel/compat-data@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.11.0.tgz#e9f73efe09af1355b723a7f39b11bad637d7c99c" + integrity sha512-TPSvJfv73ng0pfnEOh17bYMPQbI95+nGWc71Ss4vZdRBHTDqmM9Z8ZV4rYz8Ks7sfzc95n30k6ODIq5UGnXcYQ== + dependencies: + browserslist "^4.12.0" + invariant "^2.2.4" + semver "^5.5.0" + +"@babel/core@^7.9.6": + version "7.11.1" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.1.tgz#2c55b604e73a40dc21b0e52650b11c65cf276643" + integrity sha512-XqF7F6FWQdKGGWAzGELL+aCO1p+lRY5Tj5/tbT3St1G8NaH70jhhDIKknIZaDans0OQBG5wRAldROLHSt44BgQ== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/generator" "^7.11.0" + "@babel/helper-module-transforms" "^7.11.0" + "@babel/helpers" "^7.10.4" + "@babel/parser" "^7.11.1" + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.11.0" + "@babel/types" "^7.11.0" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.1" + json5 "^2.1.2" + lodash "^4.17.19" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/generator@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.0.tgz#4b90c78d8c12825024568cbe83ee6c9af193585c" + integrity sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ== + dependencies: + "@babel/types" "^7.11.0" + jsesc "^2.5.1" + source-map "^0.5.0" + +"@babel/helper-annotate-as-pure@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz#5bf0d495a3f757ac3bda48b5bf3b3ba309c72ba3" + integrity sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA== + dependencies: + "@babel/types" "^7.10.4" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz#bb0b75f31bf98cbf9ff143c1ae578b87274ae1a3" + integrity sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg== + dependencies: + "@babel/helper-explode-assignable-expression" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helper-compilation-targets@^7.10.4", "@babel/helper-compilation-targets@^7.9.6": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.4.tgz#804ae8e3f04376607cc791b9d47d540276332bd2" + integrity sha512-a3rYhlsGV0UHNDvrtOXBg8/OpfV0OKTkxKPzIplS1zpx7CygDcWWxckxZeDd3gzPzC4kUT0A4nVFDK0wGMh4MQ== + dependencies: + "@babel/compat-data" "^7.10.4" + browserslist "^4.12.0" + invariant "^2.2.4" + levenary "^1.1.1" + semver "^5.5.0" + +"@babel/helper-create-class-features-plugin@^7.10.4", "@babel/helper-create-class-features-plugin@^7.10.5": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.5.tgz#9f61446ba80e8240b0a5c85c6fdac8459d6f259d" + integrity sha512-0nkdeijB7VlZoLT3r/mY3bUkw3T8WG/hNw+FATs/6+pG2039IJWjTYL0VTISqsNHMUTEnwbVnc89WIJX9Qed0A== + dependencies: + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-member-expression-to-functions" "^7.10.5" + "@babel/helper-optimise-call-expression" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-replace-supers" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.10.4" + +"@babel/helper-create-regexp-features-plugin@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.4.tgz#fdd60d88524659a0b6959c0579925e425714f3b8" + integrity sha512-2/hu58IEPKeoLF45DBwx3XFqsbCXmkdAay4spVr2x0jYgRxrSNp+ePwvSsy9g6YSaNDcKIQVPXk1Ov8S2edk2g== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-regex" "^7.10.4" + regexpu-core "^4.7.0" + +"@babel/helper-define-map@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz#b53c10db78a640800152692b13393147acb9bb30" + integrity sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ== + dependencies: + "@babel/helper-function-name" "^7.10.4" + "@babel/types" "^7.10.5" + lodash "^4.17.19" + +"@babel/helper-explode-assignable-expression@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.4.tgz#40a1cd917bff1288f699a94a75b37a1a2dbd8c7c" + integrity sha512-4K71RyRQNPRrR85sr5QY4X3VwG4wtVoXZB9+L3r1Gp38DhELyHCtovqydRi7c1Ovb17eRGiQ/FD5s8JdU0Uy5A== + dependencies: + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helper-function-name@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz#d2d3b20c59ad8c47112fa7d2a94bc09d5ef82f1a" + integrity sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ== + dependencies: + "@babel/helper-get-function-arity" "^7.10.4" + "@babel/template" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helper-get-function-arity@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz#98c1cbea0e2332f33f9a4661b8ce1505b2c19ba2" + integrity sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A== + dependencies: + "@babel/types" "^7.10.4" + +"@babel/helper-hoist-variables@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz#d49b001d1d5a68ca5e6604dda01a6297f7c9381e" + integrity sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA== + dependencies: + "@babel/types" "^7.10.4" + +"@babel/helper-member-expression-to-functions@^7.10.4", "@babel/helper-member-expression-to-functions@^7.10.5": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz#ae69c83d84ee82f4b42f96e2a09410935a8f26df" + integrity sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q== + dependencies: + "@babel/types" "^7.11.0" + +"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz#4c5c54be04bd31670a7382797d75b9fa2e5b5620" + integrity sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw== + dependencies: + "@babel/types" "^7.10.4" + +"@babel/helper-module-transforms@^7.10.4", "@babel/helper-module-transforms@^7.10.5", "@babel/helper-module-transforms@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz#b16f250229e47211abdd84b34b64737c2ab2d359" + integrity sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg== + dependencies: + "@babel/helper-module-imports" "^7.10.4" + "@babel/helper-replace-supers" "^7.10.4" + "@babel/helper-simple-access" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.11.0" + "@babel/template" "^7.10.4" + "@babel/types" "^7.11.0" + lodash "^4.17.19" + +"@babel/helper-optimise-call-expression@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz#50dc96413d594f995a77905905b05893cd779673" + integrity sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg== + dependencies: + "@babel/types" "^7.10.4" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" + integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== + +"@babel/helper-regex@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.10.5.tgz#32dfbb79899073c415557053a19bd055aae50ae0" + integrity sha512-68kdUAzDrljqBrio7DYAEgCoJHxppJOERHOgOrDN7WjOzP0ZQ1LsSDRXcemzVZaLvjaJsJEESb6qt+znNuENDg== + dependencies: + lodash "^4.17.19" + +"@babel/helper-remap-async-to-generator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.4.tgz#fce8bea4e9690bbe923056ded21e54b4e8b68ed5" + integrity sha512-86Lsr6NNw3qTNl+TBcF1oRZMaVzJtbWTyTko+CQL/tvNvcGYEFKbLXDPxtW0HKk3McNOk4KzY55itGWCAGK5tg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-wrap-function" "^7.10.4" + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helper-replace-supers@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz#d585cd9388ea06e6031e4cd44b6713cbead9e6cf" + integrity sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.10.4" + "@babel/helper-optimise-call-expression" "^7.10.4" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helper-simple-access@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz#0f5ccda2945277a2a7a2d3a821e15395edcf3461" + integrity sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw== + dependencies: + "@babel/template" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helper-skip-transparent-expression-wrappers@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.11.0.tgz#eec162f112c2f58d3af0af125e3bb57665146729" + integrity sha512-0XIdiQln4Elglgjbwo9wuJpL/K7AGCY26kmEt0+pRP0TAj4jjyNq1MjoRvikrTVqKcx4Gysxt4cXvVFXP/JO2Q== + dependencies: + "@babel/types" "^7.11.0" + +"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz#f8a491244acf6a676158ac42072911ba83ad099f" + integrity sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg== + dependencies: + "@babel/types" "^7.11.0" + +"@babel/helper-validator-identifier@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" + integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== + +"@babel/helper-wrap-function@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz#8a6f701eab0ff39f765b5a1cfef409990e624b87" + integrity sha512-6py45WvEF0MhiLrdxtRjKjufwLL1/ob2qDJgg5JgNdojBAZSAKnAjkyOCNug6n+OBl4VW76XjvgSFTdaMcW0Ug== + dependencies: + "@babel/helper-function-name" "^7.10.4" + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helpers@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.10.4.tgz#2abeb0d721aff7c0a97376b9e1f6f65d7a475044" + integrity sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA== + dependencies: + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/highlight@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143" + integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== + dependencies: + "@babel/helper-validator-identifier" "^7.10.4" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.10.4", "@babel/parser@^7.11.0", "@babel/parser@^7.11.1", "@babel/parser@^7.7.0": + version "7.11.2" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.2.tgz#0882ab8a455df3065ea2dcb4c753b2460a24bead" + integrity sha512-Vuj/+7vLo6l1Vi7uuO+1ngCDNeVmNbTngcJFKCR/oEtz8tKz0CJxZEGmPt9KcIloZhOZ3Zit6xbpXT2MDlS9Vw== + +"@babel/plugin-proposal-async-generator-functions@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.5.tgz#3491cabf2f7c179ab820606cec27fed15e0e8558" + integrity sha512-cNMCVezQbrRGvXJwm9fu/1sJj9bHdGAgKodZdLqOQIpfoH3raqmRPBM17+lh7CzhiKRRBrGtZL9WcjxSoGYUSg== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-remap-async-to-generator" "^7.10.4" + "@babel/plugin-syntax-async-generators" "^7.8.0" + +"@babel/plugin-proposal-class-properties@^7.10.4", "@babel/plugin-proposal-class-properties@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.4.tgz#a33bf632da390a59c7a8c570045d1115cd778807" + integrity sha512-vhwkEROxzcHGNu2mzUC0OFFNXdZ4M23ib8aRRcJSsW8BZK9pQMD7QB7csl97NBbgGZO7ZyHUyKDnxzOaP4IrCg== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-proposal-decorators@^7.8.3": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.10.5.tgz#42898bba478bc4b1ae242a703a953a7ad350ffb4" + integrity sha512-Sc5TAQSZuLzgY0664mMDn24Vw2P8g/VhyLyGPaWiHahhgLqeZvcGeyBZOrJW0oSKIK2mvQ22a1ENXBIQLhrEiQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.10.5" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-decorators" "^7.10.4" + +"@babel/plugin-proposal-dynamic-import@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.4.tgz#ba57a26cb98b37741e9d5bca1b8b0ddf8291f17e" + integrity sha512-up6oID1LeidOOASNXgv/CFbgBqTuKJ0cJjz6An5tWD+NVBNlp3VNSBxv2ZdU7SYl3NxJC7agAQDApZusV6uFwQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-dynamic-import" "^7.8.0" + +"@babel/plugin-proposal-export-namespace-from@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.10.4.tgz#570d883b91031637b3e2958eea3c438e62c05f54" + integrity sha512-aNdf0LY6/3WXkhh0Fdb6Zk9j1NMD8ovj3F6r0+3j837Pn1S1PdNtcwJ5EG9WkVPNHPxyJDaxMaAOVq4eki0qbg== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + +"@babel/plugin-proposal-json-strings@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.4.tgz#593e59c63528160233bd321b1aebe0820c2341db" + integrity sha512-fCL7QF0Jo83uy1K0P2YXrfX11tj3lkpN7l4dMv9Y9VkowkhkQDwFHFd8IiwyK5MZjE8UpbgokkgtcReH88Abaw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-json-strings" "^7.8.0" + +"@babel/plugin-proposal-logical-assignment-operators@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.11.0.tgz#9f80e482c03083c87125dee10026b58527ea20c8" + integrity sha512-/f8p4z+Auz0Uaf+i8Ekf1iM7wUNLcViFUGiPxKeXvxTSl63B875YPiVdUDdem7hREcI0E0kSpEhS8tF5RphK7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + +"@babel/plugin-proposal-nullish-coalescing-operator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz#02a7e961fc32e6d5b2db0649e01bf80ddee7e04a" + integrity sha512-wq5n1M3ZUlHl9sqT2ok1T2/MTt6AXE0e1Lz4WzWBr95LsAZ5qDXe4KnFuauYyEyLiohvXFMdbsOTMyLZs91Zlw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + +"@babel/plugin-proposal-numeric-separator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.4.tgz#ce1590ff0a65ad12970a609d78855e9a4c1aef06" + integrity sha512-73/G7QoRoeNkLZFxsoCCvlg4ezE4eM+57PnOqgaPOozd5myfj7p0muD1mRVJvbUWbOzD+q3No2bWbaKy+DJ8DA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-proposal-object-rest-spread@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.11.0.tgz#bd81f95a1f746760ea43b6c2d3d62b11790ad0af" + integrity sha512-wzch41N4yztwoRw0ak+37wxwJM2oiIiy6huGCoqkvSTA9acYWcPfn9Y4aJqmFFJ70KTJUu29f3DQ43uJ9HXzEA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-transform-parameters" "^7.10.4" + +"@babel/plugin-proposal-optional-catch-binding@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.4.tgz#31c938309d24a78a49d68fdabffaa863758554dd" + integrity sha512-LflT6nPh+GK2MnFiKDyLiqSqVHkQnVf7hdoAvyTnnKj9xB3docGRsdPuxp6qqqW19ifK3xgc9U5/FwrSaCNX5g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" + +"@babel/plugin-proposal-optional-chaining@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.11.0.tgz#de5866d0646f6afdaab8a566382fe3a221755076" + integrity sha512-v9fZIu3Y8562RRwhm1BbMRxtqZNFmFA2EG+pT2diuU8PT3H6T/KXoZ54KgYisfOFZHV6PfvAiBIZ9Rcz+/JCxA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-skip-transparent-expression-wrappers" "^7.11.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.0" + +"@babel/plugin-proposal-private-methods@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.4.tgz#b160d972b8fdba5c7d111a145fc8c421fc2a6909" + integrity sha512-wh5GJleuI8k3emgTg5KkJK6kHNsGEr0uBTDBuQUBJwckk9xs1ez79ioheEVVxMLyPscB0LfkbVHslQqIzWV6Bw== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-proposal-unicode-property-regex@^7.10.4", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.4.tgz#4483cda53041ce3413b7fe2f00022665ddfaa75d" + integrity sha512-H+3fOgPnEXFL9zGYtKQe4IDOPKYlZdF1kqFDQRRb8PK4B8af1vAGK04tF5iQAAsui+mHNBQSAtd2/ndEDe9wuA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-async-generators@^7.8.0": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz#6644e6a0baa55a61f9e3231f6c9eeb6ee46c124c" + integrity sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-decorators@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.10.4.tgz#6853085b2c429f9d322d02f5a635018cdeb2360c" + integrity sha512-2NaoC6fAk2VMdhY1eerkfHV+lVYC1u8b+jmRJISqANCJlTxYy19HGdIkkQtix2UtkcPuPu+IlDgrVseZnU03bw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-dynamic-import@^7.8.0", "@babel/plugin-syntax-dynamic-import@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" + integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-export-namespace-from@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" + integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-json-strings@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-jsx@^7.2.0", "@babel/plugin-syntax-jsx@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.10.4.tgz#39abaae3cbf710c4373d8429484e6ba21340166c" + integrity sha512-KCg9mio9jwiARCB7WAcQ7Y1q+qicILjoK8LP/VkPkEKaf5dkaZZK1EcTe91a3JJlZ3qy6L5s9X52boEYi8DM9g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-top-level-await@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.4.tgz#4bbeb8917b54fcf768364e0a81f560e33a3ef57d" + integrity sha512-ni1brg4lXEmWyafKr0ccFWkJG0CeMt4WV1oyeBW6EFObF4oOHclbkj5cARxAPQyAQ2UTuplJyK4nfkXIMMFvsQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-arrow-functions@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.4.tgz#e22960d77e697c74f41c501d44d73dbf8a6a64cd" + integrity sha512-9J/oD1jV0ZCBcgnoFWFq1vJd4msoKb/TCpGNFyyLt0zABdcvgK3aYikZ8HjzB14c26bc7E3Q1yugpwGy2aTPNA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-async-to-generator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.4.tgz#41a5017e49eb6f3cda9392a51eef29405b245a37" + integrity sha512-F6nREOan7J5UXTLsDsZG3DXmZSVofr2tGNwfdrVwkDWHfQckbQXnXSPfD7iO+c/2HGqycwyLST3DnZ16n+cBJQ== + dependencies: + "@babel/helper-module-imports" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-remap-async-to-generator" "^7.10.4" + +"@babel/plugin-transform-block-scoped-functions@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.4.tgz#1afa595744f75e43a91af73b0d998ecfe4ebc2e8" + integrity sha512-WzXDarQXYYfjaV1szJvN3AD7rZgZzC1JtjJZ8dMHUyiK8mxPRahynp14zzNjU3VkPqPsO38CzxiWO1c9ARZ8JA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-block-scoping@^7.10.4": + version "7.11.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.11.1.tgz#5b7efe98852bef8d652c0b28144cd93a9e4b5215" + integrity sha512-00dYeDE0EVEHuuM+26+0w/SCL0BH2Qy7LwHuI4Hi4MH5gkC8/AqMN5uWFJIsoXZrAphiMm1iXzBw6L2T+eA0ew== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-classes@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.4.tgz#405136af2b3e218bc4a1926228bc917ab1a0adc7" + integrity sha512-2oZ9qLjt161dn1ZE0Ms66xBncQH4In8Sqw1YWgBUZuGVJJS5c0OFZXL6dP2MRHrkU/eKhWg8CzFJhRQl50rQxA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-define-map" "^7.10.4" + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-optimise-call-expression" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-replace-supers" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.10.4" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.4.tgz#9ded83a816e82ded28d52d4b4ecbdd810cdfc0eb" + integrity sha512-JFwVDXcP/hM/TbyzGq3l/XWGut7p46Z3QvqFMXTfk6/09m7xZHJUN9xHfsv7vqqD4YnfI5ueYdSJtXqqBLyjBw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-destructuring@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.4.tgz#70ddd2b3d1bea83d01509e9bb25ddb3a74fc85e5" + integrity sha512-+WmfvyfsyF603iPa6825mq6Qrb7uLjTOsa3XOFzlYcYDHSS4QmpOWOL0NNBY5qMbvrcf3tq0Cw+v4lxswOBpgA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-dotall-regex@^7.10.4", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.4.tgz#469c2062105c1eb6a040eaf4fac4b488078395ee" + integrity sha512-ZEAVvUTCMlMFAbASYSVQoxIbHm2OkG2MseW6bV2JjIygOjdVv8tuxrCTzj1+Rynh7ODb8GivUy7dzEXzEhuPaA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-duplicate-keys@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.4.tgz#697e50c9fee14380fe843d1f306b295617431e47" + integrity sha512-GL0/fJnmgMclHiBTTWXNlYjYsA7rDrtsazHG6mglaGSTh0KsrW04qml+Bbz9FL0LcJIRwBWL5ZqlNHKTkU3xAA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-exponentiation-operator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.4.tgz#5ae338c57f8cf4001bdb35607ae66b92d665af2e" + integrity sha512-S5HgLVgkBcRdyQAHbKj+7KyuWx8C6t5oETmUuwz1pt3WTWJhsUV0WIIXuVvfXMxl/QQyHKlSCNNtaIamG8fysw== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-for-of@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.4.tgz#c08892e8819d3a5db29031b115af511dbbfebae9" + integrity sha512-ItdQfAzu9AlEqmusA/65TqJ79eRcgGmpPPFvBnGILXZH975G0LNjP1yjHvGgfuCxqrPPueXOPe+FsvxmxKiHHQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-function-name@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.4.tgz#6a467880e0fc9638514ba369111811ddbe2644b7" + integrity sha512-OcDCq2y5+E0dVD5MagT5X+yTRbcvFjDI2ZVAottGH6tzqjx/LKpgkUepu3hp/u4tZBzxxpNGwLsAvGBvQ2mJzg== + dependencies: + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-literals@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.4.tgz#9f42ba0841100a135f22712d0e391c462f571f3c" + integrity sha512-Xd/dFSTEVuUWnyZiMu76/InZxLTYilOSr1UlHV+p115Z/Le2Fi1KXkJUYz0b42DfndostYlPub3m8ZTQlMaiqQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-member-expression-literals@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.4.tgz#b1ec44fcf195afcb8db2c62cd8e551c881baf8b7" + integrity sha512-0bFOvPyAoTBhtcJLr9VcwZqKmSjFml1iVxvPL0ReomGU53CX53HsM4h2SzckNdkQcHox1bpAqzxBI1Y09LlBSw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-modules-amd@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.5.tgz#1b9cddaf05d9e88b3aad339cb3e445c4f020a9b1" + integrity sha512-elm5uruNio7CTLFItVC/rIzKLfQ17+fX7EVz5W0TMgIHFo1zY0Ozzx+lgwhL4plzl8OzVn6Qasx5DeEFyoNiRw== + dependencies: + "@babel/helper-module-transforms" "^7.10.5" + "@babel/helper-plugin-utils" "^7.10.4" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-commonjs@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.4.tgz#66667c3eeda1ebf7896d41f1f16b17105a2fbca0" + integrity sha512-Xj7Uq5o80HDLlW64rVfDBhao6OX89HKUmb+9vWYaLXBZOma4gA6tw4Ni1O5qVDoZWUV0fxMYA0aYzOawz0l+1w== + dependencies: + "@babel/helper-module-transforms" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-simple-access" "^7.10.4" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-systemjs@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.5.tgz#6270099c854066681bae9e05f87e1b9cadbe8c85" + integrity sha512-f4RLO/OL14/FP1AEbcsWMzpbUz6tssRaeQg11RH1BP/XnPpRoVwgeYViMFacnkaw4k4wjRSjn3ip1Uw9TaXuMw== + dependencies: + "@babel/helper-hoist-variables" "^7.10.4" + "@babel/helper-module-transforms" "^7.10.5" + "@babel/helper-plugin-utils" "^7.10.4" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-umd@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.4.tgz#9a8481fe81b824654b3a0b65da3df89f3d21839e" + integrity sha512-mohW5q3uAEt8T45YT7Qc5ws6mWgJAaL/8BfWD9Dodo1A3RKWli8wTS+WiQ/knF+tXlPirW/1/MqzzGfCExKECA== + dependencies: + "@babel/helper-module-transforms" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.4.tgz#78b4d978810b6f3bcf03f9e318f2fc0ed41aecb6" + integrity sha512-V6LuOnD31kTkxQPhKiVYzYC/Jgdq53irJC/xBSmqcNcqFGV+PER4l6rU5SH2Vl7bH9mLDHcc0+l9HUOe4RNGKA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.10.4" + +"@babel/plugin-transform-new-target@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.4.tgz#9097d753cb7b024cb7381a3b2e52e9513a9c6888" + integrity sha512-YXwWUDAH/J6dlfwqlWsztI2Puz1NtUAubXhOPLQ5gjR/qmQ5U96DY4FQO8At33JN4XPBhrjB8I4eMmLROjjLjw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-object-super@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.4.tgz#d7146c4d139433e7a6526f888c667e314a093894" + integrity sha512-5iTw0JkdRdJvr7sY0vHqTpnruUpTea32JHmq/atIWqsnNussbRzjEDyWep8UNztt1B5IusBYg8Irb0bLbiEBCQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-replace-supers" "^7.10.4" + +"@babel/plugin-transform-parameters@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.5.tgz#59d339d58d0b1950435f4043e74e2510005e2c4a" + integrity sha512-xPHwUj5RdFV8l1wuYiu5S9fqWGM2DrYc24TMvUiRrPVm+SM3XeqU9BcokQX/kEUe+p2RBwy+yoiR1w/Blq6ubw== + dependencies: + "@babel/helper-get-function-arity" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-property-literals@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.4.tgz#f6fe54b6590352298785b83edd815d214c42e3c0" + integrity sha512-ofsAcKiUxQ8TY4sScgsGeR2vJIsfrzqvFb9GvJ5UdXDzl+MyYCaBj/FGzXuv7qE0aJcjWMILny1epqelnFlz8g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-regenerator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.4.tgz#2015e59d839074e76838de2159db421966fd8b63" + integrity sha512-3thAHwtor39A7C04XucbMg17RcZ3Qppfxr22wYzZNcVIkPHfpM9J0SO8zuCV6SZa265kxBJSrfKTvDCYqBFXGw== + dependencies: + regenerator-transform "^0.14.2" + +"@babel/plugin-transform-reserved-words@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.4.tgz#8f2682bcdcef9ed327e1b0861585d7013f8a54dd" + integrity sha512-hGsw1O6Rew1fkFbDImZIEqA8GoidwTAilwCyWqLBM9f+e/u/sQMQu7uX6dyokfOayRuuVfKOW4O7HvaBWM+JlQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-runtime@^7.9.6": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.11.0.tgz#e27f78eb36f19448636e05c33c90fd9ad9b8bccf" + integrity sha512-LFEsP+t3wkYBlis8w6/kmnd6Kb1dxTd+wGJ8MlxTGzQo//ehtqlVL4S9DNUa53+dtPSQobN2CXx4d81FqC58cw== + dependencies: + "@babel/helper-module-imports" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + resolve "^1.8.1" + semver "^5.5.1" + +"@babel/plugin-transform-shorthand-properties@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.4.tgz#9fd25ec5cdd555bb7f473e5e6ee1c971eede4dd6" + integrity sha512-AC2K/t7o07KeTIxMoHneyX90v3zkm5cjHJEokrPEAGEy3UCp8sLKfnfOIGdZ194fyN4wfX/zZUWT9trJZ0qc+Q== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-spread@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.11.0.tgz#fa84d300f5e4f57752fe41a6d1b3c554f13f17cc" + integrity sha512-UwQYGOqIdQJe4aWNyS7noqAnN2VbaczPLiEtln+zPowRNlD+79w3oi2TWfYe0eZgd+gjZCbsydN7lzWysDt+gw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-skip-transparent-expression-wrappers" "^7.11.0" + +"@babel/plugin-transform-sticky-regex@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.4.tgz#8f3889ee8657581130a29d9cc91d7c73b7c4a28d" + integrity sha512-Ddy3QZfIbEV0VYcVtFDCjeE4xwVTJWTmUtorAJkn6u/92Z/nWJNV+mILyqHKrUxXYKA2EoCilgoPePymKL4DvQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-regex" "^7.10.4" + +"@babel/plugin-transform-template-literals@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.5.tgz#78bc5d626a6642db3312d9d0f001f5e7639fde8c" + integrity sha512-V/lnPGIb+KT12OQikDvgSuesRX14ck5FfJXt6+tXhdkJ+Vsd0lDCVtF6jcB4rNClYFzaB2jusZ+lNISDk2mMMw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-typeof-symbol@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.4.tgz#9509f1a7eec31c4edbffe137c16cc33ff0bc5bfc" + integrity sha512-QqNgYwuuW0y0H+kUE/GWSR45t/ccRhe14Fs/4ZRouNNQsyd4o3PG4OtHiIrepbM2WKUBDAXKCAK/Lk4VhzTaGA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-unicode-escapes@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.4.tgz#feae523391c7651ddac115dae0a9d06857892007" + integrity sha512-y5XJ9waMti2J+e7ij20e+aH+fho7Wb7W8rNuu72aKRwCHFqQdhkdU2lo3uZ9tQuboEJcUFayXdARhcxLQ3+6Fg== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-unicode-regex@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.4.tgz#e56d71f9282fac6db09c82742055576d5e6d80a8" + integrity sha512-wNfsc4s8N2qnIwpO/WP2ZiSyjfpTamT2C9V9FDH/Ljub9zw6P3SjkXcFmc0RQUt96k2fmIvtla2MMjgTwIAC+A== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/preset-env@^7.9.6": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.11.0.tgz#860ee38f2ce17ad60480c2021ba9689393efb796" + integrity sha512-2u1/k7rG/gTh02dylX2kL3S0IJNF+J6bfDSp4DI2Ma8QN6Y9x9pmAax59fsCk6QUQG0yqH47yJWA+u1I1LccAg== + dependencies: + "@babel/compat-data" "^7.11.0" + "@babel/helper-compilation-targets" "^7.10.4" + "@babel/helper-module-imports" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-proposal-async-generator-functions" "^7.10.4" + "@babel/plugin-proposal-class-properties" "^7.10.4" + "@babel/plugin-proposal-dynamic-import" "^7.10.4" + "@babel/plugin-proposal-export-namespace-from" "^7.10.4" + "@babel/plugin-proposal-json-strings" "^7.10.4" + "@babel/plugin-proposal-logical-assignment-operators" "^7.11.0" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.10.4" + "@babel/plugin-proposal-numeric-separator" "^7.10.4" + "@babel/plugin-proposal-object-rest-spread" "^7.11.0" + "@babel/plugin-proposal-optional-catch-binding" "^7.10.4" + "@babel/plugin-proposal-optional-chaining" "^7.11.0" + "@babel/plugin-proposal-private-methods" "^7.10.4" + "@babel/plugin-proposal-unicode-property-regex" "^7.10.4" + "@babel/plugin-syntax-async-generators" "^7.8.0" + "@babel/plugin-syntax-class-properties" "^7.10.4" + "@babel/plugin-syntax-dynamic-import" "^7.8.0" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.0" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.0" + "@babel/plugin-syntax-top-level-await" "^7.10.4" + "@babel/plugin-transform-arrow-functions" "^7.10.4" + "@babel/plugin-transform-async-to-generator" "^7.10.4" + "@babel/plugin-transform-block-scoped-functions" "^7.10.4" + "@babel/plugin-transform-block-scoping" "^7.10.4" + "@babel/plugin-transform-classes" "^7.10.4" + "@babel/plugin-transform-computed-properties" "^7.10.4" + "@babel/plugin-transform-destructuring" "^7.10.4" + "@babel/plugin-transform-dotall-regex" "^7.10.4" + "@babel/plugin-transform-duplicate-keys" "^7.10.4" + "@babel/plugin-transform-exponentiation-operator" "^7.10.4" + "@babel/plugin-transform-for-of" "^7.10.4" + "@babel/plugin-transform-function-name" "^7.10.4" + "@babel/plugin-transform-literals" "^7.10.4" + "@babel/plugin-transform-member-expression-literals" "^7.10.4" + "@babel/plugin-transform-modules-amd" "^7.10.4" + "@babel/plugin-transform-modules-commonjs" "^7.10.4" + "@babel/plugin-transform-modules-systemjs" "^7.10.4" + "@babel/plugin-transform-modules-umd" "^7.10.4" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.10.4" + "@babel/plugin-transform-new-target" "^7.10.4" + "@babel/plugin-transform-object-super" "^7.10.4" + "@babel/plugin-transform-parameters" "^7.10.4" + "@babel/plugin-transform-property-literals" "^7.10.4" + "@babel/plugin-transform-regenerator" "^7.10.4" + "@babel/plugin-transform-reserved-words" "^7.10.4" + "@babel/plugin-transform-shorthand-properties" "^7.10.4" + "@babel/plugin-transform-spread" "^7.11.0" + "@babel/plugin-transform-sticky-regex" "^7.10.4" + "@babel/plugin-transform-template-literals" "^7.10.4" + "@babel/plugin-transform-typeof-symbol" "^7.10.4" + "@babel/plugin-transform-unicode-escapes" "^7.10.4" + "@babel/plugin-transform-unicode-regex" "^7.10.4" + "@babel/preset-modules" "^0.1.3" + "@babel/types" "^7.11.0" + browserslist "^4.12.0" + core-js-compat "^3.6.2" + invariant "^2.2.2" + levenary "^1.1.1" + semver "^5.5.0" + +"@babel/preset-modules@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.3.tgz#13242b53b5ef8c883c3cf7dddd55b36ce80fbc72" + integrity sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" + "@babel/plugin-transform-dotall-regex" "^7.4.4" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + +"@babel/runtime@^7.8.4", "@babel/runtime@^7.9.6": + version "7.11.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736" + integrity sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/template@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278" + integrity sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/parser" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/traverse@^7.10.4", "@babel/traverse@^7.11.0", "@babel/traverse@^7.7.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.0.tgz#9b996ce1b98f53f7c3e4175115605d56ed07dd24" + integrity sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/generator" "^7.11.0" + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.11.0" + "@babel/parser" "^7.11.0" + "@babel/types" "^7.11.0" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.19" + +"@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.4.4", "@babel/types@^7.7.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.0.tgz#2ae6bf1ba9ae8c3c43824e5861269871b206e90d" + integrity sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA== + dependencies: + "@babel/helper-validator-identifier" "^7.10.4" + lodash "^4.17.19" + to-fast-properties "^2.0.0" + +"@ckeditor/ckeditor5-core@^23.0.0": + version "23.0.0" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-core/-/ckeditor5-core-23.0.0.tgz#ae1a29bccd100e8fed5998f58abce4e6c47cd208" + integrity sha512-NjelymGQBJPnEplS0rN/y6oDCdg6+5BcFF5NffxCzzXyqrFguIVSzgSaBXB7ujwX6AkecvEPM7yN8UQg+8z98A== + dependencies: + "@ckeditor/ckeditor5-engine" "^23.0.0" + "@ckeditor/ckeditor5-utils" "^23.0.0" + lodash-es "^4.17.15" + +"@ckeditor/ckeditor5-engine@^23.0.0": + version "23.0.0" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-23.0.0.tgz#9ab22fdaff274b4e94f76f74b70d119cc5d88ddb" + integrity sha512-DKYHxN7WORlX3HsgEXMlIaUQFfyGzg21aMA8vRIl3IZrDKdsyJILu63Z+CTs0NSP5CGZyOqwSPE20Pf5luQrUA== + dependencies: + "@ckeditor/ckeditor5-utils" "^23.0.0" + lodash-es "^4.17.15" + +"@ckeditor/ckeditor5-ui@^23.0.0": + version "23.0.0" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-23.0.0.tgz#2beead2be04cf23f7af2a3a660ad0ecb1bb7ecd6" + integrity sha512-X8RyCPMRWBYkb+Ze3e588JOGWfVz8C4cwkYbCHoKC9IaAnJhVeFngQIRMEP4+lTdqTEBW6q/5RZotKLlNOPY2g== + dependencies: + "@ckeditor/ckeditor5-core" "^23.0.0" + "@ckeditor/ckeditor5-utils" "^23.0.0" + lodash-es "^4.17.15" + +"@ckeditor/ckeditor5-upload@^23.0.0": + version "23.0.0" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-upload/-/ckeditor5-upload-23.0.0.tgz#a9cbde33dcbf8e7d40273afd6cc5799233401291" + integrity sha512-mqWpUP5HzRjj5s+fBxVxs+M4xFBK05nQybbOIDZGLTtdUm8dNghOpz9m9PFZlTLu5GaaROGERIXxEatYafqxDw== + dependencies: + "@ckeditor/ckeditor5-core" "^23.0.0" + "@ckeditor/ckeditor5-ui" "^23.0.0" + "@ckeditor/ckeditor5-utils" "^23.0.0" + +"@ckeditor/ckeditor5-utils@^23.0.0": + version "23.0.0" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-23.0.0.tgz#1e002dbf5dc1890cfea6d3bd9213005205861689" + integrity sha512-el37RemQW207NBN3/DK5XNsFPiyno67bAAQ0Xw0nLqqgQhxPP+UyIWlG2F2Oa7eiVWg2/UdGgeQOOq/OV3ZYTA== + dependencies: + lodash-es "^4.17.15" + +"@ckeditor/ckeditor5-vue@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-vue/-/ckeditor5-vue-1.0.1.tgz#cddb99609f61b647214b704656c08a15b6a53865" + integrity sha512-4MaQwZ04cWwqYW0732sg2aqx9ILeHIP0LSLKUuLCLR21qYONZPvxY/V/czh1DH99toaL/iwPvEoJtO2ldriPaA== + +"@hapi/address@2.x.x": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5" + integrity sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ== + +"@hapi/bourne@1.x.x": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@hapi/bourne/-/bourne-1.3.2.tgz#0a7095adea067243ce3283e1b56b8a8f453b242a" + integrity sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA== + +"@hapi/hoek@8.x.x", "@hapi/hoek@^8.3.0": + version "8.5.1" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.5.1.tgz#fde96064ca446dec8c55a8c2f130957b070c6e06" + integrity sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow== + +"@hapi/joi@^15.0.1": + version "15.1.1" + resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-15.1.1.tgz#c675b8a71296f02833f8d6d243b34c57b8ce19d7" + integrity sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ== + dependencies: + "@hapi/address" "2.x.x" + "@hapi/bourne" "1.x.x" + "@hapi/hoek" "8.x.x" + "@hapi/topo" "3.x.x" + +"@hapi/topo@3.x.x": + version "3.1.6" + resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-3.1.6.tgz#68d935fa3eae7fdd5ab0d7f953f3205d8b2bfc29" + integrity sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ== + dependencies: + "@hapi/hoek" "^8.3.0" + +"@intervolga/optimize-cssnano-plugin@^1.0.5": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@intervolga/optimize-cssnano-plugin/-/optimize-cssnano-plugin-1.0.6.tgz#be7c7846128b88f6a9b1d1261a0ad06eb5c0fdf8" + integrity sha512-zN69TnSr0viRSU6cEDIcuPcP67QcpQ6uHACg58FiN9PDrU6SLyGW3MR4tiISbYxy1kDWAVPwD+XwQTWE5cigAA== + dependencies: + cssnano "^4.0.0" + cssnano-preset-default "^4.0.0" + postcss "^7.0.0" + +"@mrmlnc/readdir-enhanced@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" + integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== + dependencies: + call-me-maybe "^1.0.1" + glob-to-regexp "^0.3.0" + +"@nodelib/fs.stat@^1.1.2": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" + integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== + +"@soda/friendly-errors-webpack-plugin@^1.7.1": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.7.1.tgz#706f64bcb4a8b9642b48ae3ace444c70334d615d" + integrity sha512-cWKrGaFX+rfbMrAxVv56DzhPNqOJPZuNIS2HGMELtgGzb+vsMzyig9mml5gZ/hr2BGtSLV+dP2LUEuAL8aG2mQ== + dependencies: + chalk "^1.1.3" + error-stack-parser "^2.0.0" + string-width "^2.0.0" + +"@soda/get-current-script@^1.0.0": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@soda/get-current-script/-/get-current-script-1.0.2.tgz#a53515db25d8038374381b73af20bb4f2e508d87" + integrity sha512-T7VNNlYVM1SgQ+VsMYhnDkcGmWhQdL0bDyGm5TlQ3GBXnJscEClUUOKduWTmm2zCnvNLC1hc3JpuXjs/nFOc5w== + +"@types/anymatch@*": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" + integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA== + +"@types/body-parser@*": + version "1.19.0" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.0.tgz#0685b3c47eb3006ffed117cdd55164b61f80538f" + integrity sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/color-name@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" + integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== + +"@types/connect-history-api-fallback@*": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.3.tgz#4772b79b8b53185f0f4c9deab09236baf76ee3b4" + integrity sha512-7SxFCd+FLlxCfwVwbyPxbR4khL9aNikJhrorw8nUIOqeuooc9gifBuDQOJw5kzN7i6i3vLn9G8Wde/4QDihpYw== + dependencies: + "@types/express-serve-static-core" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.33" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.33.tgz#31610c901eca573b8713c3330abc6e6b9f588546" + integrity sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A== + dependencies: + "@types/node" "*" + +"@types/express-serve-static-core@*": + version "4.17.12" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.12.tgz#9a487da757425e4f267e7d1c5720226af7f89591" + integrity sha512-EaEdY+Dty1jEU7U6J4CUWwxL+hyEGMkO5jan5gplfegUgCUsIUWqXxqw47uGjimeT4Qgkz/XUfwoau08+fgvKA== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@*": + version "4.17.8" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.8.tgz#3df4293293317e61c60137d273a2e96cd8d5f27a" + integrity sha512-wLhcKh3PMlyA2cNAB9sjM1BntnhPMiM0JOBwPBqttjHev2428MLEB4AYVN+d8s2iyCVZac+o41Pflm/ZH5vLXQ== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "*" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/glob@^7.1.1": + version "7.1.3" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" + integrity sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w== + dependencies: + "@types/minimatch" "*" + "@types/node" "*" + +"@types/http-proxy-middleware@*": + version "0.19.3" + resolved "https://registry.yarnpkg.com/@types/http-proxy-middleware/-/http-proxy-middleware-0.19.3.tgz#b2eb96fbc0f9ac7250b5d9c4c53aade049497d03" + integrity sha512-lnBTx6HCOUeIJMLbI/LaL5EmdKLhczJY5oeXZpX/cXE4rRqb3RmV7VcMpiEfYkmTjipv3h7IAyIINe4plEv7cA== + dependencies: + "@types/connect" "*" + "@types/http-proxy" "*" + "@types/node" "*" + +"@types/http-proxy@*": + version "1.17.4" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.4.tgz#e7c92e3dbe3e13aa799440ff42e6d3a17a9d045b" + integrity sha512-IrSHl2u6AWXduUaDLqYpt45tLVCtYv7o4Z0s1KghBCDgIIS9oW5K1H8mZG/A2CfeLdEa7rTd1ACOiHBc1EMT2Q== + dependencies: + "@types/node" "*" + +"@types/json-schema@^7.0.4": + version "7.0.5" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd" + integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ== + +"@types/mime@*": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.3.tgz#c893b73721db73699943bfc3653b1deb7faa4a3a" + integrity sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q== + +"@types/mini-css-extract-plugin@^0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@types/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.1.tgz#d4bdde5197326fca039d418f4bdda03dc74dc451" + integrity sha512-+mN04Oszdz9tGjUP/c1ReVwJXxSniLd7lF++sv+8dkABxVNthg6uccei+4ssKxRHGoMmPxdn7uBdJWONSJGTGQ== + dependencies: + "@types/webpack" "*" + +"@types/minimatch@*": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" + integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== + +"@types/minimist@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.0.tgz#69a23a3ad29caf0097f06eda59b361ee2f0639f6" + integrity sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY= + +"@types/node@*": + version "14.0.27" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.27.tgz#a151873af5a5e851b51b3b065c9e63390a9e0eb1" + integrity sha512-kVrqXhbclHNHGu9ztnAwSncIgJv/FaxmzXJvGXNdcCpV1b8u1/Mi6z6m0vwy0LzKeXFTPLH0NzwmoJ3fNCIq0g== + +"@types/normalize-package-data@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" + integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== + +"@types/q@^1.5.1": + version "1.5.4" + resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24" + integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug== + +"@types/qs@*": + version "6.9.4" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.4.tgz#a59e851c1ba16c0513ea123830dd639a0a15cb6a" + integrity sha512-+wYo+L6ZF6BMoEjtf8zB2esQsqdV6WsjRK/GP9WOgLPrq87PbNWgIxS76dS5uvl/QXtHGakZmwTznIfcPXcKlQ== + +"@types/range-parser@*": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" + integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== + +"@types/serve-static@*": + version "1.13.5" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.5.tgz#3d25d941a18415d3ab092def846e135a08bbcf53" + integrity sha512-6M64P58N+OXjU432WoLLBQxbA0LRGBCRm7aAGQJ+SMC1IMl0dgRVi9EFfoDcS2a7Xogygk/eGN94CfwU9UF7UQ== + dependencies: + "@types/express-serve-static-core" "*" + "@types/mime" "*" + +"@types/source-list-map@*": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" + integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA== + +"@types/tapable@*": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.6.tgz#a9ca4b70a18b270ccb2bc0aaafefd1d486b7ea74" + integrity sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA== + +"@types/uglify-js@*": + version "3.9.3" + resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.9.3.tgz#d94ed608e295bc5424c9600e6b8565407b6b4b6b" + integrity sha512-KswB5C7Kwduwjj04Ykz+AjvPcfgv/37Za24O2EDzYNbwyzOo8+ydtvzUfZ5UMguiVu29Gx44l1A6VsPPcmYu9w== + dependencies: + source-map "^0.6.1" + +"@types/webpack-dev-server@^3.11.0": + version "3.11.0" + resolved "https://registry.yarnpkg.com/@types/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz#bcc3b85e7dc6ac2db25330610513f2228c2fcfb2" + integrity sha512-3+86AgSzl18n5P1iUP9/lz3G3GMztCp+wxdDvVuNhx1sr1jE79GpYfKHL8k+Vht3N74K2n98CuAEw4YPJCYtDA== + dependencies: + "@types/connect-history-api-fallback" "*" + "@types/express" "*" + "@types/http-proxy-middleware" "*" + "@types/serve-static" "*" + "@types/webpack" "*" + +"@types/webpack-sources@*": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-1.4.2.tgz#5d3d4dea04008a779a90135ff96fb5c0c9e6292c" + integrity sha512-77T++JyKow4BQB/m9O96n9d/UUHWLQHlcqXb9Vsf4F1+wKNrrlWNFPDLKNT92RJnCSL6CieTc+NDXtCVZswdTw== + dependencies: + "@types/node" "*" + "@types/source-list-map" "*" + source-map "^0.7.3" + +"@types/webpack@*", "@types/webpack@^4.0.0": + version "4.41.22" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.22.tgz#ff9758a17c6bd499e459b91e78539848c32d0731" + integrity sha512-JQDJK6pj8OMV9gWOnN1dcLCyU9Hzs6lux0wBO4lr1+gyEhIBR9U3FMrz12t2GPkg110XAxEAw2WHF6g7nZIbRQ== + dependencies: + "@types/anymatch" "*" + "@types/node" "*" + "@types/tapable" "*" + "@types/uglify-js" "*" + "@types/webpack-sources" "*" + source-map "^0.6.0" + +"@vue/babel-helper-vue-jsx-merge-props@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.0.0.tgz#048fe579958da408fb7a8b2a3ec050b50a661040" + integrity sha512-6tyf5Cqm4m6v7buITuwS+jHzPlIPxbFzEhXR5JGZpbrvOcp1hiQKckd305/3C7C36wFekNTQSxAtgeM0j0yoUw== + +"@vue/babel-plugin-transform-vue-jsx@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.1.2.tgz#c0a3e6efc022e75e4247b448a8fc6b86f03e91c0" + integrity sha512-YfdaoSMvD1nj7+DsrwfTvTnhDXI7bsuh+Y5qWwvQXlD24uLgnsoww3qbiZvWf/EoviZMrvqkqN4CBw0W3BWUTQ== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/plugin-syntax-jsx" "^7.2.0" + "@vue/babel-helper-vue-jsx-merge-props" "^1.0.0" + html-tags "^2.0.0" + lodash.kebabcase "^4.1.1" + svg-tags "^1.0.0" + +"@vue/babel-preset-app@^4.4.6": + version "4.4.6" + resolved "https://registry.yarnpkg.com/@vue/babel-preset-app/-/babel-preset-app-4.4.6.tgz#92aef916e83f1abe0a2ed1e9e2cef5b332f958c4" + integrity sha512-urIa6Qk3lKacLvscrzxMNyYlTqKFcPAUo5MohOjv1ISZ9PssHw693WTOrqSC0XksdMLtp/rnLvc6l5G8Muk0lw== + dependencies: + "@babel/core" "^7.9.6" + "@babel/helper-compilation-targets" "^7.9.6" + "@babel/helper-module-imports" "^7.8.3" + "@babel/plugin-proposal-class-properties" "^7.8.3" + "@babel/plugin-proposal-decorators" "^7.8.3" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-syntax-jsx" "^7.8.3" + "@babel/plugin-transform-runtime" "^7.9.6" + "@babel/preset-env" "^7.9.6" + "@babel/runtime" "^7.9.6" + "@vue/babel-preset-jsx" "^1.1.2" + babel-plugin-dynamic-import-node "^2.3.3" + core-js "^3.6.5" + core-js-compat "^3.6.5" + semver "^6.1.0" + +"@vue/babel-preset-jsx@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@vue/babel-preset-jsx/-/babel-preset-jsx-1.1.2.tgz#2e169eb4c204ea37ca66c2ea85a880bfc99d4f20" + integrity sha512-zDpVnFpeC9YXmvGIDSsKNdL7qCG2rA3gjywLYHPCKDT10erjxF4U+6ay9X6TW5fl4GsDlJp9bVfAVQAAVzxxvQ== + dependencies: + "@vue/babel-helper-vue-jsx-merge-props" "^1.0.0" + "@vue/babel-plugin-transform-vue-jsx" "^1.1.2" + "@vue/babel-sugar-functional-vue" "^1.1.2" + "@vue/babel-sugar-inject-h" "^1.1.2" + "@vue/babel-sugar-v-model" "^1.1.2" + "@vue/babel-sugar-v-on" "^1.1.2" + +"@vue/babel-sugar-functional-vue@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@vue/babel-sugar-functional-vue/-/babel-sugar-functional-vue-1.1.2.tgz#f7e24fba09e6f1ee70104560a8808057555f1a9a" + integrity sha512-YhmdJQSVEFF5ETJXzrMpj0nkCXEa39TvVxJTuVjzvP2rgKhdMmQzlJuMv/HpadhZaRVMCCF3AEjjJcK5q/cYzQ== + dependencies: + "@babel/plugin-syntax-jsx" "^7.2.0" + +"@vue/babel-sugar-inject-h@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@vue/babel-sugar-inject-h/-/babel-sugar-inject-h-1.1.2.tgz#8a5276b6d8e2ed16ffc8078aad94236274e6edf0" + integrity sha512-VRSENdTvD5htpnVp7i7DNuChR5rVMcORdXjvv5HVvpdKHzDZAYiLSD+GhnhxLm3/dMuk8pSzV+k28ECkiN5m8w== + dependencies: + "@babel/plugin-syntax-jsx" "^7.2.0" + +"@vue/babel-sugar-v-model@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@vue/babel-sugar-v-model/-/babel-sugar-v-model-1.1.2.tgz#1ff6fd1b800223fc9cb1e84dceb5e52d737a8192" + integrity sha512-vLXPvNq8vDtt0u9LqFdpGM9W9IWDmCmCyJXuozlq4F4UYVleXJ2Fa+3JsnTZNJcG+pLjjfnEGHci2339Kj5sGg== + dependencies: + "@babel/plugin-syntax-jsx" "^7.2.0" + "@vue/babel-helper-vue-jsx-merge-props" "^1.0.0" + "@vue/babel-plugin-transform-vue-jsx" "^1.1.2" + camelcase "^5.0.0" + html-tags "^2.0.0" + svg-tags "^1.0.0" + +"@vue/babel-sugar-v-on@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.1.2.tgz#b2ef99b8f2fab09fbead25aad70ef42e1cf5b13b" + integrity sha512-T8ZCwC8Jp2uRtcZ88YwZtZXe7eQrJcfRq0uTFy6ShbwYJyz5qWskRFoVsdTi9o0WEhmQXxhQUewodOSCUPVmsQ== + dependencies: + "@babel/plugin-syntax-jsx" "^7.2.0" + "@vue/babel-plugin-transform-vue-jsx" "^1.1.2" + camelcase "^5.0.0" + +"@vue/cli-overlay@^4.5.6": + version "4.5.6" + resolved "https://registry.yarnpkg.com/@vue/cli-overlay/-/cli-overlay-4.5.6.tgz#56544f9d3d4f74a3d8d593a497b137450ebfe171" + integrity sha512-8kFIdiErtGRlvKWJV0AcF6SXakQDxeuqqcMhWt3qIJxRH6aD33RTC37Q3KWuMsYryBZpEY3tNWGhS1d4spQu0g== + +"@vue/cli-plugin-babel@~4.4.0": + version "4.4.6" + resolved "https://registry.yarnpkg.com/@vue/cli-plugin-babel/-/cli-plugin-babel-4.4.6.tgz#d5d750d4f74900c00836e19c164193650df26f3b" + integrity sha512-9cX9mN+4DIbcqw3rV6UBOA0t5zikIkrBLQloUzsOBOu5Xb7/UoD7inInFj7bnyHUflr5LqbdWJ+etCQcWAIIXA== + dependencies: + "@babel/core" "^7.9.6" + "@vue/babel-preset-app" "^4.4.6" + "@vue/cli-shared-utils" "^4.4.6" + babel-loader "^8.1.0" + cache-loader "^4.1.0" + thread-loader "^2.1.3" + webpack "^4.0.0" + +"@vue/cli-plugin-eslint@~4.4.0": + version "4.4.6" + resolved "https://registry.yarnpkg.com/@vue/cli-plugin-eslint/-/cli-plugin-eslint-4.4.6.tgz#442d62a70dd93e4a549ff9164d2d10f4e97a58f1" + integrity sha512-3a9rVpOKPQsDgAlRkhmBMHboGobivG/47BbQGE66Z8YJxrgF/AWikP3Jy67SmxtszRkyiWfw4aJFRV9r3MzffQ== + dependencies: + "@vue/cli-shared-utils" "^4.4.6" + eslint-loader "^2.2.1" + globby "^9.2.0" + inquirer "^7.1.0" + webpack "^4.0.0" + yorkie "^2.0.0" + +"@vue/cli-plugin-router@^4.5.6": + version "4.5.6" + resolved "https://registry.yarnpkg.com/@vue/cli-plugin-router/-/cli-plugin-router-4.5.6.tgz#96f43cdeea6931ae25adb065dd757d6ff4f81354" + integrity sha512-QEqOGglg0JEKddZPuyiSnAzAVK7IzLrdTPCUegigzGSbUXDW4gQiltY3/2nij2q538YvdIM7JXtW1sUfy4MgHQ== + dependencies: + "@vue/cli-shared-utils" "^4.5.6" + +"@vue/cli-plugin-vuex@^4.5.6": + version "4.5.6" + resolved "https://registry.yarnpkg.com/@vue/cli-plugin-vuex/-/cli-plugin-vuex-4.5.6.tgz#484687d85369b0dca065c4491bf18efff5e31ecf" + integrity sha512-cWxj0jIhhupU+oFl0mc1St3ig9iF5F01XKwAhKEbvvuHR97zHxLd29My/vvcRwojZMy4aY320oJ+0ljoCIbueQ== + +"@vue/cli-service@^4.5.6": + version "4.5.6" + resolved "https://registry.yarnpkg.com/@vue/cli-service/-/cli-service-4.5.6.tgz#a63fd390ed8cbfb5d36201f54dec9aeb90ca93e3" + integrity sha512-wl0rhjHSpy2Mc2zNU6sfhaUVNNaRzgXNfZMIpTZMO3wJalPMLuvGC3KLMaXcpvuI01zeQBmkEocAdhzay4lQ0w== + dependencies: + "@intervolga/optimize-cssnano-plugin" "^1.0.5" + "@soda/friendly-errors-webpack-plugin" "^1.7.1" + "@soda/get-current-script" "^1.0.0" + "@types/minimist" "^1.2.0" + "@types/webpack" "^4.0.0" + "@types/webpack-dev-server" "^3.11.0" + "@vue/cli-overlay" "^4.5.6" + "@vue/cli-plugin-router" "^4.5.6" + "@vue/cli-plugin-vuex" "^4.5.6" + "@vue/cli-shared-utils" "^4.5.6" + "@vue/component-compiler-utils" "^3.1.2" + "@vue/preload-webpack-plugin" "^1.1.0" + "@vue/web-component-wrapper" "^1.2.0" + acorn "^7.4.0" + acorn-walk "^7.1.1" + address "^1.1.2" + autoprefixer "^9.8.6" + browserslist "^4.12.0" + cache-loader "^4.1.0" + case-sensitive-paths-webpack-plugin "^2.3.0" + cli-highlight "^2.1.4" + clipboardy "^2.3.0" + cliui "^6.0.0" + copy-webpack-plugin "^5.1.1" + css-loader "^3.5.3" + cssnano "^4.1.10" + debug "^4.1.1" + default-gateway "^5.0.5" + dotenv "^8.2.0" + dotenv-expand "^5.1.0" + file-loader "^4.2.0" + fs-extra "^7.0.1" + globby "^9.2.0" + hash-sum "^2.0.0" + html-webpack-plugin "^3.2.0" + launch-editor-middleware "^2.2.1" + lodash.defaultsdeep "^4.6.1" + lodash.mapvalues "^4.6.0" + lodash.transform "^4.6.0" + mini-css-extract-plugin "^0.9.0" + minimist "^1.2.5" + pnp-webpack-plugin "^1.6.4" + portfinder "^1.0.26" + postcss-loader "^3.0.0" + ssri "^7.1.0" + terser-webpack-plugin "^2.3.6" + thread-loader "^2.1.3" + url-loader "^2.2.0" + vue-loader "^15.9.2" + vue-style-loader "^4.1.2" + webpack "^4.0.0" + webpack-bundle-analyzer "^3.8.0" + webpack-chain "^6.4.0" + webpack-dev-server "^3.11.0" + webpack-merge "^4.2.2" + optionalDependencies: + vue-loader-v16 "npm:vue-loader@^16.0.0-beta.7" + +"@vue/cli-shared-utils@^4.4.6": + version "4.4.6" + resolved "https://registry.yarnpkg.com/@vue/cli-shared-utils/-/cli-shared-utils-4.4.6.tgz#0ec59880920736c6dd79079ac0b5ceac29fa55e1" + integrity sha512-ba+FZZCjiTSu2otnLjY4qXqASe7ZIQ/QBljk5oRPgqrR0p1NUkDPUcZhqa041aOaSW1yAfSfhOD7Q84nMnWhzQ== + dependencies: + "@hapi/joi" "^15.0.1" + chalk "^2.4.2" + execa "^1.0.0" + launch-editor "^2.2.1" + lru-cache "^5.1.1" + node-ipc "^9.1.1" + open "^6.3.0" + ora "^3.4.0" + read-pkg "^5.1.1" + request "^2.88.2" + semver "^6.1.0" + strip-ansi "^6.0.0" + +"@vue/cli-shared-utils@^4.5.6": + version "4.5.6" + resolved "https://registry.yarnpkg.com/@vue/cli-shared-utils/-/cli-shared-utils-4.5.6.tgz#14644972043c95566788d07d9a9367edd438a4d6" + integrity sha512-p6ePDlEa7Xc0GEt99KDOCwPZtR7UnoEaZLMfwPYU5LAWkdCmtAw8HPAY/WWcjtoiaAkY4k9tz7ZehQasZ9mJxg== + dependencies: + "@hapi/joi" "^15.0.1" + chalk "^2.4.2" + execa "^1.0.0" + launch-editor "^2.2.1" + lru-cache "^5.1.1" + node-ipc "^9.1.1" + open "^6.3.0" + ora "^3.4.0" + read-pkg "^5.1.1" + request "^2.88.2" + semver "^6.1.0" + strip-ansi "^6.0.0" + +"@vue/component-compiler-utils@^3.1.0", "@vue/component-compiler-utils@^3.1.2": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-3.2.0.tgz#8f85182ceed28e9b3c75313de669f83166d11e5d" + integrity sha512-lejBLa7xAMsfiZfNp7Kv51zOzifnb29FwdnMLa96z26kXErPFioSf9BMcePVIQ6/Gc6/mC0UrPpxAWIHyae0vw== + dependencies: + consolidate "^0.15.1" + hash-sum "^1.0.2" + lru-cache "^4.1.2" + merge-source-map "^1.1.0" + postcss "^7.0.14" + postcss-selector-parser "^6.0.2" + source-map "~0.6.1" + vue-template-es2015-compiler "^1.9.0" + optionalDependencies: + prettier "^1.18.2" + +"@vue/preload-webpack-plugin@^1.1.0": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@vue/preload-webpack-plugin/-/preload-webpack-plugin-1.1.2.tgz#ceb924b4ecb3b9c43871c7a429a02f8423e621ab" + integrity sha512-LIZMuJk38pk9U9Ur4YzHjlIyMuxPlACdBIHH9/nGYVTsaGKOSnSuELiE8vS9wa+dJpIYspYUOqk+L1Q4pgHQHQ== + +"@vue/web-component-wrapper@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@vue/web-component-wrapper/-/web-component-wrapper-1.2.0.tgz#bb0e46f1585a7e289b4ee6067dcc5a6ae62f1dd1" + integrity sha512-Xn/+vdm9CjuC9p3Ae+lTClNutrVhsXpzxvoTXXtoys6kVRX9FkueSUAqSWAyZntmVLlR4DosBV4pH8y5Z/HbUw== + +"@webassemblyjs/ast@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" + integrity sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA== + dependencies: + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + +"@webassemblyjs/floating-point-hex-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4" + integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA== + +"@webassemblyjs/helper-api-error@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2" + integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw== + +"@webassemblyjs/helper-buffer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00" + integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA== + +"@webassemblyjs/helper-code-frame@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27" + integrity sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA== + dependencies: + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/helper-fsm@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8" + integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw== + +"@webassemblyjs/helper-module-context@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07" + integrity sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g== + dependencies: + "@webassemblyjs/ast" "1.9.0" + +"@webassemblyjs/helper-wasm-bytecode@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790" + integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw== + +"@webassemblyjs/helper-wasm-section@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346" + integrity sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + +"@webassemblyjs/ieee754@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4" + integrity sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95" + integrity sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab" + integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w== + +"@webassemblyjs/wasm-edit@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf" + integrity sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/helper-wasm-section" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-opt" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/wasm-gen@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c" + integrity sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wasm-opt@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61" + integrity sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + +"@webassemblyjs/wasm-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e" + integrity sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wast-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914" + integrity sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/floating-point-hex-parser" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-code-frame" "1.9.0" + "@webassemblyjs/helper-fsm" "1.9.0" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/wast-printer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899" + integrity sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + "@xtuc/long" "4.2.2" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +acorn-jsx@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.2.0.tgz#4c66069173d6fdd68ed85239fc256226182b2ebe" + integrity sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ== + +acorn-walk@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" + integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== + +acorn@^6.4.1: + version "6.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" + integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== + +acorn@^7.1.1, acorn@^7.4.0: + version "7.4.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.0.tgz#e1ad486e6c54501634c6c397c5c121daa383607c" + integrity sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w== + +address@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" + integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== + +aggregate-error@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.0.1.tgz#db2fe7246e536f40d9b5442a39e117d7dd6a24e0" + integrity sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ajv-errors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" + integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== + +ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.12.3: + version "6.12.3" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.3.tgz#18c5af38a111ddeb4f2697bd78d68abc1cabd706" + integrity sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +alphanum-sort@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" + integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= + +ansi-colors@^3.0.0: + version "3.2.4" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" + integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== + +ansi-escapes@^4.2.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.1.tgz#a5c47cc43181f1f38ffd7076837700d395522a61" + integrity sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA== + dependencies: + type-fest "^0.11.0" + +ansi-html@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" + integrity sha1-gTWEAhliqenm/QOflA0S9WynhZ4= + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" + integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== + dependencies: + "@types/color-name" "^1.1.1" + color-convert "^2.0.1" + +any-promise@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +anymatch@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" + integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +aproba@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +arch@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/arch/-/arch-2.1.2.tgz#0c52bbe7344bb4fa260c443d2cbad9c00ff2f0bf" + integrity sha512-NTBIIbAfkJeIletyABbVtdPgeKfDafR+1mZV/AyyfC1UkVkp9iUjV+wwmqtUgphHYajbI86jejBJp5e+jkGTiQ== + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-flatten@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== + +array-union@^1.0.1, array-union@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +asn1.js@^4.0.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +assert@^1.1.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" + integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== + dependencies: + object-assign "^4.1.1" + util "0.10.3" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== + +async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + +async@^2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +autoprefixer@^9.8.6: + version "9.8.6" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.6.tgz#3b73594ca1bf9266320c5acf1588d74dea74210f" + integrity sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg== + dependencies: + browserslist "^4.12.0" + caniuse-lite "^1.0.30001109" + colorette "^1.2.1" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + postcss "^7.0.32" + postcss-value-parser "^4.1.0" + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.0.tgz#a17b3a8ea811060e74d47d306122400ad4497ae2" + integrity sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA== + +axios@^0.19.2: + version "0.19.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27" + integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA== + dependencies: + follow-redirects "1.5.10" + +babel-eslint@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.1.0.tgz#6968e568a910b78fb3779cdd8b6ac2f479943232" + integrity sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.7.0" + "@babel/traverse" "^7.7.0" + "@babel/types" "^7.7.0" + eslint-visitor-keys "^1.0.0" + resolve "^1.12.0" + +babel-loader@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.1.0.tgz#c611d5112bd5209abe8b9fa84c3e4da25275f1c3" + integrity sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw== + dependencies: + find-cache-dir "^2.1.0" + loader-utils "^1.4.0" + mkdirp "^0.5.3" + pify "^4.0.1" + schema-utils "^2.6.5" + +babel-plugin-dynamic-import-node@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" + integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== + dependencies: + object.assign "^4.1.0" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base64-js@^1.0.2: + version "1.3.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" + integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + +bfj@^6.1.1: + version "6.1.2" + resolved "https://registry.yarnpkg.com/bfj/-/bfj-6.1.2.tgz#325c861a822bcb358a41c78a33b8e6e2086dde7f" + integrity sha512-BmBJa4Lip6BPRINSZ0BPEIfB1wUY/9rwbwvIHQA1KjX9om29B6id0wnWXq7m3bn5JrUVjeOTnVuhPT1FiHwPGw== + dependencies: + bluebird "^3.5.5" + check-types "^8.0.3" + hoopy "^0.1.4" + tryer "^1.0.1" + +big.js@^3.1.3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" + integrity sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q== + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + +binary-extensions@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" + integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== + +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +bluebird@^3.1.1, bluebird@^3.5.5: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.4.0: + version "4.11.9" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828" + integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw== + +bn.js@^5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.2.tgz#c9686902d3c9a27729f43ab10f9d79c2004da7b0" + integrity sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA== + +body-parser@1.19.0: + version "1.19.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" + integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== + dependencies: + bytes "3.1.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.7.2" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.7.0" + raw-body "2.4.0" + type-is "~1.6.17" + +bonjour@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" + integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= + dependencies: + array-flatten "^2.1.0" + deep-equal "^1.0.1" + dns-equal "^1.0.0" + dns-txt "^2.0.2" + multicast-dns "^6.0.1" + multicast-dns-service-types "^1.1.0" + +boolbase@^1.0.0, boolbase@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= + dependencies: + bn.js "^4.1.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3" + integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg== + dependencies: + bn.js "^5.1.1" + browserify-rsa "^4.0.1" + create-hash "^1.2.0" + create-hmac "^1.1.7" + elliptic "^6.5.3" + inherits "^2.0.4" + parse-asn1 "^5.1.5" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== + dependencies: + pako "~1.0.5" + +browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.8.5: + version "4.14.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.0.tgz#2908951abfe4ec98737b72f34c3bcedc8d43b000" + integrity sha512-pUsXKAF2lVwhmtpeA3LJrZ76jXuusrNyhduuQs7CDFf9foT4Y38aQOserd2lMe5DSSrjf3fx34oHwryuvxAUgQ== + dependencies: + caniuse-lite "^1.0.30001111" + electron-to-chromium "^1.3.523" + escalade "^3.0.2" + node-releases "^1.1.60" + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer-indexof@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" + integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== + +buffer-json@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/buffer-json/-/buffer-json-2.0.0.tgz#f73e13b1e42f196fe2fd67d001c7d7107edd7c23" + integrity sha512-+jjPFVqyfF1esi9fvfUs3NqM0pH1ziZ36VP4hmA/y/Ssfo/5w5xHKfTw9BwQjoJ1w/oVtpLomqwUHKdefGyuHw== + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + +buffer@^4.3.0: + version "4.9.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + +bytes@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== + +cacache@^12.0.2, cacache@^12.0.3: + version "12.0.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" + integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== + dependencies: + bluebird "^3.5.5" + chownr "^1.1.1" + figgy-pudding "^3.5.1" + glob "^7.1.4" + graceful-fs "^4.1.15" + infer-owner "^1.0.3" + lru-cache "^5.1.1" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.3" + ssri "^6.0.1" + unique-filename "^1.1.1" + y18n "^4.0.0" + +cacache@^13.0.1: + version "13.0.1" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-13.0.1.tgz#a8000c21697089082f85287a1aec6e382024a71c" + integrity sha512-5ZvAxd05HDDU+y9BVvcqYu2LLXmPnQ0hW62h32g4xBTgL/MppR4/04NHfj/ycM2y6lmTnbw6HVi+1eN0Psba6w== + dependencies: + chownr "^1.1.2" + figgy-pudding "^3.5.1" + fs-minipass "^2.0.0" + glob "^7.1.4" + graceful-fs "^4.2.2" + infer-owner "^1.0.4" + lru-cache "^5.1.1" + minipass "^3.0.0" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.2" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + p-map "^3.0.0" + promise-inflight "^1.0.1" + rimraf "^2.7.1" + ssri "^7.0.0" + unique-filename "^1.1.1" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +cache-loader@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cache-loader/-/cache-loader-4.1.0.tgz#9948cae353aec0a1fcb1eafda2300816ec85387e" + integrity sha512-ftOayxve0PwKzBF/GLsZNC9fJBXl8lkZE3TOsjkboHfVHVkL39iUEs1FO07A33mizmci5Dudt38UZrrYXDtbhw== + dependencies: + buffer-json "^2.0.0" + find-cache-dir "^3.0.0" + loader-utils "^1.2.3" + mkdirp "^0.5.1" + neo-async "^2.6.1" + schema-utils "^2.0.0" + +call-me-maybe@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" + integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= + +caller-callsite@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" + integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= + dependencies: + callsites "^2.0.0" + +caller-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" + integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= + dependencies: + caller-callsite "^2.0.0" + +callsites@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camel-case@3.0.x: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" + integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M= + dependencies: + no-case "^2.2.0" + upper-case "^1.1.1" + +camelcase@^5.0.0, camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +caniuse-api@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" + integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== + dependencies: + browserslist "^4.0.0" + caniuse-lite "^1.0.0" + lodash.memoize "^4.1.2" + lodash.uniq "^4.5.0" + +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001111: + version "1.0.30001112" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001112.tgz#0fffc3b934ff56ff0548c37bc9dad7d882bcf672" + integrity sha512-J05RTQlqsatidif/38aN3PGULCLrg8OYQOlJUKbeYVzC2mGZkZLIztwRlB3MtrfLmawUmjFlNJvy/uhwniIe1Q== + +case-sensitive-paths-webpack-plugin@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz#23ac613cc9a856e4f88ff8bb73bbb5e989825cf7" + integrity sha512-/4YgnZS8y1UXXmC02xD5rRrBEu6T5ub+mQHLNRj0fzTRbgdBYhsNo2V5EqwgqrExjxsjtF/OpAKAMkKsxbD5XQ== + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chalk@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" + integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + +check-types@^8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/check-types/-/check-types-8.0.3.tgz#3356cca19c889544f2d7a95ed49ce508a0ecf552" + integrity sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ== + +chokidar@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" + optionalDependencies: + fsevents "^1.2.7" + +chokidar@^3.4.1: + version "3.4.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.2.tgz#38dc8e658dec3809741eb3ef7bb0a47fe424232d" + integrity sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.4.0" + optionalDependencies: + fsevents "~2.1.2" + +chownr@^1.1.1, chownr@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +chrome-trace-event@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" + integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== + dependencies: + tslib "^1.9.0" + +ci-info@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" + integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +ckeditor5-build-classic-simple-upload-adapter-image-resize@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/ckeditor5-build-classic-simple-upload-adapter-image-resize/-/ckeditor5-build-classic-simple-upload-adapter-image-resize-1.0.4.tgz#9ded03761c6d3bbc42d995aa038a3304f24dee04" + integrity sha512-9h1ypNTsmZMfKUcWmE0huvRr2BsgPKTyiar5v+aLJS2UkSdNNgD/Lw+baGLgnkVjIG+iVsQCR5V9JRSgyrVrkg== + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +clean-css@4.2.x: + version "4.2.3" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78" + integrity sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA== + dependencies: + source-map "~0.6.0" + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= + dependencies: + restore-cursor "^2.0.0" + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-highlight@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/cli-highlight/-/cli-highlight-2.1.4.tgz#098cb642cf17f42adc1c1145e07f960ec4d7522b" + integrity sha512-s7Zofobm20qriqDoU9sXptQx0t2R9PEgac92mENNm7xaEe1hn71IIMsXMK+6encA6WRCWWxIGQbipr3q998tlQ== + dependencies: + chalk "^3.0.0" + highlight.js "^9.6.0" + mz "^2.4.0" + parse5 "^5.1.1" + parse5-htmlparser2-tree-adapter "^5.1.1" + yargs "^15.0.0" + +cli-spinners@^2.0.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.4.0.tgz#c6256db216b878cfba4720e719cec7cf72685d7f" + integrity sha512-sJAofoarcm76ZGpuooaO0eDy8saEy+YoZBLjC4h8srt4jeBnkYeOgqxgsJQTpyt2LjI5PTfLJHSL+41Yu4fEJA== + +cli-width@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" + integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== + +clipboardy@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/clipboardy/-/clipboardy-2.3.0.tgz#3c2903650c68e46a91b388985bc2774287dba290" + integrity sha512-mKhiIL2DrQIsuXMgBgnfEHOZOryC7kY7YO//TN6c63wlEm3NG5tz+YgY5rVi29KCmq/QQjKYvM7a19+MDOTHOQ== + dependencies: + arch "^2.1.1" + execa "^1.0.0" + is-wsl "^2.1.1" + +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + +cliui@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" + integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^6.2.0" + +clone@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= + +coa@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3" + integrity sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA== + dependencies: + "@types/q" "^1.5.1" + chalk "^2.4.1" + q "^1.1.2" + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0, color-convert@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@^1.0.0, color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +color-string@^1.5.2: + version "1.5.3" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" + integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/color/-/color-3.1.2.tgz#68148e7f85d41ad7649c5fa8c8106f098d229e10" + integrity sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg== + dependencies: + color-convert "^1.9.1" + color-string "^1.5.2" + +colorette@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b" + integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw== + +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@2.17.x: + version "2.17.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" + integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== + +commander@^2.18.0, commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@~2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" + integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concat-stream@^1.5.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +connect-history-api-fallback@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" + integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== + +console-browserify@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" + integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== + +consolidate@^0.15.1: + version "0.15.1" + resolved "https://registry.yarnpkg.com/consolidate/-/consolidate-0.15.1.tgz#21ab043235c71a07d45d9aad98593b0dba56bab7" + integrity sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw== + dependencies: + bluebird "^3.1.1" + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= + +content-disposition@0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" + integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== + dependencies: + safe-buffer "5.1.2" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +convert-source-map@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" + integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== + dependencies: + safe-buffer "~5.1.1" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" + integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== + +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +copy-webpack-plugin@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-5.1.1.tgz#5481a03dea1123d88a988c6ff8b78247214f0b88" + integrity sha512-P15M5ZC8dyCjQHWwd4Ia/dm0SgVvZJMYeykVIVYXbGyqO4dWB5oyPHp9i7wjwo5LhtlhKbiBCdS2NvM07Wlybg== + dependencies: + cacache "^12.0.3" + find-cache-dir "^2.1.0" + glob-parent "^3.1.0" + globby "^7.1.1" + is-glob "^4.0.1" + loader-utils "^1.2.3" + minimatch "^3.0.4" + normalize-path "^3.0.0" + p-limit "^2.2.1" + schema-utils "^1.0.0" + serialize-javascript "^2.1.2" + webpack-log "^2.0.0" + +core-js-compat@^3.6.2, core-js-compat@^3.6.5: + version "3.6.5" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.6.5.tgz#2a51d9a4e25dfd6e690251aa81f99e3c05481f1c" + integrity sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng== + dependencies: + browserslist "^4.8.5" + semver "7.0.0" + +core-js@^3.6.5: + version "3.6.5" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.5.tgz#7395dc273af37fb2e50e9bd3d9fe841285231d1a" + integrity sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA== + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +cosmiconfig@^5.0.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" + integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== + dependencies: + import-fresh "^2.0.0" + is-directory "^0.3.1" + js-yaml "^3.13.1" + parse-json "^4.0.0" + +create-ecdh@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" + integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== + dependencies: + bn.js "^4.1.0" + elliptic "^6.5.3" + +create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^6.0.0, cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^7.0.0: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +css-color-names@0.0.4, css-color-names@^0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" + integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA= + +css-declaration-sorter@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz#c198940f63a76d7e36c1e71018b001721054cb22" + integrity sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA== + dependencies: + postcss "^7.0.1" + timsort "^0.3.0" + +css-loader@^3.5.3: + version "3.6.0" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.6.0.tgz#2e4b2c7e6e2d27f8c8f28f61bffcd2e6c91ef645" + integrity sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ== + dependencies: + camelcase "^5.3.1" + cssesc "^3.0.0" + icss-utils "^4.1.1" + loader-utils "^1.2.3" + normalize-path "^3.0.0" + postcss "^7.0.32" + postcss-modules-extract-imports "^2.0.0" + postcss-modules-local-by-default "^3.0.2" + postcss-modules-scope "^2.2.0" + postcss-modules-values "^3.0.0" + postcss-value-parser "^4.1.0" + schema-utils "^2.7.0" + semver "^6.3.0" + +css-select-base-adapter@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" + integrity sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w== + +css-select@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" + integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= + dependencies: + boolbase "~1.0.0" + css-what "2.1" + domutils "1.5.1" + nth-check "~1.0.1" + +css-select@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.1.0.tgz#6a34653356635934a81baca68d0255432105dbef" + integrity sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ== + dependencies: + boolbase "^1.0.0" + css-what "^3.2.1" + domutils "^1.7.0" + nth-check "^1.0.2" + +css-tree@1.0.0-alpha.37: + version "1.0.0-alpha.37" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22" + integrity sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg== + dependencies: + mdn-data "2.0.4" + source-map "^0.6.1" + +css-tree@1.0.0-alpha.39: + version "1.0.0-alpha.39" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.39.tgz#2bff3ffe1bb3f776cf7eefd91ee5cba77a149eeb" + integrity sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA== + dependencies: + mdn-data "2.0.6" + source-map "^0.6.1" + +css-what@2.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" + integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== + +css-what@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.3.0.tgz#10fec696a9ece2e591ac772d759aacabac38cd39" + integrity sha512-pv9JPyatiPaQ6pf4OvD/dbfm0o5LviWmwxNWzblYf/1u9QZd0ihV+PMwy5jdQWQ3349kZmKEx9WXuSka2dM4cg== + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +cssnano-preset-default@^4.0.0, cssnano-preset-default@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz#51ec662ccfca0f88b396dcd9679cdb931be17f76" + integrity sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA== + dependencies: + css-declaration-sorter "^4.0.1" + cssnano-util-raw-cache "^4.0.1" + postcss "^7.0.0" + postcss-calc "^7.0.1" + postcss-colormin "^4.0.3" + postcss-convert-values "^4.0.1" + postcss-discard-comments "^4.0.2" + postcss-discard-duplicates "^4.0.2" + postcss-discard-empty "^4.0.1" + postcss-discard-overridden "^4.0.1" + postcss-merge-longhand "^4.0.11" + postcss-merge-rules "^4.0.3" + postcss-minify-font-values "^4.0.2" + postcss-minify-gradients "^4.0.2" + postcss-minify-params "^4.0.2" + postcss-minify-selectors "^4.0.2" + postcss-normalize-charset "^4.0.1" + postcss-normalize-display-values "^4.0.2" + postcss-normalize-positions "^4.0.2" + postcss-normalize-repeat-style "^4.0.2" + postcss-normalize-string "^4.0.2" + postcss-normalize-timing-functions "^4.0.2" + postcss-normalize-unicode "^4.0.1" + postcss-normalize-url "^4.0.1" + postcss-normalize-whitespace "^4.0.2" + postcss-ordered-values "^4.1.2" + postcss-reduce-initial "^4.0.3" + postcss-reduce-transforms "^4.0.2" + postcss-svgo "^4.0.2" + postcss-unique-selectors "^4.0.1" + +cssnano-util-get-arguments@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz#ed3a08299f21d75741b20f3b81f194ed49cc150f" + integrity sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8= + +cssnano-util-get-match@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz#c0e4ca07f5386bb17ec5e52250b4f5961365156d" + integrity sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0= + +cssnano-util-raw-cache@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz#b26d5fd5f72a11dfe7a7846fb4c67260f96bf282" + integrity sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA== + dependencies: + postcss "^7.0.0" + +cssnano-util-same-parent@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz#574082fb2859d2db433855835d9a8456ea18bbf3" + integrity sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q== + +cssnano@^4.0.0, cssnano@^4.1.10: + version "4.1.10" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.10.tgz#0ac41f0b13d13d465487e111b778d42da631b8b2" + integrity sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ== + dependencies: + cosmiconfig "^5.0.0" + cssnano-preset-default "^4.0.7" + is-resolvable "^1.0.0" + postcss "^7.0.0" + +csso@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/csso/-/csso-4.0.3.tgz#0d9985dc852c7cc2b2cacfbbe1079014d1a8e903" + integrity sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ== + dependencies: + css-tree "1.0.0-alpha.39" + +cyclist@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" + integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +de-indent@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" + integrity sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0= + +debug@2.6.9, debug@^2.2.0, debug@^2.3.3: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@=3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +debug@^3.1.1, debug@^3.2.5: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +deep-equal@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" + integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== + dependencies: + is-arguments "^1.0.4" + is-date-object "^1.0.1" + is-regex "^1.0.4" + object-is "^1.0.1" + object-keys "^1.1.1" + regexp.prototype.flags "^1.2.0" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +deepmerge@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-1.5.2.tgz#10499d868844cdad4fee0842df8c7f6f0c95a753" + integrity sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ== + +default-gateway@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b" + integrity sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA== + dependencies: + execa "^1.0.0" + ip-regex "^2.1.0" + +default-gateway@^5.0.5: + version "5.0.5" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-5.0.5.tgz#4fd6bd5d2855d39b34cc5a59505486e9aafc9b10" + integrity sha512-z2RnruVmj8hVMmAnEJMTIJNijhKCDiGjbLP+BHJFOT7ld3Bo5qcIBpVYDniqhbMIIf+jZDlkP2MkPXiQy/DBLA== + dependencies: + execa "^3.3.0" + +defaults@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" + integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= + dependencies: + clone "^1.0.2" + +define-properties@^1.1.2, define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +del@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4" + integrity sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ== + dependencies: + "@types/glob" "^7.1.1" + globby "^6.1.0" + is-path-cwd "^2.0.0" + is-path-in-cwd "^2.0.0" + p-map "^2.0.0" + pify "^4.0.1" + rimraf "^2.6.3" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +des.js@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" + integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +detect-node@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" + integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw== + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +dir-glob@^2.0.0, dir-glob@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" + integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw== + dependencies: + path-type "^3.0.0" + +dns-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" + integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= + +dns-packet@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.1.tgz#12aa426981075be500b910eedcd0b47dd7deda5a" + integrity sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg== + dependencies: + ip "^1.1.0" + safe-buffer "^5.0.1" + +dns-txt@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" + integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= + dependencies: + buffer-indexof "^1.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +dom-converter@^0.2: + version "0.2.0" + resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" + integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== + dependencies: + utila "~0.4" + +dom-serializer@0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" + integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== + dependencies: + domelementtype "^2.0.1" + entities "^2.0.0" + +domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== + +domelementtype@1, domelementtype@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" + integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== + +domelementtype@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" + integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ== + +domhandler@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" + integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== + dependencies: + domelementtype "1" + +domutils@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" + integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= + dependencies: + dom-serializer "0" + domelementtype "1" + +domutils@^1.5.1, domutils@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== + dependencies: + dom-serializer "0" + domelementtype "1" + +dot-prop@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.2.0.tgz#c34ecc29556dc45f1f4c22697b6f4904e0cc4fcb" + integrity sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A== + dependencies: + is-obj "^2.0.0" + +dotenv-expand@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" + integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== + +dotenv@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" + integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== + +duplexer@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E= + +duplexify@^3.4.2, duplexify@^3.6.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +easy-stack@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/easy-stack/-/easy-stack-1.0.0.tgz#12c91b3085a37f0baa336e9486eac4bf94e3e788" + integrity sha1-EskbMIWjfwuqM26UhurEv5Tj54g= + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +ejs@^2.6.1: + version "2.7.4" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.4.tgz#48661287573dcc53e366c7a1ae52c3a120eec9ba" + integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA== + +electron-to-chromium@^1.3.523: + version "1.3.524" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.524.tgz#dd49646594466192de35956a5369bb20d616aa78" + integrity sha512-ZUvklIBkfXQyA6IeiEss1nfKRICcdB5afAGZAaPGaExdfrkpUu/WWVO+X7QpNnphaVMllXnAcvKnVPdyM+DCPQ== + +elliptic@^6.5.3: + version "6.5.3" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6" + integrity sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw== + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +enhanced-resolve@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz#3b806f3bfafc1ec7de69551ef93cca46c1704126" + integrity sha512-3e87LvavsdxyoCfGusJnrZ5G8SLPOFeHSNpZI/ATL9a5leXo2k0w6MKnbqhdBad9qTobSfB20Ld7UmgoNbAZkQ== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.5.0" + tapable "^1.0.0" + +entities@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" + integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== + +entities@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.3.tgz#5c487e5742ab93c15abb5da22759b8590ec03b7f" + integrity sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ== + +errno@^0.1.3, errno@~0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" + integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== + dependencies: + prr "~1.0.1" + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +error-stack-parser@^2.0.0: + version "2.0.6" + resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.6.tgz#5a99a707bd7a4c58a797902d48d82803ede6aad8" + integrity sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ== + dependencies: + stackframe "^1.1.1" + +es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.5: + version "1.17.6" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a" + integrity sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw== + dependencies: + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + is-callable "^1.2.0" + is-regex "^1.1.0" + object-inspect "^1.7.0" + object-keys "^1.1.1" + object.assign "^4.1.0" + string.prototype.trimend "^1.0.1" + string.prototype.trimstart "^1.0.1" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +escalade@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.0.2.tgz#6a580d70edb87880f22b4c91d0d56078df6962c4" + integrity sha512-gPYAU37hYCUhW5euPeR+Y74F7BL+IBsV93j5cvGriSaD1aG6MGsqsV1yamRdrWrb2j3aiZvb0X+UBOWpx3JWtQ== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +eslint-loader@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/eslint-loader/-/eslint-loader-2.2.1.tgz#28b9c12da54057af0845e2a6112701a2f6bf8337" + integrity sha512-RLgV9hoCVsMLvOxCuNjdqOrUqIj9oJg8hF44vzJaYqsAHuY9G2YAeN3joQ9nxP0p5Th9iFSIpKo+SD8KISxXRg== + dependencies: + loader-fs-cache "^1.0.0" + loader-utils "^1.0.2" + object-assign "^4.0.1" + object-hash "^1.1.4" + rimraf "^2.6.1" + +eslint-plugin-vue@^6.2.2: + version "6.2.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-6.2.2.tgz#27fecd9a3a24789b0f111ecdd540a9e56198e0fe" + integrity sha512-Nhc+oVAHm0uz/PkJAWscwIT4ijTrK5fqNqz9QB1D35SbbuMG1uB6Yr5AJpvPSWg+WOw7nYNswerYh0kOk64gqQ== + dependencies: + natural-compare "^1.4.0" + semver "^5.6.0" + vue-eslint-parser "^7.0.0" + +eslint-scope@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" + integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-scope@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.0.tgz#d0f971dfe59c69e0cada684b23d49dbf82600ce5" + integrity sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-utils@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" + integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== + dependencies: + eslint-visitor-keys "^1.1.0" + +eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" + integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + +eslint@^6.7.2: + version "6.8.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" + integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig== + dependencies: + "@babel/code-frame" "^7.0.0" + ajv "^6.10.0" + chalk "^2.1.0" + cross-spawn "^6.0.5" + debug "^4.0.1" + doctrine "^3.0.0" + eslint-scope "^5.0.0" + eslint-utils "^1.4.3" + eslint-visitor-keys "^1.1.0" + espree "^6.1.2" + esquery "^1.0.1" + esutils "^2.0.2" + file-entry-cache "^5.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^5.0.0" + globals "^12.1.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + inquirer "^7.0.0" + is-glob "^4.0.0" + js-yaml "^3.13.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.14" + minimatch "^3.0.4" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.3" + progress "^2.0.0" + regexpp "^2.0.1" + semver "^6.1.2" + strip-ansi "^5.2.0" + strip-json-comments "^3.0.1" + table "^5.2.3" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + +espree@^6.1.2, espree@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" + integrity sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw== + dependencies: + acorn "^7.1.1" + acorn-jsx "^5.2.0" + eslint-visitor-keys "^1.1.0" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.0.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.3.1.tgz#b78b5828aa8e214e29fb74c4d5b752e1c033da57" + integrity sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + dependencies: + estraverse "^4.1.0" + +estraverse@^4.1.0, estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" + integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +event-pubsub@4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/event-pubsub/-/event-pubsub-4.3.0.tgz#f68d816bc29f1ec02c539dc58c8dd40ce72cb36e" + integrity sha512-z7IyloorXvKbFx9Bpie2+vMJKKx1fH1EN5yiTfp8CiLOTptSYy1g8H4yDpGlEdshL1PBiFtBHepF2cNsqeEeFQ== + +eventemitter3@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384" + integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ== + +events@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz#93b87c18f8efcd4202a461aec4dfc0556b639379" + integrity sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg== + +eventsource@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.0.7.tgz#8fbc72c93fcd34088090bc0a4e64f4b5cee6d8d0" + integrity sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ== + dependencies: + original "^1.0.0" + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +execa@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.8.0.tgz#d8d76bbc1b55217ed190fd6dd49d3c774ecfc8da" + integrity sha1-2NdrvBtVIX7RkP1t1J08d07PyNo= + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^3.3.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-3.4.0.tgz#c08ed4550ef65d858fac269ffc8572446f37eb89" + integrity sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g== + dependencies: + cross-spawn "^7.0.0" + get-stream "^5.0.0" + human-signals "^1.1.1" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.0" + onetime "^5.1.0" + p-finally "^2.0.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +express@^4.16.3, express@^4.17.1: + version "4.17.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" + integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== + dependencies: + accepts "~1.3.7" + array-flatten "1.1.1" + body-parser "1.19.0" + content-disposition "0.5.3" + content-type "~1.0.4" + cookie "0.4.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.5" + qs "6.7.0" + range-parser "~1.2.1" + safe-buffer "5.1.2" + send "0.17.1" + serve-static "1.14.1" + setprototypeof "1.1.1" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +external-editor@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + +fast-deep-equal@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^2.2.6: + version "2.2.7" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d" + integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw== + dependencies: + "@mrmlnc/readdir-enhanced" "^2.2.1" + "@nodelib/fs.stat" "^1.1.2" + glob-parent "^3.1.0" + is-glob "^4.0.0" + merge2 "^1.2.3" + micromatch "^3.1.10" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +faye-websocket@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" + integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ= + dependencies: + websocket-driver ">=0.5.1" + +faye-websocket@~0.11.1: + version "0.11.3" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e" + integrity sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA== + dependencies: + websocket-driver ">=0.5.1" + +figgy-pudding@^3.5.1: + version "3.5.2" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" + integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== + +figures@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" + integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" + integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== + dependencies: + flat-cache "^2.0.1" + +file-loader@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-4.3.0.tgz#780f040f729b3d18019f20605f723e844b8a58af" + integrity sha512-aKrYPYjF1yG3oX0kWRrqrSMfgftm7oJW5M+m4owoldH5C51C0RkIwB++JbRvEW3IU6/ZG5n8UvEcdgwOt2UOWA== + dependencies: + loader-utils "^1.2.3" + schema-utils "^2.5.0" + +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + +filesize@^3.6.1: + version "3.6.1" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317" + integrity sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg== + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +find-cache-dir@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" + integrity sha1-yN765XyKUqinhPnjHFfHQumToLk= + dependencies: + commondir "^1.0.1" + mkdirp "^0.5.1" + pkg-dir "^1.0.0" + +find-cache-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" + integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== + dependencies: + commondir "^1.0.1" + make-dir "^2.0.0" + pkg-dir "^3.0.0" + +find-cache-dir@^3.0.0, find-cache-dir@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" + integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ== + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +flat-cache@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" + integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== + dependencies: + flatted "^2.0.0" + rimraf "2.6.3" + write "1.0.3" + +flatted@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" + integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== + +flush-write-stream@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" + integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== + dependencies: + inherits "^2.0.3" + readable-stream "^2.3.6" + +follow-redirects@1.5.10: + version "1.5.10" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" + integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== + dependencies: + debug "=3.1.0" + +follow-redirects@^1.0.0: + version "1.12.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.12.1.tgz#de54a6205311b93d60398ebc01cf7015682312b6" + integrity sha512-tmRv0AVuR7ZyouUHLeNSiO6pqulF7dYa3s19c6t+wz9LD69/uSzdMxJ2S91nTI9U3rt/IldxpzMOFejp6f0hjg== + +for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +from2@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-extra@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-minipass@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@^1.2.7: + version "1.2.13" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" + integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== + dependencies: + bindings "^1.5.0" + nan "^2.12.1" + +fsevents@~2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" + integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +gensync@^1.0.0-beta.1: + version "1.0.0-beta.1" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" + integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== + +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= + +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-stream@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9" + integrity sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw== + dependencies: + pump "^3.0.0" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-parent@^5.0.0, glob-parent@~5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" + integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== + dependencies: + is-glob "^4.0.1" + +glob-to-regexp@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" + integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= + +glob@^7.0.3, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globals@^12.1.0: + version "12.4.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" + integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== + dependencies: + type-fest "^0.8.1" + +globby@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +globby@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/globby/-/globby-7.1.1.tgz#fb2ccff9401f8600945dfada97440cca972b8680" + integrity sha1-+yzP+UAfhgCUXfral0QMypcrhoA= + dependencies: + array-union "^1.0.1" + dir-glob "^2.0.0" + glob "^7.1.2" + ignore "^3.3.5" + pify "^3.0.0" + slash "^1.0.0" + +globby@^9.2.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-9.2.0.tgz#fd029a706c703d29bdd170f4b6db3a3f7a7cb63d" + integrity sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg== + dependencies: + "@types/glob" "^7.1.1" + array-union "^1.0.2" + dir-glob "^2.2.2" + fast-glob "^2.2.6" + glob "^7.1.3" + ignore "^4.0.3" + pify "^4.0.1" + slash "^2.0.0" + +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.2: + version "4.2.4" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" + integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== + +gzip-size@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274" + integrity sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA== + dependencies: + duplexer "^0.1.1" + pify "^4.0.1" + +handle-thing@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" + integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.3: + version "5.1.5" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== + dependencies: + ajv "^6.12.3" + har-schema "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.0, has-symbols@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" + integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.0, has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hash-base@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== + dependencies: + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +hash-sum@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-1.0.2.tgz#33b40777754c6432573c120cc3808bbd10d47f04" + integrity sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ= + +hash-sum@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-2.0.0.tgz#81d01bb5de8ea4a214ad5d6ead1b523460b0b45a" + integrity sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg== + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +he@1.2.x, he@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +hex-color-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" + integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== + +highlight.js@^9.6.0: + version "9.18.3" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.18.3.tgz#a1a0a2028d5e3149e2380f8a865ee8516703d634" + integrity sha512-zBZAmhSupHIl5sITeMqIJnYCDfAEc3Gdkqj65wC1lpI468MMQeeQkhcIAvk+RylAkxrCcI9xy9piHiXeQ1BdzQ== + +hmac-drbg@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +hoopy@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d" + integrity sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ== + +hosted-git-info@^2.1.4: + version "2.8.8" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" + integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +hsl-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/hsl-regex/-/hsl-regex-1.0.0.tgz#d49330c789ed819e276a4c0d272dffa30b18fe6e" + integrity sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4= + +hsla-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/hsla-regex/-/hsla-regex-1.0.0.tgz#c1ce7a3168c8c6614033a4b5f7877f3b225f9c38" + integrity sha1-wc56MWjIxmFAM6S194d/OyJfnDg= + +html-comment-regex@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" + integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ== + +html-entities@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.3.1.tgz#fb9a1a4b5b14c5daba82d3e34c6ae4fe701a0e44" + integrity sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA== + +html-minifier@^3.2.3: + version "3.5.21" + resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.21.tgz#d0040e054730e354db008463593194015212d20c" + integrity sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA== + dependencies: + camel-case "3.0.x" + clean-css "4.2.x" + commander "2.17.x" + he "1.2.x" + param-case "2.1.x" + relateurl "0.2.x" + uglify-js "3.4.x" + +html-tags@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-2.0.0.tgz#10b30a386085f43cede353cc8fa7cb0deeea668b" + integrity sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos= + +html-webpack-plugin@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz#b01abbd723acaaa7b37b6af4492ebda03d9dd37b" + integrity sha1-sBq71yOsqqeze2r0SS69oD2d03s= + dependencies: + html-minifier "^3.2.3" + loader-utils "^0.2.16" + lodash "^4.17.3" + pretty-error "^2.0.2" + tapable "^1.0.0" + toposort "^1.0.0" + util.promisify "1.0.0" + +htmlparser2@^3.3.0: + version "3.10.1" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" + integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== + dependencies: + domelementtype "^1.3.1" + domhandler "^2.3.0" + domutils "^1.5.1" + entities "^1.1.1" + inherits "^2.0.1" + readable-stream "^3.1.1" + +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= + +http-errors@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" + integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-errors@~1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-parser-js@>=0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.2.tgz#da2e31d237b393aae72ace43882dd7e270a8ff77" + integrity sha512-opCO9ASqg5Wy2FNo7A0sxy71yGbbkJJXLdgMK04Tcypw9jr2MgWbyubb0+WdmDmGnFflO7fRbqbaihh/ENDlRQ== + +http-proxy-middleware@0.19.1: + version "0.19.1" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a" + integrity sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q== + dependencies: + http-proxy "^1.17.0" + is-glob "^4.0.0" + lodash "^4.17.11" + micromatch "^3.1.10" + +http-proxy@^1.17.0: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= + +human-signals@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" + integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== + +iconv-lite@0.4.24, iconv-lite@^0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +icss-utils@^4.0.0, icss-utils@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" + integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA== + dependencies: + postcss "^7.0.14" + +ieee754@^1.1.4: + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= + +ignore@^3.3.5: + version "3.3.10" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" + integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== + +ignore@^4.0.3, ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +import-cwd@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" + integrity sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk= + dependencies: + import-from "^2.1.0" + +import-fresh@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" + integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= + dependencies: + caller-path "^2.0.0" + resolve-from "^3.0.0" + +import-fresh@^3.0.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" + integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-from@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" + integrity sha1-M1238qev/VOqpHHUuAId7ja387E= + dependencies: + resolve-from "^3.0.0" + +import-local@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" + integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== + dependencies: + pkg-dir "^3.0.0" + resolve-cwd "^2.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +indexes-of@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" + integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= + +infer-owner@^1.0.3, infer-owner@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +inquirer@^7.0.0, inquirer@^7.1.0: + version "7.3.3" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003" + integrity sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA== + dependencies: + ansi-escapes "^4.2.1" + chalk "^4.1.0" + cli-cursor "^3.1.0" + cli-width "^3.0.0" + external-editor "^3.0.3" + figures "^3.0.0" + lodash "^4.17.19" + mute-stream "0.0.8" + run-async "^2.4.0" + rxjs "^6.6.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + through "^2.3.6" + +internal-ip@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907" + integrity sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg== + dependencies: + default-gateway "^4.2.0" + ipaddr.js "^1.9.0" + +invariant@^2.2.2, invariant@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +ip-regex@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" + integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= + +ip@^1.1.0, ip@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= + +ipaddr.js@1.9.1, ipaddr.js@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-absolute-url@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" + integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY= + +is-absolute-url@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" + integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q== + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-arguments@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" + integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + dependencies: + binary-extensions "^1.0.0" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-callable@^1.1.4, is-callable@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb" + integrity sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw== + +is-ci@^1.0.10: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" + integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== + dependencies: + ci-info "^1.5.0" + +is-color-stop@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-color-stop/-/is-color-stop-1.1.0.tgz#cfff471aee4dd5c9e158598fbe12967b5cdad345" + integrity sha1-z/9HGu5N1cnhWFmPvhKWe1za00U= + dependencies: + css-color-names "^0.0.4" + hex-color-regex "^1.1.0" + hsl-regex "^1.0.0" + hsla-regex "^1.0.0" + rgb-regex "^1.0.1" + rgba-regex "^1.0.0" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" + integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= + +is-docker@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.1.1.tgz#4125a88e44e450d384e09047ede71adc2d144156" + integrity sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw== + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" + integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== + +is-path-cwd@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" + integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== + +is-path-in-cwd@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz#bfe2dca26c69f397265a4009963602935a053acb" + integrity sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ== + dependencies: + is-path-inside "^2.1.0" + +is-path-inside@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2" + integrity sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg== + dependencies: + path-is-inside "^1.0.2" + +is-plain-obj@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= + +is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-regex@^1.0.4, is-regex@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.1.tgz#c6f98aacc546f6cec5468a07b7b153ab564a57b9" + integrity sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg== + dependencies: + has-symbols "^1.0.1" + +is-resolvable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" + integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== + +is-svg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75" + integrity sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ== + dependencies: + html-comment-regex "^1.1.0" + +is-symbol@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" + integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== + dependencies: + has-symbols "^1.0.1" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= + +is-wsl@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +javascript-stringify@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/javascript-stringify/-/javascript-stringify-2.0.1.tgz#6ef358035310e35d667c675ed63d3eb7c1aa19e5" + integrity sha512-yV+gqbd5vaOYjqlbk16EG89xB5udgjqQF3C5FAORDg4f/IS1Yc5ERCv5e/57yBcfJYw05V5JyIXabhwb75Xxow== + +jest-worker@^25.4.0: + version "25.5.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-25.5.0.tgz#2611d071b79cea0f43ee57a3d118593ac1547db1" + integrity sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw== + dependencies: + merge-stream "^2.0.0" + supports-color "^7.0.0" + +js-message@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/js-message/-/js-message-1.0.5.tgz#2300d24b1af08e89dd095bc1a4c9c9cfcb892d15" + integrity sha1-IwDSSxrwjondCVvBpMnJz8uJLRU= + +js-queue@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/js-queue/-/js-queue-2.0.0.tgz#362213cf860f468f0125fc6c96abc1742531f948" + integrity sha1-NiITz4YPRo8BJfxslqvBdCUx+Ug= + dependencies: + easy-stack "^1.0.0" + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" + integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + +json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +json3@^3.3.2: + version "3.3.3" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" + integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA== + +json5@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + +json5@^2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" + integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== + dependencies: + minimist "^1.2.5" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +killable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" + integrity sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg== + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +launch-editor-middleware@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/launch-editor-middleware/-/launch-editor-middleware-2.2.1.tgz#e14b07e6c7154b0a4b86a0fd345784e45804c157" + integrity sha512-s0UO2/gEGiCgei3/2UN3SMuUj1phjQN8lcpnvgLSz26fAzNWPQ6Nf/kF5IFClnfU2ehp6LrmKdMU/beveO+2jg== + dependencies: + launch-editor "^2.2.1" + +launch-editor@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.2.1.tgz#871b5a3ee39d6680fcc26d37930b6eeda89db0ca" + integrity sha512-On+V7K2uZK6wK7x691ycSUbLD/FyKKelArkbaAMSSJU8JmqmhwN2+mnJDNINuJWSrh2L0kDk+ZQtbC/gOWUwLw== + dependencies: + chalk "^2.3.0" + shell-quote "^1.6.1" + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +levenary@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/levenary/-/levenary-1.1.1.tgz#842a9ee98d2075aa7faeedbe32679e9205f46f77" + integrity sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ== + dependencies: + leven "^3.1.0" + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +lines-and-columns@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" + integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= + +loader-fs-cache@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/loader-fs-cache/-/loader-fs-cache-1.0.3.tgz#f08657646d607078be2f0a032f8bd69dd6f277d9" + integrity sha512-ldcgZpjNJj71n+2Mf6yetz+c9bM4xpKtNds4LbqXzU/PTdeAX0g3ytnU1AJMEcTk2Lex4Smpe3Q/eCTsvUBxbA== + dependencies: + find-cache-dir "^0.1.1" + mkdirp "^0.5.1" + +loader-runner@^2.3.1, loader-runner@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" + integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== + +loader-utils@^0.2.16: + version "0.2.17" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" + integrity sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g= + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + object-assign "^4.0.1" + +loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" + integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^1.0.1" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash-es@^4.17.15: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.15.tgz#21bd96839354412f23d7a10340e5eac6ee455d78" + integrity sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ== + +lodash.defaultsdeep@^4.6.1: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6" + integrity sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA== + +lodash.kebabcase@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36" + integrity sha1-hImxyw0p/4gZXM7KRI/21swpXDY= + +lodash.mapvalues@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz#1bafa5005de9dd6f4f26668c30ca37230cc9689c" + integrity sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw= + +lodash.memoize@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= + +lodash.transform@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.transform/-/lodash.transform-4.6.0.tgz#12306422f63324aed8483d3f38332b5f670547a0" + integrity sha1-EjBkIvYzJK7YSD0/ODMrX2cFR6A= + +lodash.uniq@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= + +lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.3: + version "4.17.19" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" + integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== + +log-symbols@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" + integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== + dependencies: + chalk "^2.0.1" + +loglevel@^1.6.8: + version "1.6.8" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.8.tgz#8a25fb75d092230ecd4457270d80b54e28011171" + integrity sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA== + +loose-envify@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lower-case@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" + integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw= + +lru-cache@^4.0.1, lru-cache@^4.1.2: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +make-dir@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + +make-dir@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +mdn-data@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" + integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA== + +mdn-data@2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.6.tgz#852dc60fcaa5daa2e8cf6c9189c440ed3e042978" + integrity sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA== + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +memory-fs@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +memory-fs@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" + integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +merge-source-map@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" + integrity sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw== + dependencies: + source-map "^0.6.1" + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.2.3: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@1.44.0, "mime-db@>= 1.43.0 < 2": + version "1.44.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" + integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== + +mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: + version "2.1.27" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" + integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== + dependencies: + mime-db "1.44.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mime@^2.4.4: + version "2.4.6" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.6.tgz#e5b407c90db442f2beb5b162373d07b69affa4d1" + integrity sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA== + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mini-css-extract-plugin@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz#47f2cf07aa165ab35733b1fc97d4c46c0564339e" + integrity sha512-lp3GeY7ygcgAmVIcRPBVhIkf8Us7FZjA+ILpal44qLdSu11wmjKQ3d9k15lfD7pO4esu9eUIAW7qiYIBppv40A== + dependencies: + loader-utils "^1.1.0" + normalize-url "1.9.1" + schema-utils "^1.0.0" + webpack-sources "^1.1.0" + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +minipass-collect@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" + integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== + dependencies: + minipass "^3.0.0" + +minipass-flush@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" + integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== + dependencies: + minipass "^3.0.0" + +minipass-pipeline@^1.2.2: + version "1.2.4" + resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" + integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== + dependencies: + minipass "^3.0.0" + +minipass@^3.0.0, minipass@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" + integrity sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg== + dependencies: + yallist "^4.0.0" + +mississippi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^3.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@~0.5.1: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +multicast-dns-service-types@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" + integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= + +multicast-dns@^6.0.1: + version "6.2.3" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" + integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== + dependencies: + dns-packet "^1.3.1" + thunky "^1.0.2" + +mute-stream@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + +mz@^2.4.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + +nan@^2.12.1: + version "2.14.1" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" + integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + +neo-async@^2.5.0, neo-async@^2.6.0, neo-async@^2.6.1: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +no-case@^2.2.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" + integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ== + dependencies: + lower-case "^1.1.1" + +node-forge@0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579" + integrity sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ== + +node-ipc@^9.1.1: + version "9.1.1" + resolved "https://registry.yarnpkg.com/node-ipc/-/node-ipc-9.1.1.tgz#4e245ed6938e65100e595ebc5dc34b16e8dd5d69" + integrity sha512-FAyICv0sIRJxVp3GW5fzgaf9jwwRQxAKDJlmNFUL5hOy+W4X/I5AypyHoq0DXXbo9o/gt79gj++4cMr4jVWE/w== + dependencies: + event-pubsub "4.3.0" + js-message "1.0.5" + js-queue "2.0.0" + +node-libs-browser@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" + integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== + dependencies: + assert "^1.1.1" + browserify-zlib "^0.2.0" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^3.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.1" + process "^0.11.10" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.11.0" + vm-browserify "^1.0.1" + +node-releases@^1.1.60: + version "1.1.60" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.60.tgz#6948bdfce8286f0b5d0e5a88e8384e954dfe7084" + integrity sha512-gsO4vjEdQaTusZAEebUWp2a5d7dF5DYoIpDG7WySnk7BuZDW+GPpHXoXXuYawRBr/9t5q54tirPz79kFIWg4dA== + +normalize-package-data@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-1.0.0.tgz#32d0e472f91ff345701c15a8311018d3b0a90379" + integrity sha1-MtDkcvkf80VwHBWoMRAY07CpA3k= + +normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= + +normalize-url@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c" + integrity sha1-LMDWazHqIwNkWENuNiDYWVTGbDw= + dependencies: + object-assign "^4.0.1" + prepend-http "^1.0.0" + query-string "^4.1.0" + sort-keys "^1.0.0" + +normalize-url@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" + integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +npm-run-path@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +nth-check@^1.0.2, nth-check@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" + integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== + dependencies: + boolbase "~1.0.0" + +num2fraction@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" + integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-hash@^1.1.4: + version "1.3.1" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df" + integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA== + +object-inspect@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0" + integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA== + +object-is@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.2.tgz#c5d2e87ff9e119f78b7a088441519e2eec1573b6" + integrity sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.assign@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649" + integrity sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +object.values@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e" + integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + function-bind "^1.1.1" + has "^1.0.3" + +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= + dependencies: + mimic-fn "^1.0.0" + +onetime@^5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.1.tgz#5c8016847b0d67fcedb7eef254751cfcdc7e9418" + integrity sha512-ZpZpjcJeugQfWsfyQlshVoowIIQ1qBGSVll4rfDq6JJVO//fesjoX808hXWfBjY+ROZgpKDI5TRSRBSoJiZ8eg== + dependencies: + mimic-fn "^2.1.0" + +open@^6.3.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/open/-/open-6.4.0.tgz#5c13e96d0dc894686164f18965ecfe889ecfc8a9" + integrity sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg== + dependencies: + is-wsl "^1.1.0" + +opener@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed" + integrity sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA== + +opn@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc" + integrity sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA== + dependencies: + is-wsl "^1.1.0" + +optionator@^0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + +ora@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/ora/-/ora-3.4.0.tgz#bf0752491059a3ef3ed4c85097531de9fdbcd318" + integrity sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg== + dependencies: + chalk "^2.4.2" + cli-cursor "^2.1.0" + cli-spinners "^2.0.0" + log-symbols "^2.2.0" + strip-ansi "^5.2.0" + wcwidth "^1.0.1" + +original@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" + integrity sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg== + dependencies: + url-parse "^1.4.3" + +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= + +os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-finally@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561" + integrity sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw== + +p-limit@^2.0.0, p-limit@^2.2.0, p-limit@^2.2.1, p-limit@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-map@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" + integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== + +p-map@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-3.0.0.tgz#d704d9af8a2ba684e2600d9a215983d4141a979d" + integrity sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ== + dependencies: + aggregate-error "^3.0.0" + +p-retry@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-3.0.1.tgz#316b4c8893e2c8dc1cfa891f406c4b422bebf328" + integrity sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w== + dependencies: + retry "^0.12.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +pako@~1.0.5: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + +parallel-transform@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" + integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== + dependencies: + cyclist "^1.0.1" + inherits "^2.0.3" + readable-stream "^2.1.5" + +param-case@2.1.x: + version "2.1.1" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" + integrity sha1-35T9jPZTHs915r75oIWPvHK+Ikc= + dependencies: + no-case "^2.2.0" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-asn1@^5.0.0, parse-asn1@^5.1.5: + version "5.1.5" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e" + integrity sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ== + dependencies: + asn1.js "^4.0.0" + browserify-aes "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +parse-json@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.0.1.tgz#7cfe35c1ccd641bce3981467e6c2ece61b3b3878" + integrity sha512-ztoZ4/DYeXQq4E21v169sC8qWINGpcosGv9XhTDvg9/hWvx/zrFkc9BiWxR58OJLHGk28j5BL0SDLeV2WmFZlQ== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + lines-and-columns "^1.1.6" + +parse5-htmlparser2-tree-adapter@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-5.1.1.tgz#e8c743d4e92194d5293ecde2b08be31e67461cbc" + integrity sha512-CF+TKjXqoqyDwHqBhFQ+3l5t83xYi6fVT1tQNg+Ye0JRLnTxWvIroCjEp1A0k4lneHNBGnICUf0cfYVYGEazqw== + dependencies: + parse5 "^5.1.1" + +parse5@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" + integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== + +parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" + integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== + dependencies: + pify "^3.0.0" + +pbkdf2@^3.0.3: + version "3.1.1" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94" + integrity sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +picomatch@^2.0.4, picomatch@^2.2.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +pkg-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + integrity sha1-ektQio1bstYp1EcFb/TpyTFM89Q= + dependencies: + find-up "^1.0.0" + +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + +pkg-dir@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +pnp-webpack-plugin@^1.6.4: + version "1.6.4" + resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149" + integrity sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg== + dependencies: + ts-pnp "^1.1.6" + +portfinder@^1.0.26: + version "1.0.28" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778" + integrity sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA== + dependencies: + async "^2.6.2" + debug "^3.1.1" + mkdirp "^0.5.5" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +postcss-calc@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.3.tgz#d65cca92a3c52bf27ad37a5f732e0587b74f1623" + integrity sha512-IB/EAEmZhIMEIhG7Ov4x+l47UaXOS1n2f4FBUk/aKllQhtSCxWhTzn0nJgkqN7fo/jcWySvWTSB6Syk9L+31bA== + dependencies: + postcss "^7.0.27" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.0.2" + +postcss-colormin@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-4.0.3.tgz#ae060bce93ed794ac71264f08132d550956bd381" + integrity sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw== + dependencies: + browserslist "^4.0.0" + color "^3.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-convert-values@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz#ca3813ed4da0f812f9d43703584e449ebe189a7f" + integrity sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ== + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-discard-comments@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz#1fbabd2c246bff6aaad7997b2b0918f4d7af4033" + integrity sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg== + dependencies: + postcss "^7.0.0" + +postcss-discard-duplicates@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz#3fe133cd3c82282e550fc9b239176a9207b784eb" + integrity sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ== + dependencies: + postcss "^7.0.0" + +postcss-discard-empty@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz#c8c951e9f73ed9428019458444a02ad90bb9f765" + integrity sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w== + dependencies: + postcss "^7.0.0" + +postcss-discard-overridden@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz#652aef8a96726f029f5e3e00146ee7a4e755ff57" + integrity sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg== + dependencies: + postcss "^7.0.0" + +postcss-load-config@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-2.1.0.tgz#c84d692b7bb7b41ddced94ee62e8ab31b417b003" + integrity sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q== + dependencies: + cosmiconfig "^5.0.0" + import-cwd "^2.0.0" + +postcss-loader@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-3.0.0.tgz#6b97943e47c72d845fa9e03f273773d4e8dd6c2d" + integrity sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA== + dependencies: + loader-utils "^1.1.0" + postcss "^7.0.0" + postcss-load-config "^2.0.0" + schema-utils "^1.0.0" + +postcss-merge-longhand@^4.0.11: + version "4.0.11" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz#62f49a13e4a0ee04e7b98f42bb16062ca2549e24" + integrity sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw== + dependencies: + css-color-names "0.0.4" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + stylehacks "^4.0.0" + +postcss-merge-rules@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz#362bea4ff5a1f98e4075a713c6cb25aefef9a650" + integrity sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ== + dependencies: + browserslist "^4.0.0" + caniuse-api "^3.0.0" + cssnano-util-same-parent "^4.0.0" + postcss "^7.0.0" + postcss-selector-parser "^3.0.0" + vendors "^1.0.0" + +postcss-minify-font-values@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz#cd4c344cce474343fac5d82206ab2cbcb8afd5a6" + integrity sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg== + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-minify-gradients@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz#93b29c2ff5099c535eecda56c4aa6e665a663471" + integrity sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q== + dependencies: + cssnano-util-get-arguments "^4.0.0" + is-color-stop "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-minify-params@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz#6b9cef030c11e35261f95f618c90036d680db874" + integrity sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg== + dependencies: + alphanum-sort "^1.0.0" + browserslist "^4.0.0" + cssnano-util-get-arguments "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + uniqs "^2.0.0" + +postcss-minify-selectors@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz#e2e5eb40bfee500d0cd9243500f5f8ea4262fbd8" + integrity sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g== + dependencies: + alphanum-sort "^1.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-selector-parser "^3.0.0" + +postcss-modules-extract-imports@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" + integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ== + dependencies: + postcss "^7.0.5" + +postcss-modules-local-by-default@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz#bb14e0cc78279d504dbdcbfd7e0ca28993ffbbb0" + integrity sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw== + dependencies: + icss-utils "^4.1.1" + postcss "^7.0.32" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + +postcss-modules-scope@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz#385cae013cc7743f5a7d7602d1073a89eaae62ee" + integrity sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ== + dependencies: + postcss "^7.0.6" + postcss-selector-parser "^6.0.0" + +postcss-modules-values@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz#5b5000d6ebae29b4255301b4a3a54574423e7f10" + integrity sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg== + dependencies: + icss-utils "^4.0.0" + postcss "^7.0.6" + +postcss-normalize-charset@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz#8b35add3aee83a136b0471e0d59be58a50285dd4" + integrity sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g== + dependencies: + postcss "^7.0.0" + +postcss-normalize-display-values@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz#0dbe04a4ce9063d4667ed2be476bb830c825935a" + integrity sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ== + dependencies: + cssnano-util-get-match "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-positions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz#05f757f84f260437378368a91f8932d4b102917f" + integrity sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA== + dependencies: + cssnano-util-get-arguments "^4.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-repeat-style@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz#c4ebbc289f3991a028d44751cbdd11918b17910c" + integrity sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q== + dependencies: + cssnano-util-get-arguments "^4.0.0" + cssnano-util-get-match "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-string@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz#cd44c40ab07a0c7a36dc5e99aace1eca4ec2690c" + integrity sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA== + dependencies: + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-timing-functions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz#8e009ca2a3949cdaf8ad23e6b6ab99cb5e7d28d9" + integrity sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A== + dependencies: + cssnano-util-get-match "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-unicode@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz#841bd48fdcf3019ad4baa7493a3d363b52ae1cfb" + integrity sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg== + dependencies: + browserslist "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-url@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz#10e437f86bc7c7e58f7b9652ed878daaa95faae1" + integrity sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA== + dependencies: + is-absolute-url "^2.0.0" + normalize-url "^3.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-whitespace@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz#bf1d4070fe4fcea87d1348e825d8cc0c5faa7d82" + integrity sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA== + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-ordered-values@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz#0cf75c820ec7d5c4d280189559e0b571ebac0eee" + integrity sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw== + dependencies: + cssnano-util-get-arguments "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-reduce-initial@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz#7fd42ebea5e9c814609639e2c2e84ae270ba48df" + integrity sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA== + dependencies: + browserslist "^4.0.0" + caniuse-api "^3.0.0" + has "^1.0.0" + postcss "^7.0.0" + +postcss-reduce-transforms@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz#17efa405eacc6e07be3414a5ca2d1074681d4e29" + integrity sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg== + dependencies: + cssnano-util-get-match "^4.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-selector-parser@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz#b310f5c4c0fdaf76f94902bbaa30db6aa84f5270" + integrity sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA== + dependencies: + dot-prop "^5.2.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz#934cf799d016c83411859e09dcecade01286ec5c" + integrity sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg== + dependencies: + cssesc "^3.0.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-svgo@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-4.0.2.tgz#17b997bc711b333bab143aaed3b8d3d6e3d38258" + integrity sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw== + dependencies: + is-svg "^3.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + svgo "^1.0.0" + +postcss-unique-selectors@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz#9446911f3289bfd64c6d680f073c03b1f9ee4bac" + integrity sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg== + dependencies: + alphanum-sort "^1.0.0" + postcss "^7.0.0" + uniqs "^2.0.0" + +postcss-value-parser@^3.0.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" + integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== + +postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" + integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== + +postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.27, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6: + version "7.0.32" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.32.tgz#4310d6ee347053da3433db2be492883d62cec59d" + integrity sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw== + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +prepend-http@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= + +prettier@^1.18.2: + version "1.19.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" + integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== + +pretty-error@^2.0.2: + version "2.1.1" + resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3" + integrity sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM= + dependencies: + renderkid "^2.0.1" + utila "~0.4" + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= + +proxy-addr@~2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" + integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.9.1" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= + +psl@^1.1.28: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + +punycode@^1.2.4: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +q@^1.1.2: + version "1.5.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" + integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= + +qs@6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" + integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== + +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +query-string@^4.1.0: + version "4.3.4" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" + integrity sha1-u7aTucqRXCMlFbIosaArYJBD2+s= + dependencies: + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + +querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +querystringify@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e" + integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA== + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" + integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== + dependencies: + bytes "3.1.0" + http-errors "1.7.2" + iconv-lite "0.4.24" + unpipe "1.0.0" + +read-pkg@^5.1.1: + version "5.2.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" + integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== + dependencies: + "@types/normalize-package-data" "^2.4.0" + normalize-package-data "^2.5.0" + parse-json "^5.0.0" + type-fest "^0.6.0" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +readdirp@~3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.4.0.tgz#9fdccdf9e9155805449221ac645e8303ab5b9ada" + integrity sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ== + dependencies: + picomatch "^2.2.1" + +regenerate-unicode-properties@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" + integrity sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA== + dependencies: + regenerate "^1.4.0" + +regenerate@^1.4.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.1.tgz#cad92ad8e6b591773485fbe05a485caf4f457e6f" + integrity sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A== + +regenerator-runtime@^0.13.4: + version "0.13.7" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" + integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== + +regenerator-transform@^0.14.2: + version "0.14.5" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4" + integrity sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw== + dependencies: + "@babel/runtime" "^7.8.4" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexp.prototype.flags@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75" + integrity sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + +regexpp@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== + +regexpu-core@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.0.tgz#fcbf458c50431b0bb7b45d6967b8192d91f3d938" + integrity sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ== + dependencies: + regenerate "^1.4.0" + regenerate-unicode-properties "^8.2.0" + regjsgen "^0.5.1" + regjsparser "^0.6.4" + unicode-match-property-ecmascript "^1.0.4" + unicode-match-property-value-ecmascript "^1.2.0" + +regjsgen@^0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" + integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== + +regjsparser@^0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.4.tgz#a769f8684308401a66e9b529d2436ff4d0666272" + integrity sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw== + dependencies: + jsesc "~0.5.0" + +relateurl@0.2.x: + version "0.2.7" + resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" + integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +renderkid@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.3.tgz#380179c2ff5ae1365c522bf2fcfcff01c5b74149" + integrity sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA== + dependencies: + css-select "^1.1.0" + dom-converter "^0.2" + htmlparser2 "^3.3.0" + strip-ansi "^3.0.0" + utila "^0.4.0" + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +request@^2.88.2: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= + dependencies: + resolve-from "^3.0.0" + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + integrity sha1-six699nWiBvItuZTM17rywoYh0g= + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@^1.10.0, resolve@^1.12.0, resolve@^1.3.2, resolve@^1.8.1: + version "1.17.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" + integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== + dependencies: + path-parse "^1.0.6" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= + +rgb-regex@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/rgb-regex/-/rgb-regex-1.0.1.tgz#c0e0d6882df0e23be254a475e8edd41915feaeb1" + integrity sha1-wODWiC3w4jviVKR16O3UGRX+rrE= + +rgba-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" + integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= + +rimraf@2.6.3: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + +rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3, rimraf@^2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +run-async@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" + integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== + +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= + dependencies: + aproba "^1.1.1" + +rxjs@^6.6.0: + version "6.6.2" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.2.tgz#8096a7ac03f2cc4fe5860ef6e572810d9e01c0d2" + integrity sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg== + dependencies: + tslib "^1.9.0" + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sax@~1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +schema-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" + integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== + dependencies: + ajv "^6.1.0" + ajv-errors "^1.0.0" + ajv-keywords "^3.1.0" + +schema-utils@^2.0.0, schema-utils@^2.5.0, schema-utils@^2.6.5, schema-utils@^2.6.6, schema-utils@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" + integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== + dependencies: + "@types/json-schema" "^7.0.4" + ajv "^6.12.2" + ajv-keywords "^3.4.1" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= + +selfsigned@^1.10.7: + version "1.10.7" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.7.tgz#da5819fd049d5574f28e88a9bcc6dbc6e6f3906b" + integrity sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA== + dependencies: + node-forge "0.9.0" + +"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== + +semver@^6.0.0, semver@^6.1.0, semver@^6.1.2, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +send@0.17.1: + version "0.17.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" + integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.7.2" + mime "1.6.0" + ms "2.1.1" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +serialize-javascript@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61" + integrity sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ== + +serialize-javascript@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-3.1.0.tgz#8bf3a9170712664ef2561b44b691eafe399214ea" + integrity sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg== + dependencies: + randombytes "^2.1.0" + +serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.14.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" + integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.1" + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +shell-quote@^1.6.1: + version "1.7.2" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" + integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" + integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== + +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= + dependencies: + is-arrayish "^0.3.1" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= + +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== + +slice-ansi@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== + dependencies: + ansi-styles "^3.2.0" + astral-regex "^1.0.0" + is-fullwidth-code-point "^2.0.0" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +sockjs-client@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.4.0.tgz#c9f2568e19c8fd8173b4997ea3420e0bb306c7d5" + integrity sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g== + dependencies: + debug "^3.2.5" + eventsource "^1.0.7" + faye-websocket "~0.11.1" + inherits "^2.0.3" + json3 "^3.3.2" + url-parse "^1.4.3" + +sockjs@0.3.20: + version "0.3.20" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.20.tgz#b26a283ec562ef8b2687b44033a4eeceac75d855" + integrity sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA== + dependencies: + faye-websocket "^0.10.0" + uuid "^3.4.0" + websocket-driver "0.6.5" + +sort-keys@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + integrity sha1-RBttTTRnmPG05J6JIK37oOVD+a0= + dependencies: + is-plain-obj "^1.0.0" + +source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + +source-map-resolve@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@~0.5.12: + version "0.5.19" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" + integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + +source-map@^0.5.0, source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@^0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +spdx-correct@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.5" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654" + integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q== + +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" + integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +ssri@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" + integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== + dependencies: + figgy-pudding "^3.5.1" + +ssri@^7.0.0, ssri@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-7.1.0.tgz#92c241bf6de82365b5c7fb4bd76e975522e1294d" + integrity sha512-77/WrDZUWocK0mvA5NTRQyveUf+wsrIc6vyrxpS8tVvYBcX215QbafrJR3KtkpskIzoFLqqNuuYQvxaMjXJ/0g== + dependencies: + figgy-pudding "^3.5.1" + minipass "^3.1.1" + +stable@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" + integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== + +stackframe@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.2.0.tgz#52429492d63c62eb989804c11552e3d22e779303" + integrity sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA== + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +stream-browserify@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" + integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-each@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-http@^2.7.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +stream-shift@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" + integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== + +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= + +string-width@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^3.0.0, string-width@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" + integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + +string.prototype.trimend@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" + integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + +string.prototype.trimstart@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" + integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + +string_decoder@^1.0.0, string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.0" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-indent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" + integrity sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g= + +strip-json-comments@^3.0.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +stylehacks@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5" + integrity sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g== + dependencies: + browserslist "^4.0.0" + postcss "^7.0.0" + postcss-selector-parser "^3.0.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" + integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.0.0, supports-color@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" + integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== + dependencies: + has-flag "^4.0.0" + +svg-tags@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764" + integrity sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q= + +svgo@^1.0.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167" + integrity sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw== + dependencies: + chalk "^2.4.1" + coa "^2.0.2" + css-select "^2.0.0" + css-select-base-adapter "^0.1.1" + css-tree "1.0.0-alpha.37" + csso "^4.0.2" + js-yaml "^3.13.1" + mkdirp "~0.5.1" + object.values "^1.1.0" + sax "~1.2.4" + stable "^0.1.8" + unquote "~1.1.1" + util.promisify "~1.0.0" + +table@^5.2.3: + version "5.4.6" + resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" + integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== + dependencies: + ajv "^6.10.2" + lodash "^4.17.14" + slice-ansi "^2.1.0" + string-width "^3.0.0" + +tapable@^1.0.0, tapable@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== + +terser-webpack-plugin@^1.4.3: + version "1.4.4" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.4.tgz#2c63544347324baafa9a56baaddf1634c8abfc2f" + integrity sha512-U4mACBHIegmfoEe5fdongHESNJWqsGU+W0S/9+BmYGVQDw1+c2Ow05TpMhxjPK1sRb7cuYq1BPl1e5YHJMTCqA== + dependencies: + cacache "^12.0.2" + find-cache-dir "^2.1.0" + is-wsl "^1.1.0" + schema-utils "^1.0.0" + serialize-javascript "^3.1.0" + source-map "^0.6.1" + terser "^4.1.2" + webpack-sources "^1.4.0" + worker-farm "^1.7.0" + +terser-webpack-plugin@^2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-2.3.7.tgz#4910ff5d1a872168cc7fa6cd3749e2b0d60a8a0b" + integrity sha512-xzYyaHUNhzgaAdBsXxk2Yvo/x1NJdslUaussK3fdpBbvttm1iIwU+c26dj9UxJcwk2c5UWt5F55MUTIA8BE7Dg== + dependencies: + cacache "^13.0.1" + find-cache-dir "^3.3.1" + jest-worker "^25.4.0" + p-limit "^2.3.0" + schema-utils "^2.6.6" + serialize-javascript "^3.1.0" + source-map "^0.6.1" + terser "^4.6.12" + webpack-sources "^1.4.3" + +terser@^4.1.2, terser@^4.6.12: + version "4.8.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17" + integrity sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw== + dependencies: + commander "^2.20.0" + source-map "~0.6.1" + source-map-support "~0.5.12" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY= + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.1" + resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" + integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== + dependencies: + any-promise "^1.0.0" + +thread-loader@^2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/thread-loader/-/thread-loader-2.1.3.tgz#cbd2c139fc2b2de6e9d28f62286ab770c1acbdda" + integrity sha512-wNrVKH2Lcf8ZrWxDF/khdlLlsTMczdcwPA9VEK4c2exlEPynYWxi9op3nPTo5lAnDIkE0rQEB3VBP+4Zncc9Hg== + dependencies: + loader-runner "^2.3.1" + loader-utils "^1.1.0" + neo-async "^2.6.0" + +through2@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +thunky@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" + integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== + +timers-browserify@^2.0.4: + version "2.0.11" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f" + integrity sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ== + dependencies: + setimmediate "^1.0.4" + +timsort@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" + integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + +toposort@^1.0.0: + version "1.0.7" + resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.7.tgz#2e68442d9f64ec720b8cc89e6443ac6caa950029" + integrity sha1-LmhELZ9k7HILjMieZEOsbKqVACk= + +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +tryer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" + integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== + +ts-pnp@^1.1.6: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" + integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== + +tslib@^1.9.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" + integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-fest@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" + integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ== + +type-fest@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" + integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== + +type-fest@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" + integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== + +type-is@~1.6.17, type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +uglify-js@3.4.x: + version "3.4.10" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f" + integrity sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw== + dependencies: + commander "~2.19.0" + source-map "~0.6.1" + +unicode-canonical-property-names-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" + integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== + +unicode-match-property-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" + integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== + dependencies: + unicode-canonical-property-names-ecmascript "^1.0.4" + unicode-property-aliases-ecmascript "^1.0.4" + +unicode-match-property-value-ecmascript@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531" + integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ== + +unicode-property-aliases-ecmascript@^1.0.4: + version "1.1.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz#dd57a99f6207bedff4628abefb94c50db941c8f4" + integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg== + +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +uniq@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= + +uniqs@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" + integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI= + +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" + integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== + dependencies: + imurmurhash "^0.1.4" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +unquote@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" + integrity sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ= + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +upath@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + +upper-case@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" + integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg= + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +url-loader@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-2.3.0.tgz#e0e2ef658f003efb8ca41b0f3ffbf76bab88658b" + integrity sha512-goSdg8VY+7nPZKUEChZSEtW5gjbS66USIGCeSJ1OVOJ7Yfuh/36YxCwMi5HVEJh6mqUYOoy3NJ0vlOMrWsSHog== + dependencies: + loader-utils "^1.2.3" + mime "^2.4.4" + schema-utils "^2.5.0" + +url-parse@^1.4.3: + version "1.4.7" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278" + integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util.promisify@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== + dependencies: + define-properties "^1.1.2" + object.getownpropertydescriptors "^2.0.3" + +util.promisify@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" + integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.2" + has-symbols "^1.0.1" + object.getownpropertydescriptors "^2.1.0" + +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= + dependencies: + inherits "2.0.1" + +util@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" + integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== + dependencies: + inherits "2.0.3" + +utila@^0.4.0, utila@~0.4: + version "0.4.0" + resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" + integrity sha1-ihagXURWV6Oupe7MWxKk+lN5dyw= + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@^3.3.2, uuid@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +v8-compile-cache@^2.0.3: + version "2.1.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745" + integrity sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ== + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +vendors@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e" + integrity sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w== + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vm-browserify@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" + integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== + +vue-eslint-parser@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-7.1.0.tgz#9cdbcc823e656b087507a1911732b867ac101e83" + integrity sha512-Kr21uPfthDc63nDl27AGQEhtt9VrZ9nkYk/NTftJ2ws9XiJwzJJCnCr3AITQ2jpRMA0XPGDECxYH8E027qMK9Q== + dependencies: + debug "^4.1.1" + eslint-scope "^5.0.0" + eslint-visitor-keys "^1.1.0" + espree "^6.2.1" + esquery "^1.0.1" + lodash "^4.17.15" + +vue-hot-reload-api@^2.3.0: + version "2.3.4" + resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz#532955cc1eb208a3d990b3a9f9a70574657e08f2" + integrity sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog== + +"vue-loader-v16@npm:vue-loader@^16.0.0-beta.7": + version "16.0.0-beta.7" + resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-16.0.0-beta.7.tgz#6f2726fa0e2b1fbae67895c47593bbf69f2b9ab8" + integrity sha512-xQ8/GZmRPdQ3EinnE0IXwdVoDzh7Dowo0MowoyBuScEBXrRabw6At5/IdtD3waKklKW5PGokPsm8KRN6rvQ1cw== + dependencies: + "@types/mini-css-extract-plugin" "^0.9.1" + chalk "^3.0.0" + hash-sum "^2.0.0" + loader-utils "^1.2.3" + merge-source-map "^1.1.0" + source-map "^0.6.1" + +vue-loader@^15.9.2: + version "15.9.3" + resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.9.3.tgz#0de35d9e555d3ed53969516cac5ce25531299dda" + integrity sha512-Y67VnGGgVLH5Voostx8JBZgPQTlDQeOVBLOEsjc2cXbCYBKexSKEpOA56x0YZofoDOTszrLnIShyOX1p9uCEHA== + dependencies: + "@vue/component-compiler-utils" "^3.1.0" + hash-sum "^1.0.2" + loader-utils "^1.1.0" + vue-hot-reload-api "^2.3.0" + vue-style-loader "^4.1.0" + +vue-router@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.4.3.tgz#fa93768616ee338aa174f160ac965167fa572ffa" + integrity sha512-BADg1mjGWX18Dpmy6bOGzGNnk7B/ZA0RxuA6qedY/YJwirMfKXIDzcccmHbQI0A6k5PzMdMloc0ElHfyOoX35A== + +vue-style-loader@^4.1.0, vue-style-loader@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/vue-style-loader/-/vue-style-loader-4.1.2.tgz#dedf349806f25ceb4e64f3ad7c0a44fba735fcf8" + integrity sha512-0ip8ge6Gzz/Bk0iHovU9XAUQaFt/G2B61bnWa2tCcqqdgfHs1lF9xXorFbE55Gmy92okFT+8bfmySuUOu13vxQ== + dependencies: + hash-sum "^1.0.2" + loader-utils "^1.0.2" + +vue-template-compiler@^2.6.11: + version "2.6.11" + resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.6.11.tgz#c04704ef8f498b153130018993e56309d4698080" + integrity sha512-KIq15bvQDrcCjpGjrAhx4mUlyyHfdmTaoNfeoATHLAiWB+MU3cx4lOzMwrnUh9cCxy0Lt1T11hAFY6TQgroUAA== + dependencies: + de-indent "^1.0.2" + he "^1.1.0" + +vue-template-es2015-compiler@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825" + integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw== + +vue@^2.6.11: + version "2.6.11" + resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.11.tgz#76594d877d4b12234406e84e35275c6d514125c5" + integrity sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ== + +watchpack-chokidar2@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz#9948a1866cbbd6cb824dea13a7ed691f6c8ddff0" + integrity sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA== + dependencies: + chokidar "^2.1.8" + +watchpack@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.4.tgz#6e9da53b3c80bb2d6508188f5b200410866cd30b" + integrity sha512-aWAgTW4MoSJzZPAicljkO1hsi1oKj/RRq/OJQh2PKI2UKL04c2Bs+MBOB+BBABHTXJpf9mCwHN7ANCvYsvY2sg== + dependencies: + graceful-fs "^4.1.2" + neo-async "^2.5.0" + optionalDependencies: + chokidar "^3.4.1" + watchpack-chokidar2 "^2.0.0" + +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + +wcwidth@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" + integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= + dependencies: + defaults "^1.0.3" + +webpack-bundle-analyzer@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.8.0.tgz#ce6b3f908daf069fd1f7266f692cbb3bded9ba16" + integrity sha512-PODQhAYVEourCcOuU+NiYI7WdR8QyELZGgPvB1y2tjbUpbmcQOt5Q7jEK+ttd5se0KSBKD9SXHCEozS++Wllmw== + dependencies: + acorn "^7.1.1" + acorn-walk "^7.1.1" + bfj "^6.1.1" + chalk "^2.4.1" + commander "^2.18.0" + ejs "^2.6.1" + express "^4.16.3" + filesize "^3.6.1" + gzip-size "^5.0.0" + lodash "^4.17.15" + mkdirp "^0.5.1" + opener "^1.5.1" + ws "^6.0.0" + +webpack-bundle-tracker@0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/webpack-bundle-tracker/-/webpack-bundle-tracker-0.4.3.tgz#48a3e2226ddb9d24d704640ab4168c2d120f4526" + integrity sha512-Sl/+OsNhFAH3/c6XADupRu8jLvGojfXX0pZIIm3O5ZcJqkHHqlY4nLG+NVRcbDgM/jOeWimKDGQMVEa8FBeJ2g== + dependencies: + deep-extend "^0.6.0" + mkdirp "^0.5.1" + strip-ansi "^5.2.0" + +webpack-chain@^6.4.0: + version "6.5.1" + resolved "https://registry.yarnpkg.com/webpack-chain/-/webpack-chain-6.5.1.tgz#4f27284cbbb637e3c8fbdef43eef588d4d861206" + integrity sha512-7doO/SRtLu8q5WM0s7vPKPWX580qhi0/yBHkOxNkv50f6qB76Zy9o2wRTrrPULqYTvQlVHuvbA8v+G5ayuUDsA== + dependencies: + deepmerge "^1.5.2" + javascript-stringify "^2.0.1" + +webpack-dev-middleware@^3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz#0019c3db716e3fa5cecbf64f2ab88a74bab331f3" + integrity sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw== + dependencies: + memory-fs "^0.4.1" + mime "^2.4.4" + mkdirp "^0.5.1" + range-parser "^1.2.1" + webpack-log "^2.0.0" + +webpack-dev-server@^3.11.0: + version "3.11.0" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz#8f154a3bce1bcfd1cc618ef4e703278855e7ff8c" + integrity sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg== + dependencies: + ansi-html "0.0.7" + bonjour "^3.5.0" + chokidar "^2.1.8" + compression "^1.7.4" + connect-history-api-fallback "^1.6.0" + debug "^4.1.1" + del "^4.1.1" + express "^4.17.1" + html-entities "^1.3.1" + http-proxy-middleware "0.19.1" + import-local "^2.0.0" + internal-ip "^4.3.0" + ip "^1.1.5" + is-absolute-url "^3.0.3" + killable "^1.0.1" + loglevel "^1.6.8" + opn "^5.5.0" + p-retry "^3.0.1" + portfinder "^1.0.26" + schema-utils "^1.0.0" + selfsigned "^1.10.7" + semver "^6.3.0" + serve-index "^1.9.1" + sockjs "0.3.20" + sockjs-client "1.4.0" + spdy "^4.0.2" + strip-ansi "^3.0.1" + supports-color "^6.1.0" + url "^0.11.0" + webpack-dev-middleware "^3.7.2" + webpack-log "^2.0.0" + ws "^6.2.1" + yargs "^13.3.2" + +webpack-log@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f" + integrity sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg== + dependencies: + ansi-colors "^3.0.0" + uuid "^3.3.2" + +webpack-merge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d" + integrity sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g== + dependencies: + lodash "^4.17.15" + +webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack@^4.0.0: + version "4.44.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.44.1.tgz#17e69fff9f321b8f117d1fda714edfc0b939cc21" + integrity sha512-4UOGAohv/VGUNQJstzEywwNxqX417FnjZgZJpJQegddzPmTvph37eBIRbRTfdySXzVtJXLJfbMN3mMYhM6GdmQ== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/wasm-edit" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + acorn "^6.4.1" + ajv "^6.10.2" + ajv-keywords "^3.4.1" + chrome-trace-event "^1.0.2" + enhanced-resolve "^4.3.0" + eslint-scope "^4.0.3" + json-parse-better-errors "^1.0.2" + loader-runner "^2.4.0" + loader-utils "^1.2.3" + memory-fs "^0.4.1" + micromatch "^3.1.10" + mkdirp "^0.5.3" + neo-async "^2.6.1" + node-libs-browser "^2.2.1" + schema-utils "^1.0.0" + tapable "^1.1.3" + terser-webpack-plugin "^1.4.3" + watchpack "^1.7.4" + webpack-sources "^1.4.1" + +websocket-driver@0.6.5: + version "0.6.5" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.6.5.tgz#5cb2556ceb85f4373c6d8238aa691c8454e13a36" + integrity sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY= + dependencies: + websocket-extensions ">=0.1.1" + +websocket-driver@>=0.5.1: + version "0.7.4" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" + integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== + dependencies: + http-parser-js ">=0.5.1" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.4" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +worker-farm@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" + integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== + dependencies: + errno "~0.1.7" + +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +write@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== + dependencies: + mkdirp "^0.5.1" + +ws@^6.0.0, ws@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" + integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== + dependencies: + async-limiter "~1.0.0" + +xtend@^4.0.0, xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yargs-parser@^13.1.2: + version "13.1.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" + integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@^18.1.2: + version "18.1.3" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" + integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs@^13.3.2: + version "13.3.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" + integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== + dependencies: + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.2" + +yargs@^15.0.0: + version "15.4.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" + integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== + dependencies: + cliui "^6.0.0" + decamelize "^1.2.0" + find-up "^4.1.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^4.2.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^18.1.2" + +yorkie@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yorkie/-/yorkie-2.0.0.tgz#92411912d435214e12c51c2ae1093e54b6bb83d9" + integrity sha512-jcKpkthap6x63MB4TxwCyuIGkV0oYP/YRyuQU5UO0Yz/E/ZAu+653/uov+phdmO54n6BcvFRyyt0RRrWdN2mpw== + dependencies: + execa "^0.8.0" + is-ci "^1.0.10" + normalize-path "^1.0.0" + strip-indent "^2.0.0"